连接失败,显示SIGN_IN_REQUIRED(4)。

22

我正在开发一个Android应用程序,想要使用Google API。为此,我已经导入了google-play-service-lib项目。

我正在按照此链接初始化GoogleApiClient对象。

我的代码:

1)在onCreate()方法中,我正在构建GoogleApiClient对象:

mGoogleApiClient = new GoogleApiClient.Builder(this)
    .addConnectionCallbacks(this)
    .addOnConnectionFailedListener(this)
    .addApi(Plus.API, null)
    .addScope(Plus.SCOPE_PLUS_LOGIN)
    .build();

2) 在onStart()中,我调用了mGoogleApiClient.connect()

3) 我的活动实现了ConnectionCallbacksOnConnectionFailedListener。

4) 我的onConnectionFailed()方法如下:

public void onConnectionFailed(ConnectionResult result) {
    //in dubug result looks like : ConnectionResult{
    //statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent
                    // {41f8ca70: android.os.BinderProxy@41f8ca10}}
     try {
     if(!mIntentInProgress && result.hasResolution())
     {
         mIntentInProgress=true;
        result.startResolutionForResult(mActivity, RC_SIGN_IN);
          }

    } catch (SendIntentException e) {
        e.printStackTrace();
    }
}

5) 我的onActivityResult()方法包含:

if (requestCode == RC_SIGN_IN) {
   if (!mGoogleApiClient.isConnecting()) {
      mGoogleApiClient.connect();
   }
}

运行我的应用程序时,我收到一个Toast提示,说出现了内部错误。我确实在Google控制台中创建了该项目。

11个回答

23

我遇到了同样的问题。

根据文档: 客户端可以选择继续不使用API,也可以调用startResolutionForResult(Activity,int)来提示用户登录。

因此,您应该尝试使用startResolutionForResult()函数进行登录。

@Override
public void onConnectionFailed(ConnectionResult result) {
   if (result.hasResolution()) {
       try {
           // !!!
           result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
       } catch (SendIntentException e) {
           mPlusClient.connect();
       }
   }

   mConnectionResult = result;
}

3
如果登录意图失败,为什么要在catch块内尝试调用mPlusClient.connect()呢?此时用户尚未登录,因此调用必然会再次失败。 - user2836797
1
对我不起作用。尝试startResolutionForResult()后,我的onConnected()被调用并收到了电子邮件,但在尝试获取此对象后,Person对象为空。 - Rahul Rastogi
1
REQUEST_CODE_RESOLVE_ERR是什么?我在REQUEST_CODE_RESOLVE_ERR上得到了未解决的符号。 - nav_jan
3
@nav_jan 这是一个他们自己定义的请求代码。你可以很容易地设置自己的代码,比如 private static int REQUEST_CODE_RESOLVE_ERR = 1000; 或者任何你想要的正整数。然后使用它来检查是否是正确的调用,在你的 onActivityResult() 中返回。 - Recomer

8

只需按照谷歌的说明进行操作。

然而,请小心

由于您还处于开发模式,请在发布游戏之前检查是否已将测试电子邮件地址添加到游戏详情中。


你必须添加设备中的Google电子邮件才能使它正常工作。它必须添加到游戏服务->测试中。谢谢。 - Silviu St
谢谢!但是没有将该电子邮件添加到测试人员的电子邮件列表中,这是个问题。 - Philipp Cherubim

6

请确保您使用的密钥库已包含在上传到Google Play开发者控制台的apk中进行签名(如果是测试,则可以上传为alpha并在保持私有的同时发布)。

如果不是这个问题,可能是其他原因。请确保您的帐户电子邮件地址在帐户详细信息页面(在设置菜单上具有齿轮图标)的测试人员列表中列出,并且许可证响应设置为LICENSED,而不是RESPOND_NORMALLY。


3

需要从控制台页面启用Drive API。


3

3

不确定这是否是最好的答案,但对我有用。我从BasicSamples TakeANumber MainActivity中复制了onConnectionFailed()。它调用BaseGameUtils进行解决。当然,这意味着您的项目中包含了BaseGameUtils库,这又是另一个问题。但也许你只需要一个方法,所以我在下面把它复制了出来。

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
   logger.info( "onConnectionFailed() *play* : attempting to resolve");
    if (mResolvingConnectionFailure) {
       logger.info( "onConnectionFailed(): already resolving");
        return;
    }

    if (mSignInClicked || mAutoStartSignInFlow) {
        mAutoStartSignInFlow = false;
        mSignInClicked = false;
        mResolvingConnectionFailure = true;
        if (!BaseGameUtils.resolveConnectionFailure(this, mGoogleApiClient, connectionResult,
                RC_SIGN_IN, getString(R.string.signin_other_error))) {
            mResolvingConnectionFailure = false;
        }
    }
}

从谷歌的BasicSamples BaseGameUtils.java文件:

 public static boolean resolveConnectionFailure(Activity activity,
                                               GoogleApiClient client, ConnectionResult result, int requestCode,
                                               String fallbackErrorMessage) {

    if (result.hasResolution()) {
        try {
            result.startResolutionForResult(activity, requestCode);
            return true;
        } catch (IntentSender.SendIntentException e) {
            // The intent was canceled before it was sent.  Return to the default
            // state and attempt to connect to get an updated ConnectionResult.
            client.connect();
            return false;
        }
    } else {
        // not resolvable... so show an error message
        int errorCode = result.getErrorCode();
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(errorCode,
                activity, requestCode);
        if (dialog != null) {
            dialog.show();
        } else {
            // no built-in dialog: show the fallback error message
            showAlert(activity, fallbackErrorMessage);
        }
        return false;
    }
}

2

如果您没有使用调试密钥,请将应用程序推送到Google Play作为alpha版本,将自己添加为测试人员,并最重要的是 - 在Alpha页面上按照“Opt-in”链接并确认您是测试人员。


1
我遇到了相同的问题,并通过以下解决方案解决了它,实际上我使用了非常旧的google play-services库,所以我将其更新为最新的google play-service库,以支持您的android SDK并在gradle:app中保持compileSDKVersion和targetSDKVersion。在清单中添加启用Google Drive的API_KEY,然后再尝试一次。

1

1
我想分享一下我的经验。我的情况是在使用Google Play游戏服务时,遇到了onConnectionFailed出现SIGN_IN_REQUIRED错误的问题。最后我意识到我没有在开发者控制台中“发布”我的游戏设置。这不应该与发布apk的“alpha”或“beta”版本混淆。我指的是实际创建并链接到游戏APK的Google Play游戏“游戏”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接