Android Google+ 集成 - 重复 UserRecoverableAuthException [英] Android Google+ integration - repeated UserRecoverableAuthException

查看:22
本文介绍了Android Google+ 集成 - 重复 UserRecoverableAuthException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已就此与 Google 联系,我们正在聊天

该问题似乎已在三星手机除外设备上得到解决.

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

我正在根据 官方说明.一旦用户选择了他们的帐户,我希望我的服务器检索他们的 Google+ 个人资料信息并更新他们在我们网站上的个人资料以进行匹配.

I'm adding a Google+ sign in option to an app per the official instructions. Once the user has selected their account I would like my server to retrieve their Google+ profile info and update their profile on our site to match.

第一部分 - 让用户在本地选择一个 Google 帐户 - 似乎工作得很好.当我尝试为所选帐户请求令牌时,Google 身份验证对话框会显示适当的参数;但是,当我使用该对话框授权应用程序并重新请求令牌时,GoogleAuthUtil.getToken(...) 再次抛出 UserRecoverableAuthException (NeedPermissioncode>,而不是 GooglePlayServicesAvailabilityException) 并且我收到相同的对话框要求我批准!

The first part - having the user select a Google account locally - seems to work just fine. When I try to request a token for the selected account, the Google auth dialog displays with the appropriate parameters; however, when I authorize the app using that dialog and re-request the token, GoogleAuthUtil.getToken(...) again throws a UserRecoverableAuthException (NeedPermission, not GooglePlayServicesAvailabilityException) and I get the same dialog asking me to approve!

此行为出现在运行 Android 4.1.1(具有 3 个 Google 帐户)的三星 S3 和运行 4.0.3 的 Acer A100 上.它不存在于运行 2.3.4 的 HTC Glacier 上.相反,HTC Glacier 为我提供了一个有效的授权码.所有设备都安装了最新版本的 Google Play 服务并使用不同的 Google+ 帐户.

This behavior is present on a Samsung S3 running Android 4.1.1 (with 3 Google accounts) and an Acer A100 running 4.0.3. It is NOT present on an HTC Glacier running 2.3.4. Instead, the HTC Glacier gives me a valid auth code. All devices have the latest iteration of Google Play Services installed and are using different Google+ accounts.

有人见过这个吗?我可以从哪里开始调试?

Anyone seen this before? Where can I start with debugging?

这是完整的代码 - 有什么明显的错误吗?

Here's the complete code - is anything obviously awry?

public class MyGooglePlusClient {
private static final String LOG_TAG = "GPlus";
private static final String SCOPES_LOGIN = Scopes.PLUS_LOGIN + " " + Scopes.PLUS_PROFILE;
private static final String ACTIVITIES_LOGIN = "http://schemas.google.com/AddActivity";
private static MyGooglePlusClient myGPlus = null;
private BaseActivity mRequestingActivity = null;
private String mSelectedAccount = null;
    
/**
 * Get the GPlus singleton
 * @return GPlus
 */
public synchronized static MyGooglePlusClient getInstance() {
    if (myGPlus == null)
        myGPlus = new MyGooglePlusClient();
    return myGPlus;
}

public boolean login(BaseActivity requester) {
    Log.w(LOG_TAG, "Starting login...");
    if (mRequestingActivity != null) {
        Log.w(LOG_TAG, "Login attempt already in progress.");
        return false; // Cannot launch a new request; already in progress
    }
    
    mRequestingActivity = requester;
    if (mSelectedAccount == null) {
        Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, false,
                null, GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE, null, null);
        mRequestingActivity.startActivityForResult(intent, BaseActivity.REQUEST_GPLUS_SELECT);
    }
    return true;
}

public void loginCallback(String accountName) {
    mSelectedAccount = accountName;
    authorizeCallback();
}
    
public void logout() {
    Log.w(LOG_TAG, "Logging out...");
    mSelectedAccount = null;
}

public void authorizeCallback() {
    Log.w(LOG_TAG, "User authorized");

    AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            String token = null;
            try {
                Bundle b = new Bundle();
                b.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES, ACTIVITIES_LOGIN);
                token = GoogleAuthUtil.getToken(mRequestingActivity,
                        mSelectedAccount,
                        "oauth2:server:client_id:"+Constants.GOOGLE_PLUS_SERVER_OAUTH_CLIENT
                        +":api_scope:" + SCOPES_LOGIN,
                        b);
            } catch (IOException transientEx) {
                // Network or server error, try later
                Log.w(LOG_TAG, transientEx.toString());
                onCompletedLoginAttempt(false);
            } catch (GooglePlayServicesAvailabilityException e) {
                Log.w(LOG_TAG, "Google Play services not available.");
                Intent recover = e.getIntent();
                mRequestingActivity.startActivityForResult(recover, BaseActivity.REQUEST_GPLUS_AUTHORIZE);
            } catch (UserRecoverableAuthException e) {
                // Recover (with e.getIntent())
                Log.w(LOG_TAG, "User must approve "+e.toString());
                Intent recover = e.getIntent();
                mRequestingActivity.startActivityForResult(recover, BaseActivity.REQUEST_GPLUS_AUTHORIZE);
            } catch (GoogleAuthException authEx) {
                // The call is not ever expected to succeed
                Log.w(LOG_TAG, authEx.toString());
                onCompletedLoginAttempt(false);
            }

            Log.w(LOG_TAG, "Finished with task; token is "+token);
            if (token != null) {
                authorizeCallback(token);
            }
            
            return token;
        }

    };
    task.execute();
}

public void authorizeCallback(String token) {
    Log.w(LOG_TAG, "Token obtained: "+token);
    // <snipped - do some more stuff involving connecting to the server and resetting the state locally>
}

public void onCompletedLoginAttempt(boolean success) {
    Log.w(LOG_TAG, "Login attempt "+(success ? "succeeded" : "failed"));
    mRequestingActivity.hideProgressDialog();
    mRequestingActivity = null;
}
}

推荐答案

我遇到这个问题有一段时间了,并想出了一个合适的解决方案.

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

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

这一行要么返回一次性令牌,要么触发 UserRecoverableAuthException.在 Google Plus 登录指南中,它说要打开正确的恢复活动.

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");
    }
}

通过extra提供的新的oneTimeToken,提交到服务器即可正常连接.

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

我希望这会有所帮助!

这篇关于Android Google+ 集成 - 重复 UserRecoverableAuthException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆