3

I've found out a small issue when working with Google+ Sign for Android and after searching the web (and SO obviously) I'm asking my question out loud to see if anyone has noticed the same.

I'm enabling server-side API access for my app as described here. Let me be detailed about what's going on. Take this fragment:

Bundle appActivities = new Bundle();
appActivities.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES,
          "<APP-ACTIVITY1> <APP-ACTIVITY2>");
String scopes = "oauth2:server:client_id:<SERVER-CLIENT-ID>:api_scope:<SCOPE1> <SCOPE2>";
String code = null;
try {
  code = GoogleAuthUtil.getToken(
      this,                                              // Context context
      Plus.AccountApi.getAccountName(mGoogleApiClient),  // String accountName
      scopes,                                            // String scope
      appActivities                                      // Bundle bundle
  );

} catch (IOException transientEx) {
  // network or server error, the call is expected to succeed if you try again later.
  // Don't attempt to call again immediately - the request is likely to
  // fail, you'll hit quotas or back-off.
  ...
  return;
} catch (UserRecoverableAuthException e) {
  // Requesting an authorization code will always throw
  // UserRecoverableAuthException on the first call to GoogleAuthUtil.getToken
  // because the user must consent to offline access to their data.  After
  // consent is granted control is returned to your activity in onActivityResult
  // and the second call to GoogleAuthUtil.getToken will succeed.
  startActivityForResult(e.getIntent(), AUTH_CODE_REQUEST_CODE);
  return;
} catch (GoogleAuthException authEx) {
  // Failure. The call is not expected to ever succeed so it should not be
  // retried.
  ...
  return;
} catch (Exception e) {
  throw new RuntimeException(e);
}

See the UserRecoverableAuthException and it's comment? Well, that is what I want to talk you about. In that case as you can see, another activity is started and it begins a flow where you have to accept the permissions the app is requesting. As you can see the startActivityForResult method is being used. What I observed is that Activity.RESULT_OK is being returned when the users accepts to give the permissions but Activity.RESULT_CANCELED is returned both when an error/crash occurs or when the user simply refuses to give permission and cancels the flow.

So here is (YEAH, FINALLY!) my question... How can I difference one case (error/crash) from the other (possible user flow)?

acrespo
  • 1,134
  • 1
  • 10
  • 33

1 Answers1

1

Well, after fighting a while with this I think I found a solution. I don't know if it's the right way to do it, but I thought I should share it, so here it goes.

we have the onActivityresult method that the activity doing the login/sign in should implement.

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

What I thought (after a thinking a while, and later confirmed) was that the Intent data parameter should have some kind of clue or info about what kind of error or result is being returned. After inspecting it little bit I found that in the case of the user denying the permissions for the app, this intent had an Extra String with key Error and value UserCancel. So that's what I ended up using to distinguish one case from the other. Hope it helps!

   data.getExtraString("Error"); // This should have the value "UserCancel" when the user    
                                 // refused to give the permissions required by the app. 

Please note that the data intent may not always offer this ExtraString, and in fact may be null for some calls of onActityResult, so you should check if (data != null) before using this.

acrespo
  • 1,134
  • 1
  • 10
  • 33