Android Google+ integration - repeated UserRecoverableAuthException

前端 未结 8 1698
独厮守ぢ
独厮守ぢ 2020-11-30 00:55

We have contacted Google about this and we are on chat

The issue seems to be fixed for devices except Samsung phones.

I\'m

相关标签:
8条回答
  • 2020-11-30 01:08

    I have got around this issue by using a web based login. I open a url like this

    String url = "https://accounts.google.com/o/oauth2/auth?scope=" + Scopes.PLUS_LOGIN + "&client_id=" + webLoginClientId + "&response_type=code&access_type=offline&approval_prompt=force&redirect_uri=" + redirect;
    

    The redirect url then handles the response and returns to my app.

    In terms of my findings on using the Google Play Services, I've found:

    HTC One is 3.1.59 (736673-30) - not working Galaxy Note is 3.1.59 (736673-36) - not working Nexus S is 3.1.59 (736673-34) - works

    And I'd like to be involved in the chat that is occurring, however I don't have a high enough reputation to do so.

    0 讨论(0)
  • 2020-11-30 01:14

    Edit (6th Aug 2013): This seems to have been fixed for me without any changes to my code.

    The first potential issue I can see is that you are calling GoogleAuthUtil.getToken() after you get the onConnected() callback. This is a problem because requesting an authorization code for your server using GoogleAuthUtil.getToken() will always show a consent screen to your users. So you should only get an authorization code for new users and, to avoid showing new users two consent screens, you must fetch an authorization code and exchange it on your server before resolving any connection failures from PlusClient.

    Secondly, make sure you actually need both a PlusClient and an authorization code for your servers. You only need to get a PlusClient and an authorization code if you are intending to make calls to the Google APIs from both the Android client and your server. As explained in this answer.

    These issues would only result in two consent dialogs being displayed (which is clearly not an endless loop) - are you seeing more than two consent dialogs?

    0 讨论(0)
  • 2020-11-30 01:24

    I had a similar problem where an apparent auth loop kept creating {read: spamming} these "Signing In..." and Permission request dialogs while also giving out the discussed exception repeatedly.

    The problem appears in some slightly-modified example code that I (and other like me, I suspect) "cargo-culted" from AndroidHive. The solution that worked for me was ensuring that only one background token-retrieval task runs at the background at any given time.

    To make my code easier to follow, here's the auth flow in my app (that is almost identical to the example code on AndoidHive): Activity -> onConnected(...) -> getProfileInformation() -> getOneTimeToken().

    Here's where getOneTimeToken() is called:

    private void getProfileInformation() {
        try {
            if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
                Person currentPerson = Plus.PeopleApi
                        .getCurrentPerson(mGoogleApiClient);
                String personName = currentPerson.getDisplayName();
                String personPhotoUrl = currentPerson.getImage().getUrl();
                String personGooglePlusProfile = currentPerson.getUrl();
                String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
                getOneTimeToken(); // <-------
                ...
    

    Here's my getOneTimeToken():

    private void getOneTimeToken(){
        if (task==null){
        task = new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                LogHelper.log('d',LOGTAG, "Executing background task....");
                Bundle appActivities = new Bundle();
                appActivities.putString(
                             GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES,
                             ACTIVITIES_LOGIN);
                String scopes = "oauth2:server" + 
                                ":client_id:" + SERVER_CLIENT_ID + 
                                ":api_scope:" + SCOPES_LOGIN;
                String token = null;
                try {
                    token = GoogleAuthUtil.getToken(
                            ActivityPlus.this,
                            Plus.AccountApi.getAccountName(mGoogleApiClient),
                            scopes,
                            appActivities
                    );
                } catch (IOException transientEx) {
                    /* Original comment removed*/
                    LogHelper.log('e',LOGTAG, transientEx.toString());
                } catch (UserRecoverableAuthException e) {
                    /* Original comment removed*/
                    LogHelper.log('e',LOGTAG, e.toString());
                    startActivityForResult(e.getIntent(), AUTH_CODE_REQUEST);
                } catch (GoogleAuthException authEx) {
                    /* Original comment removed*/
                    LogHelper.log('e',LOGTAG, authEx.toString());
                } catch (IllegalStateException stateEx){
                    LogHelper.log('e',LOGTAG, stateEx.toString());
                }
                LogHelper.log('d',LOGTAG, "Background task finishing....");
                return token;
            }
    
            @Override
            protected void onPostExecute(String token) {
                LogHelper.log('i',LOGTAG, "Access token retrieved: " + token);
            }
    
        };
        }
        LogHelper.log('d',LOGTAG, "Task setup successful.");
        if(task.getStatus() != AsyncTask.Status.RUNNING){
            task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); //double safety!
        } else
            LogHelper.log('d',LOGTAG, 
                           "Attempted to restart task while it is running!");
    }
    

    Please note that I have a {probably redundant} double-safety against the task executing multiple times:

    1. if(task .getStatus() != AsyncTask.Status.RUNNING){...} - ensures that the task isn't running before attempting to execute it.
    2. task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);- makes sure that copies of this task are "synchronized" (i.e. a queue is in place such that only one task of this type can executed at a given time).

    P.S. Minor clarification: LogHelper.log('e',...) is equivalent to Log.e(...) etc.

    0 讨论(0)
  • 2020-11-30 01:25

    I've had this issue for a while and came up with a proper solution.

    String token = GoogleAuthUtil.getToken(this, accountName, scopeString, appActivities);
    

    This line will either return the one time token or will trigger the UserRecoverableAuthException. On the Google Plus Sign In guide, it says to open the proper recovery activity.

    startActivityForResult(e.getIntent(), RECOVERABLE_REQUEST_CODE);
    

    When the activity returns with the result, it will come back with few extras in the intent and that is where the new token resides :

    @Override
    protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
        if (requestCode == RECOVERABLE_REQUEST_CODE && responseCode == RESULT_OK) {
            Bundle extra = intent.getExtras();
            String oneTimeToken = extra.getString("authtoken");
        }
    }
    

    With the new oneTimeToken given from the extra, you can submit to the server to connect properly.

    I hope this helps!

    0 讨论(0)
  • 2020-11-30 01:25

    Had the same bug with infinite loop of permission request. For me it was because time on my phone was shifted. When I check detect time automatically this bug disappeared. Hope this helps!

    0 讨论(0)
  • 2020-11-30 01:26

    I've experienced the same issue recently - it appears to be device-specific (I had it happen every time on one S3, but on another S3 running the same OS it didn't happen, even with the same account). My hunch is that it's a bug in a client app, either the G+ app or the Google Play Services app. I managed to solve the issue on one of my devices by factory resetting it (a Motorola Defy), then reinstalling the Google Play Services app, but that's a completely useless solution to tell to users.

    0 讨论(0)
提交回复
热议问题