Trouble capturing activity result when firing Inte

2019-09-16 18:44发布

问题:

I am trying to follow Authenticating to OAuth2 Services and implement the part where an Intent is included in the Bundle provided by the AccountManagerFuture#getResult() call.

The issue is, that even though the docs say to use Activity#startActivityForResult(...), the Intent I am told to fire apparently starts in its own task, resulting in onActivityResult being called immediately.

Another part which I am uncertain I am doing correctly is the way I launch this Intent. Because the code that calls AccountManager#getAuthToken(...) is buried inside a worker thread with no access to the current Activity, I am launching a new Activity I call "CredentialsActivity" which then launches the OS-provided Intent using startActivityForResult.

This is how I do that:

      final AccountManagerFuture<Bundle> future = AccountManager.getAuthToken(...);

      // Now that we have the Future, we extract the Bundle
      Bundle bundle = null;
      try {
        bundle = future.getResult();
      } catch (Exception e) {
        log.warn(e, "Got an Exception");
      }

      if (bundle == null) {
        log.info("Unable to get auth token");
        return;
      }

      // Check if the user needs to enter credentials.
      final Intent askForPassword = (Intent) bundle.get(AccountManager.KEY_INTENT);
      if (askForPassword != null) {
        log.dev("Need to prompt for credentials, firing Intent...");
        CredentialsActivity.promptForCredentials(context, askForPassword);
      }

These are the relevant parts of CredentialsActivity:

      private static final int REQUEST_CODE_LAUNCH_CREDENTIALS_INTENT = 0;

      private static Intent newCredentialsActivityIntent(Context context) {
        final Intent intent = new Intent(context, CredentialsActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return intent;
      }

      public static void promptForCredentials(Context context, Intent credentialsIntent) {
        final Intent intent = newCredentialsActivityIntent(context);
        intent.putExtra(Intent.EXTRA_INTENT, credentialsIntent);

        context.startActivity(intent);
      }

I fire the Intent in onResume:

  @Override
  protected void onResume() {
    super.onResume();
    final Intent intent = getIntent();
    final Intent credentialsIntent = (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
    if (credentialsIntent != null) {
      startActivityForResult(credentialsIntent, REQUEST_CODE_LAUNCH_CREDENTIALS_INTENT);
    }
  }

回答1:

OK, so I think I figured this one out - I'll post the answer, just in case:

The issue is that the system provides the Intent with the NEW_TASK flag set. I needed to clear it to make this work for me:

final Intent credentialsIntent = (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
if (credentialsIntent != null) {
  credentialsIntent.setFlags(0);
  startActivityForResult(credentialsIntent, REQUEST_CODE_LAUNCH_CREDENTIALS_INTENT);
}