mori mori - 25 days ago 11
Android Question

How to handle an activity that calls AsyncTask after going back from other app in Android

My Scenario is like this

Activity -> clicked a button that will open other app (for example Facebook app-> loading -> gets data -> passing back to activity -> go back to the activity and call AsyncTask.

In my

AsyncTask
, I call
onPreExecute
to show a dialog, but after going back from other apps it doesn't proceed to show
dialog
and instead of finishing the
AsyncTask
it goes to 'onDetachedFromWindow' and crashes. I'm wondering why and how can I solve this?

I'm having an error like this when it crashes
FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@41fb6a60 is not valid; is your activity running?


Here is my
onActivityResult()
in my
Activity


public class LoginActivity extends Activity {

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

Log.e(TAG, "I'm in onActivity " + resultCode);
if (requestCode == Constants.FACEBOOK_AUTH_RESULT_CODE) {
facebook.authorizeCallback(requestCode, resultCode, data);
}
}

private class LoginDialogListener implements Facebook.DialogListener {
public void onComplete(Bundle values) {
Log.d(TAG, "LoginONComplete");
String token = facebook.getAccessToken();
long token_expires = facebook.getAccessExpires();
Log.d(TAG, "AccessToken: " + token);
Log.d(TAG, "AccessExpires: " + token_expires);

if (isPublishStreamAuthorized()) {
facebookSharedPreferences = PreferenceManager
.getDefaultSharedPreferences(context);
facebookSharedPreferences
.edit()
.putLong(Constants.FACEBOOK_ACCESS_EXPIRES,
token_expires).commit();
facebookSharedPreferences.edit()
.putString(Constants.FACEBOOK_ACCESS_TOKEN, token)
.commit();
facebookAsyncRunner.request("me", new IDRequestListener());
} else {
logoutFacebook();
}

}

public void onFacebookError(FacebookError e) {
Log.d(TAG, "FacebookError: " + e.getMessage());
}

public void onError(DialogError e) {
Log.d(TAG, "Error: " + e.getMessage());
Toast.makeText(getApplicationContext(), Constants.NO_INTERNET_CONNECTION,
Toast.LENGTH_LONG).show();
}

public void onCancel() {
Log.d(TAG, "OnCancel");
logoutFacebook();
}
}

private class IDRequestListener implements AsyncFacebookRunner.RequestListener {
public void onComplete(String response, Object state) {
try {
Log.d(TAG, "IDRequestONComplete");
Log.d(TAG, "Response: " + response.toString());
JSONObject json = Util.parseJson(response);

id = json.getString("id");
fname = json.getString("first_name");
lname = json.getString("last_name");
email = json.getString("email");
name = json.getString("name");
gender = json.getString("gender");
locale = json.getString("locale");
verified = json.getString("verified");

// check if email is null
if(email == null) {
email = "";
}

LoginActivity.this.runOnUiThread(new Runnable() {
public void run() {
Utils.setFacebookUser(context, name, id);
saveUserFBDetailsTask
= new SaveUserFBDetailsAsyncTask(id, fname, lname, email, name,
gender, locale, verified);
saveUserFBDetailsTask.execute();
/*
* String fbId, String fbFName, String fbLName, String email,
String fbName, String gender, String locale, String verified
* */
}
});
}

catch (JSONException e) {
Log.d(TAG, "JSONException: " + e.getMessage());
}

catch (FacebookError e) {
Log.d(TAG, "FacebookError: " + e.getMessage());
}
}

public void onIOException(IOException e, Object state) {
Log.d(TAG, "IOException: " + e.getMessage());
}

public void onFileNotFoundException(FileNotFoundException e,
Object state) {
Log.d(TAG, "FileNotFoundException: " + e.getMessage());
}

public void onMalformedURLException(MalformedURLException e,
Object state) {
Log.d(TAG, "MalformedURLException: " + e.getMessage());
}

public void onFacebookError(FacebookError e, Object state) {
Log.d(TAG, "FacebookError: " + e.getMessage());
}
}


Here is my AsyncTask inside my activity

class SaveUserFBDetailsAsyncTask extends AsyncTask<String, String, String> {

private String fbId, fbFName, fbLName, email, fbName, gender,
locale, verified,
result, errorCode, message, userId, cards, response;
private JSONObject returnData;

public SaveUserFBDetailsAsyncTask(String fbId, String fbFName, String fbLName, String email,
String fbName, String gender, String locale, String verified) {
this.fbId = fbId;
this.fbFName = fbFName;
this.fbLName = fbLName;
this.email = email;
this.fbName = fbName;
this.gender = gender;
this.locale = locale;
this.verified = verified;
}

protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(LoginActivity.this);
progressDialog.setMessage("Please wait...");
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.show();
}


Here is my
Facebook.java


public void authorize(Activity activity, String[] permissions,
int activityCode, final DialogListener listener) {

boolean singleSignOnStarted = false;

mAuthDialogListener = listener;

// Prefer single sign-on, where available.
if (activityCode >= 0) {
singleSignOnStarted = startSingleSignOn(activity, mAppId,
permissions, activityCode);
}
// Otherwise fall back to traditional dialog.
if (!singleSignOnStarted) {
startDialogAuth(activity, permissions);
}
}

public void authorizeCallback(int requestCode, int resultCode, Intent data) {
if (requestCode == mAuthActivityCode) {

// Successfully redirected.
if (resultCode == Activity.RESULT_OK) {

// Check OAuth 2.0/2.10 error code.
String error = data.getStringExtra("error");
if (error == null) {
error = data.getStringExtra("error_type");
}

// A Facebook error occurred.
if (error != null) {
if (error.equals(SINGLE_SIGN_ON_DISABLED)
|| error.equals("AndroidAuthKillSwitchException")) {
Util.logd("Facebook-authorize", "Hosted auth currently "
+ "disabled. Retrying dialog auth...");
startDialogAuth(mAuthActivity, mAuthPermissions);
} else if (error.equals("access_denied")
|| error.equals("OAuthAccessDeniedException")) {
Util.logd("Facebook-authorize", "Login canceled by user.");
mAuthDialogListener.onCancel();
} else {
String description = data.getStringExtra("error_description");
if (description != null) {
error = error + ":" + description;
}
Util.logd("Facebook-authorize", "Login failed: " + error);
mAuthDialogListener.onFacebookError(
new FacebookError(error));
}

// No errors.
} else {
setAccessToken(data.getStringExtra(TOKEN));
setAccessExpiresIn(data.getStringExtra(EXPIRES));
if (isSessionValid()) {
Util.logd("Facebook-authorize",
"Login Success! access_token="
+ getAccessToken() + " expires="
+ getAccessExpires());
mAuthDialogListener.onComplete(data.getExtras());
} else {
mAuthDialogListener.onFacebookError(new FacebookError(
"Failed to receive access token."));
}
}

// An error occurred before we could be redirected.
} else if (resultCode == Activity.RESULT_CANCELED) {

// An Android error occurred.
if (data != null) {
Util.logd("Facebook-authorize",
"Login failed: " + data.getStringExtra("error"));
mAuthDialogListener.onError(
new DialogError(
data.getStringExtra("error"),
data.getIntExtra("error_code", -1),
data.getStringExtra("failing_url")));

// User pressed the 'back' button.
} else {
Util.logd("Facebook-authorize", "Login canceled by user.");
mAuthDialogListener.onCancel();
}
}
}
}

Answer

I just used the latest Facebook SDK to solve it.

Comments