gpt4 book ai didi

java - 无法正确退出或完成我的应用程序 android( Activity )

转载 作者:行者123 更新时间:2023-11-30 02:39:01 25 4
gpt4 key购买 nike

以下应用程序在启动时将视频上传到 Dropbox,我在 onCreate 的末尾添加了 finish() 以在完成上传时退出应用程序,但我得到“不幸的是,DBRoulette 已停止。”。

在 Eclipse LogCat 中:

Activity com.dropbox.android.sample.DBRoulette has leaked window  com.android.internal.policy.impl.PhoneWindow$DecorView@42a7ee38 that was originally added here
android.view.WindowLeaked: Activity com.dropbox.android.sample.DBRoulette has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@42a7ee38 that was originally added here

我有 Progress viewer 这可能会导致问题,但我不知道如何解决它!我想要做的是在上传完成后自动关闭应用程序。

DBRoulette.java

@SuppressLint("SimpleDateFormat")
public class DBRoulette extends Activity {
private static final String TAG = "DBRoulette";

final static private String APP_KEY = "<My APP_KEY>";
final static private String APP_SECRET = "<My APP_SECRET>";

// You don't need to change these, leave them alone.
final static private String ACCOUNT_PREFS_NAME = "prefs";
final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";

private static final boolean USE_OAUTH1 = false;

DropboxAPI<AndroidAuthSession> mApi;

private boolean mLoggedIn;

// Android widgets
private Button mSubmit;
private RelativeLayout mDisplay;
private Button mGallery;

private ImageView mImage;

private final String PHOTO_DIR = "/Motion/";

@SuppressWarnings("unused")
final static private int NEW_PICTURE = 50;
private String mCameraFileName;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (savedInstanceState != null) {
mCameraFileName = savedInstanceState.getString("mCameraFileName");
}

// We create a new AuthSession so that we can use the Dropbox API.
AndroidAuthSession session = buildSession();
mApi = new DropboxAPI<AndroidAuthSession>(session);

// Basic Android widgets
setContentView(R.layout.main);

checkAppKeySetup();

mSubmit = (Button) findViewById(R.id.auth_button);

mSubmit.setOnClickListener(new OnClickListener() {
@SuppressWarnings("deprecation")
public void onClick(View v) {
// This logs you out if you're logged in, or vice versa
if (mLoggedIn) {
logOut();
} else {
// Start the remote authentication
if (USE_OAUTH1) {
mApi.getSession().startAuthentication(DBRoulette.this);
} else {
mApi.getSession().startOAuth2Authentication(
DBRoulette.this);


}
}
}
});

mDisplay = (RelativeLayout) findViewById(R.id.logged_in_display);

// This is where a photo is displayed
mImage = (ImageView) findViewById(R.id.image_view);


File outFile = new File("/mnt/sdcard/ipwebcam_videos/video.mov");

mCameraFileName = outFile.toString();
UploadPicture upload = new UploadPicture(DBRoulette.this, mApi, PHOTO_DIR,outFile);
upload.execute();



// Display the proper UI state if logged in or not
setLoggedIn(mApi.getSession().isLinked());
finish();

}

@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("mCameraFileName", mCameraFileName);
super.onSaveInstanceState(outState);
}

@Override
protected void onResume() {
super.onResume();
AndroidAuthSession session = mApi.getSession();
if (session.authenticationSuccessful()) {
try {
session.finishAuthentication();
storeAuth(session);
setLoggedIn(true);
} catch (IllegalStateException e) {
showToast("Couldn't authenticate with Dropbox:"
+ e.getLocalizedMessage());
Log.i(TAG, "Error authenticating", e);
}
}
}


private void logOut() {
// Remove credentials from the session
mApi.getSession().unlink();
clearKeys();
// Change UI state to display logged out version
setLoggedIn(false);
}
@SuppressWarnings("deprecation")
public String getRealPathFromURI(Uri contentUri)
{
String[] proj = { MediaStore.Audio.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}

private void setLoggedIn(boolean loggedIn) {
mLoggedIn = loggedIn;
if (loggedIn) {
mSubmit.setText("Logout from Dropbox");
mDisplay.setVisibility(View.VISIBLE);
} else {
mSubmit.setText("Login with Dropbox");
mDisplay.setVisibility(View.GONE);
mImage.setImageDrawable(null);
}
}

private void checkAppKeySetup() {
// Check to make sure that we have a valid app key
if (APP_KEY.startsWith("CHANGE") || APP_SECRET.startsWith("CHANGE")) {
showToast("You must apply for an app key and secret from developers.dropbox.com, and add them to the DBRoulette ap before trying it.");
finish();
return;
}

// Check if the app has set up its manifest properly.
Intent testIntent = new Intent(Intent.ACTION_VIEW);
String scheme = "db-" + APP_KEY;
String uri = scheme + "://" + AuthActivity.AUTH_VERSION + "/test";
testIntent.setData(Uri.parse(uri));
PackageManager pm = getPackageManager();
if (0 == pm.queryIntentActivities(testIntent, 0).size()) {
showToast("URL scheme in your app's "
+ "manifest is not set up correctly. You should have a "
+ "com.dropbox.client2.android.AuthActivity with the "
+ "scheme: " + scheme);
finish();
}
}

private void showToast(String msg) {
Toast error = Toast.makeText(this, msg, Toast.LENGTH_LONG);
error.show();
}

/**
* Shows keeping the access keys returned from Trusted Authenticator in a
* local store, rather than storing user name & password, and
* re-authenticating each time (which is not to be done, ever).
*/
private void loadAuth(AndroidAuthSession session) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(ACCESS_KEY_NAME, null);
String secret = prefs.getString(ACCESS_SECRET_NAME, null);
if (key == null || secret == null || key.length() == 0
|| secret.length() == 0)
return;

if (key.equals("oauth2:")) {
// If the key is set to "oauth2:", then we can assume the token is
// for OAuth 2.
session.setOAuth2AccessToken(secret);
} else {
// Still support using old OAuth 1 tokens.
session.setAccessTokenPair(new AccessTokenPair(key, secret));
}
}

/**
* Shows keeping the access keys returned from Trusted Authenticator in a
* local store, rather than storing user name & password, and
* re-authenticating each time (which is not to be done, ever).
*/
private void storeAuth(AndroidAuthSession session) {
// Store the OAuth 2 access token, if there is one.
String oauth2AccessToken = session.getOAuth2AccessToken();
if (oauth2AccessToken != null) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME,
0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, "oauth2:");
edit.putString(ACCESS_SECRET_NAME, oauth2AccessToken);
edit.commit();
return;
}
// Store the OAuth 1 access token, if there is one. This is only
// necessary if
// you're still using OAuth 1.
AccessTokenPair oauth1AccessToken = session.getAccessTokenPair();
if (oauth1AccessToken != null) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME,
0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, oauth1AccessToken.key);
edit.putString(ACCESS_SECRET_NAME, oauth1AccessToken.secret);
edit.commit();
return;
}
}

private void clearKeys() {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.clear();
edit.commit();
}

private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);

AndroidAuthSession session = new AndroidAuthSession(appKeyPair);
loadAuth(session);
return session;
}
}

上传图片.java

public class UploadPicture extends AsyncTask<Void, Long, Boolean> {

private DropboxAPI<?> mApi;
private String mPath;
private File mFile;

private long mFileLen;
private UploadRequest mRequest;
private Context mContext;
private final ProgressDialog mDialog;

private String mErrorMsg;
private File outFiles;


public UploadPicture(Context context, DropboxAPI<?> api, String dropboxPath,
File file) {
// We set the context this way so we don't accidentally leak activities
mContext = context.getApplicationContext();

mFileLen = file.length();
mApi = api;
mPath = dropboxPath;
mFile = file;
Date dates = new Date();
DateFormat dfs = new SimpleDateFormat("yyyyMMdd-kkmmss");

String newPicFiles = dfs.format(dates) + ".mov";
String outPaths = new File(Environment
.getExternalStorageDirectory(), newPicFiles).getPath();
outFiles = new File(outPaths);
mDialog = new ProgressDialog(context);
mDialog.setMax(100);
mDialog.setMessage("Uploading " + outFiles.getName());
mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mDialog.setProgress(0);
mDialog.setButton(ProgressDialog.BUTTON_POSITIVE, "Cancel", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// This will cancel the putFile operation
mRequest.abort();
}
});
mDialog.show();
}

@Override
protected Boolean doInBackground(Void... params) {
try {
// By creating a request, we get a handle to the putFile operation,
// so we can cancel it later if we want to
FileInputStream fis = new FileInputStream(mFile);
String path = mPath + outFiles.getName();
mRequest = mApi.putFileOverwriteRequest(path, fis, mFile.length(),
new ProgressListener() {
@Override
public long progressInterval() {
// Update the progress bar every half-second or so
return 500;
}

@Override
public void onProgress(long bytes, long total) {
publishProgress(bytes);
}
});

if (mRequest != null) {
mRequest.upload();
return true;
}

} catch (DropboxUnlinkedException e) {
// This session wasn't authenticated properly or user unlinked
mErrorMsg = "This app wasn't authenticated properly.";
} catch (DropboxFileSizeException e) {
// File size too big to upload via the API
mErrorMsg = "This file is too big to upload";
} catch (DropboxPartialFileException e) {
// We canceled the operation
mErrorMsg = "Upload canceled";
} catch (DropboxServerException e) {
// Server-side exception. These are examples of what could happen,
// but we don't do anything special with them here.
if (e.error == DropboxServerException._401_UNAUTHORIZED) {
// Unauthorized, so we should unlink them. You may want to
// automatically log the user out in this case.
} else if (e.error == DropboxServerException._403_FORBIDDEN) {
// Not allowed to access this
} else if (e.error == DropboxServerException._404_NOT_FOUND) {
// path not found (or if it was the thumbnail, can't be
// thumbnailed)
} else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
// user is over quota
} else {
// Something else
}
// This gets the Dropbox error, translated into the user's language
mErrorMsg = e.body.userError;
if (mErrorMsg == null) {
mErrorMsg = e.body.error;
}
} catch (DropboxIOException e) {
// Happens all the time, probably want to retry automatically.
mErrorMsg = "Network error. Try again.";
} catch (DropboxParseException e) {
// Probably due to Dropbox server restarting, should retry
mErrorMsg = "Dropbox error. Try again.";
} catch (DropboxException e) {
// Unknown error
mErrorMsg = "Unknown error. Try again.";
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}

@Override
protected void onProgressUpdate(Long... progress) {
int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5);
mDialog.setProgress(percent);
}

@Override
protected void onPostExecute(Boolean result) {
mDialog.dismiss();
if (result) {
showToast("Image successfully uploaded");
} else {
showToast(mErrorMsg);
}
}

private void showToast(String msg) {
Toast error = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
error.show();
}
}

最佳答案

您的问题是您试图在 Activity 结束后更新 Activity 的 UI。

首先,您启动一​​个 AsyncTask,它将进度更新发布到 UI 线程。然后,在任务完成之前,调用 finish()。调用 finish() 后对 Activity 的 UI 的任何更新都可能引发异常、导致窗口泄漏问题等。

如果您希望在执行 AsyncTask 时有任何 UI 行为,则在任务完成之前不希望 finish() Activity。

要实现这一点,您可以在 onPostExecute 中包含一个回调,它会告诉 Activity 一旦 AsyncTask 完成就可以完成。

我会这样做:

  1. 更改UploadPicture的签名:

    final Activity callingActivity;
    public UploadPicture(final Activity callingActivity, DropboxAPI api, String dropboxPath, File file) {
    Context mContext = callingActivity.getApplicationContext();
    this.callingActivity = callingActivity;

  2. 将结束调用添加到 onPostExecute:

    @Override
    protected void onPostExecute(Boolean result) {
    mDialog.dismiss();
    if (result) {
    showToast("Image successfully uploaded");
    } else {
    showToast(mErrorMsg);
    }
    callingActivity.finish(); //Finish activity only once you are done
    }

关于java - 无法正确退出或完成我的应用程序 android( Activity ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26047079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com