谷歌API客户端(GoogleApiClient)在调用onConnected函数后抛出“GoogleApiClient尚未连接”异常

75

我在使用GoogleApiClient时发现了一些不太清楚的问题。

GoogleApiClient有一个名为onConnected的函数,当客户端连接成功后会运行该函数。

我自己编写了一个名为startLocationListening的函数,最终在GoogleApiClient的onConnected函数中被调用

因此,我的startLocationListening函数无法在没有GoogleApiClient连接的情况下运行

代码和日志:

@Override
public void onConnected(Bundle bundle) {
    log("Google_Api_Client:connected.");
    initLocationRequest();
    startLocationListening(); //Exception caught inside this function
}

...

private void startLocationListening() {
    log("Starting_location_listening:now");

    //Exception caught here below:
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
   }

例外情况是:

03-30 12:23:28.947: E/AndroidRuntime(4936):     java.lang.IllegalStateException: GoogleApiClient is not connected yet.
03-30 12:23:28.947: E/AndroidRuntime(4936):     at com.google.android.gms.internal.jx.a(Unknown Source)
03-30 12:23:28.947: E/AndroidRuntime(4936):     at com.google.android.gms.common.api.c.b(Unknown Source)
03-30 12:23:28.947: E/AndroidRuntime(4936):     at com.google.android.gms.internal.nf.requestLocationUpdates(Unknown Source)
03-30 12:23:28.947: E/AndroidRuntime(4936):     at hu.company.testproject.service.GpsService.startLocationListening(GpsService.java:169)
03-30 12:23:28.947: E/AndroidRuntime(4936):     at hu.company.testproject.service.GpsService.onConnected(GpsService.java:259)

我的调试日志还显示onConnected函数被调用了

03-30 12:23:28.847: I/Locationing_GpsService(4936): Google_Api_Client:connected.
03-30 12:23:28.857: I/Locationing_GpsService(4936): initLocationRequest:initing_now
03-30 12:23:28.877: I/Locationing_GpsService(4936): initLocationRequest:interval_5000
03-30 12:23:28.897: I/Locationing_GpsService(4936): initLocationRequest:priority_100
03-30 12:23:28.917: I/Locationing_GpsService(4936): Starting_location_listening:now

在此之后,我遇到了异常。

我错过了什么吗?我收到了“已连接”的响应,运行了我的函数,然后出现了“未连接”的错误。这是怎么回事?还有一件很烦人的事情是:我现在已经使用这个位置服务几周了,从来没有遇到过这个错误。

编辑:

我添加了更具体的日志输出,真是让我大吃一惊,看看这个:

@Override
    public void onConnected(Bundle bundle) {

        if(mGoogleApiClient.isConnected()){
            log("Google_Api_Client: It was connected on (onConnected) function, working as it should.");
        }
        else{
            log("Google_Api_Client: It was NOT connected on (onConnected) function, It is definetly bugged.");
        }

        initLocationRequest();
        startLocationListening();
    }

在这种情况下的日志输出:

03-30 16:20:00.950: I/Locationing_GpsService(16608): Google_Api_Client:connected.
03-30 16:20:00.960: I/Locationing_GpsService(16608): Google_Api_Client: It was NOT connected on (onConnected) function, It is definetly bugged.

我在onConnected()方法中得到了mGoogleApiClient.isConnected() == false,这怎么可能?

编辑:

由于即使通过声望奖励也没有人能够回答这个问题,我决定向谷歌报告此问题。 谷歌官方对我的报告的回答真的让我感到惊讶。

  

“此网站是用于开发人员使用AOSP Android源代码和开发工具集的开发人员问题,并且不适用于Play服务、GMS或Google API等Google应用程序或服务。很遗憾,似乎没有合适的地方可以报告Play服务的错误。我只能说,这个网站不是,抱歉。请尝试在Google产品论坛上发布。”

完整问题报告在此。(希望他们不会因为这件事而将其删除)

所以,我在谷歌产品论坛上看了一下,但无法找到任何主题来发布此事,所以目前我感到困惑和受阻。

有地球上的任何人能帮助我吗?

编辑:

完整代码在pastebin中。


你能否在onConnectionSuspended()中添加一些日志记录,以查看它是否被调用了吗? - Anti Veeranna
@AntiVeeranna 我也在onConnectionSuspended()时得到了日志,但该函数从未被调用过。 - Adam Varhegyi
你能否也发布一下创建mGoogleApiClient的代码? - Anti Veeranna
@AntiVeeranna 在 pastebin 中添加了代码。 - Adam Varhegyi
1
@Dima,正如iheanyi所说:“尝试将您的googleApiClient创建移动到onCreate中,看看是否会出现相同的行为。” 这可以确保只有一个实例从googleApiClient中产生,并且您的服务将不再持有错误引用。 - Adam Varhegyi
显示剩余6条评论
9个回答

86
我注意到你在 onStartCommand() 中创建了 googleApiClient,这似乎不是一个好主意。
假设您的服务被触发两次,将会创建两个 googleApiClient 对象,但您只会引用其中一个。如果那个您没有引用的执行其 onConnected() 回调函数,那么该客户端会连接,但实际上您有引用的客户端可能仍未连接。
我怀疑这就是问题所在。请尝试将 googleApiClient 的创建移至 onCreate,并查看是否出现相同的行为。

是的,我认为你说得对!http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle - EyesClear
嗨@iheanyi。我正在我的MainActivity的onCreate()方法中创建我的“googleApiClient”对象。但是在某些设备上,我会遇到这个错误。你对此有什么看法? - Sattar Hummatli
@SattarHummatli 很难说。这个问题的情况可能不是某个人遇到这个错误的唯一方式。我首先会检查您是否有类似的竞态条件 - 例如,请确保您只在一个地方创建googleApiClient。如果您仍然有问题,请尝试组合最小完整可验证代码示例并发布一个问题。然后用评论回复我一个链接,我会去看一下。 - iheanyi

3

我遇到了同样的错误,但是我的问题与iheanyl的答案不同:

我声明了googleApiClient为静态变量。这导致Android无法关闭该服务。


2

我也遇到过这个问题,我通过将googleApiClient声明为静态对象来解决它。


0

在onStart()方法中调用connect()方法

 @Override
       protected void onStart() {
           super.onStart();

           // Call GoogleApiClient connection when starting the Activity
           googleApiClient.connect();
       }

       @Override
       protected void onStop() {
           super.onStop();

           // Disconnect GoogleApiClient when stopping Activity
           googleApiClient.disconnect();
       }

0

我认为我找到了问题的根源,它与 API 没有任何关系。每次我安装应用程序时都会遇到此问题。顺便说一下,就像最流行的评论一样,我在暂停和恢复时只有一个 googleApiClient。我注意到的是,获取地理位置访问权限的请求弹出。就像你在活动中所知道的那样,这将转化为暂停,并且一旦弹出窗口消失,它将恢复您的活动。很可能您的 googleClient 也被链接到这些事件以进行断开和连接。一旦权限被接受并且您即将执行 googleApiClient 任务,您就可以告诉它没有连接。

 if(googleApiClient.isConnected()){

        rxPermissions
                .request(Manifest.permission.ACCESS_FINE_LOCATION)
                .subscribe(granted -> {

                 if (granted) {
                        //here it could be client is already disconnected!!     
                        _geolocateAddress(response);
                    } else {
                        // Oups permission denied
                    }
                });
    }

您可以跳过断开和连接,因为在授权之前设置了一个标志,一旦googleApiClient任务完成或granted为false,则该标志为真。

if(googleApiClient.isConnected()){
        isRequestingPermission = true;
        rxPermissions
                .request(Manifest.permission.ACCESS_FINE_LOCATION)
                .subscribe(granted -> {
                    if (granted && googleApiClient.isConnected()) {
                        //Once the task succeeds or fails set flag to false
                        //at _geolocateAddress
                        _geolocateAddress(response);
                    } else {
                        // Oups permission denied
                        isRequestingPermission = false;
                    }
                });
    }

我们也可以单独划分出权限并在授权后调用任务。好吧,我要承认我正在使用一个片段,并重新安装了应用程序,甚至在权限方面旋转了屏幕,一旦获得授权,结果就出现了。我希望这能帮助其他人。

  • 您不必卸载应用程序。只需转到设置/应用程序管理/您的应用程序/权限并关闭任何权限,然后再次测试该应用程序即可。

0

0
将 GoogleApiClient 从 onStartCommand 移动到 onCreate 解决了我的问题。

-1

我在编写代码时遇到了这个问题,当时我不小心把googleApiClient.connect()放在了oncreate和onresume中。后来我从oncreate中将它移除了。


-4
将创建 Google API 的代码移动到 onCreate 中解决了我的问题。

9
重复已接受的答案对任何人都没有帮助,只会产生噪音。 - Tim

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