G+ 登录 Ian Barber 实施:断开连接重建 GoogleApiClient 时未调用 onConnectionFailed

G+ Sign-In Ian Barber Implementation : onConnectionFailed not getting called when disconnecting rebuilding GoogleApiClient

我已经集成 google+ 使用开发者网站登录,对于服务器端,我在 riskcompletefailure 博客上遵循了@ianbarber 的解决方案

这是我构建 GoogleApiClient 的方式:

return new GoogleApiClient.Builder(getActivity())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API, Plus.PlusOptions.builder().build())
            .addScope(new Scope("email")).addScope(Plus.SCOPE_PLUS_LOGIN)
            .build();

这是在异步任务中获取 id 令牌的方法

scopes = "audience:server:client_id:" + Util.CLIENT_ID_SERVER;
            id = GoogleAuthUtil.getToken(getActivity(),
                    Plus.AccountApi.getAccountName(mGoogleApiClient),
                    scopes);

之后调用 createSession 并根据服务器的响应更新 hashMap 并重建 GoogleApiClient 并再次重试连接,但它将转到 onConnceted() 而不是 onConnectionFailed() 因为服务器返回 401(无刷新)令牌可用)

if (cookie.equals("NO_REFRESH")) {
        Log.v(TAG, "create session for " + mAccountName);
        mSessionCookie = null;
        mUserHasRefreshOnServer.put(mAccountName, false);
    } else {
        Log.v(TAG, "refresh available on server");
        mSessionCookie = cookie;
        mUserHasRefreshOnServer.put(mAccountName, true);
    }
    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
        Log.v(TAG, "disconnect googleclient ");
    }
    Log.v(TAG, "try connect googleclient ");

    mGoogleApiClient = buildGoogleApiClient();
    mGoogleApiClient.connect();
}

这是我需要在 onConnectionFailed() 中执行的操作

public void onConnectionFailed(ConnectionResult result) {

    if ((mAccountName != null)
            && mUserHasRefreshOnServer.containsKey(mAccountName)
            && mUserHasRefreshOnServer.get(mAccountName) == Boolean.FALSE) {
            getCode(); //code for getting onetime authorization code
    }

请指出我做错了什么,详情请看这个document我完全按照

编辑:

我改变了流程.. 完全复制这个 gist 但是现在在发送 id 令牌后(假设服务器没有刷新并且没有征得同意)当我去获取代码时 我只获得 Plus.SCOPE_PLUS_LOGIN 的许可,而不是离线访问的许可,因此当我重新连接时,我仍然以错误代码 =4(需要登录)

的 onConnectionFailed 告终

但是, 备用流程,其中如果我事先解决错误(同意 Plus.SCOPE_PLUS_LOGIN),然后这次去获取 getCode,我也获得了此离线访问同意,因此需要一个 onConnected。

这是一个可以进入的有效状态!如果用户之前已登录,您可以到达那里,但您丢失了服务器上的刷新令牌。

如果你看一下要点(当然,自从迁移到 GoogleApiClient 之后它已经过时了),你可以看到我们在 onConnected 中也有一个 getCode 调用:https://gist.github.com/ianbarber/7105273#file-codeactivity-java-L97

if (mSessionCookie == null) {
  // If the server hasn't got a refresh token, grab it.
  if(mUserHasRefreshOnServer.containsKey(mAccountName)) {
    getCode();
  } else {
    // Otherwise, just get the session.
    getSession();
  }
}

这正是为了处理这种情况 - 我们知道用户已经签名,但是我们仍然需要在服务器上获取刷新令牌,因此我们必须将它们发送到 getCode 路由并弹出通过 UserRecoverableAuthException 的同意对话框。