75

So I found something that is not very clear for me about GoogleApiClient. GoogleApiClient has a function called onConnected which is run when the client is connected (for sure).

I got my own function called: startLocationListening which is eventually getting called on GoogleApiClient's onConnected function.

So my startLocationListening function couldn't run without a GoogleApiClient connection.

Code and log:

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

The exception is:

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)

...

My debug log also says the onConnected function got called:

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

After this I got the exception.

Am I missing something here? I got a response for "connected" I ran my func, and I got the error "not connected" what's this? Plus one annoying thing is: I used this location service for weeks now and never got this error.

E D I T :

I added a more specific log output, just blown my mind, check this out:

@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();
    }

log output in this case:

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.

Yes, I just got mGoogleApiClient.isConnected() == false inside onConnected() how is it possible?

E D I T:

Since nobody could answer this even with reputation bounty, I decided to report this as a bug to Google. What came next was really surprising to me. Google's official answer for my report:

"This website is for developer issues with the AOSP Android source code and the developer toolset, not Google apps or services such as Play services, GMS or Google APIs. Unfortunately there doesn't seem to be an appropriate place to report bugs with Play Services. All I can say is that this website isn't it, sorry. Try posting on the Google Product Forums instead. "

Full issue report here. (I hope they won't remove it just because it's silly)

So yeah I took a look at Google Product Forums and just couldn't find any topic to post this thing, so at the moment I am puzzled and stuck.

Does anybody in planet earth could help me with this?

E D I T:

Full code in pastebin

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Adam Varhegyi
  • 11,307
  • 33
  • 124
  • 222
  • Could you add some logging to onConnectionSuspended() as well to see whether that is called at any time? – Anti Veeranna Apr 03 '15 at 09:05
  • @AntiVeeranna I got logging too at onConnectionSuspended() at that function was never ever called. – Adam Varhegyi Apr 03 '15 at 11:03
  • Could you also post the code that creates mGoogleApiClient? – Anti Veeranna Apr 03 '15 at 12:51
  • @AntiVeeranna Added code in pastebin – Adam Varhegyi Apr 03 '15 at 15:34
  • I deleted my answer because I think I misunderstood the documentation. However, I just noticed something. Your latest log output shows "Google_Api_Client:connected" AND "Google_Api_Client: It was NOT connected . .." Your onConnected() method only logs one of those strings. How did you get both? – iheanyi Apr 03 '15 at 22:38
  • Nevermind, your log must be based on the pastebin version. – iheanyi Apr 03 '15 at 22:47
  • Looking at your pastebin clued me in to a potential problem. Posted an answer with what I found. – iheanyi Apr 03 '15 at 22:57
  • @AdamVarhegyi Can you share solution, if you solved this problem? As I understand, you solved this problem via iheanyi answer. Can you post this solution in pastebin – Dima May 18 '15 at 09:56
  • 1
    @Dima as iheanyi said "Try moving your googleApiClient creation to onCreate and see if you get the same behavior." it is ensures that only one instance will born from googleApiClient and your service will no longer hold wrong references. – Adam Varhegyi May 18 '15 at 10:15
  • @AdamVarhegyi thank you, I solve my problem my problem was that I hadn't remove START_REDELIVER_INTENT and it was sent again and as result it bore several instances of googleApiClient – Dima May 18 '15 at 12:02
  • http://stackoverflow.com/a/31691878/1318946 – Pratik Butani Jul 29 '15 at 05:45

9 Answers9

86

I just noticed that you are creating the googleApiClient in onStartCommand(). This seems like a bad idea.

Let's say that your service gets triggered twice. Two googleApiClient objects will get created, but you'll only have reference to one. If the one whose reference you don't have executes its callback to onConnected(), you will be connected in that client but the client whose reference you actually do have could still be unconnected.

I suspect that's what's going on. Try moving your googleApiClient creation to onCreate and see if you get the same behavior.

iheanyi
  • 3,107
  • 2
  • 23
  • 22
  • Yup, I think you got that right! http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle – EyesClear Apr 03 '15 at 23:02
  • Hi @iheanyi. I am creating my "googleApiClient" object on my MainActivity's onCreate() method. But I get this error on some devices. What can you say about this? – Sattar Hummatli Dec 12 '16 at 08:03
  • @SattarHummatli It's hard to say. The situation in this question is likely not the only way a someone can end up with this error. I would first check that you don't have a similar race condition - for example, make sure that you are only creating the googleApiClient in one place. If you still have an issue, try to put together [minimal complete and verifiable code example](http://stackoverflow.com/help/mcve) and post a question. Then respond with a comment to me with a link and I'll take a look. – iheanyi Dec 12 '16 at 22:52
3

I had the same error, but my problem was different from iheanyl's answer:

I had declared the googleApiClient static. This prevented android from shutting down the service.

Paamand
  • 626
  • 1
  • 6
  • 17
2

I had this problem to and I solved it with declaring googleApiClient as static object

Amine Choukri
  • 398
  • 2
  • 12
0

https://developer.android.com/reference/com/google/android/gms/common/api/GoogleApiClient.html

You should instantiate a client object in your Activity's onCreate(Bundle) method and then call connect() in onStart() and disconnect() in onStop(), regardless of the state.

The implementation of the GoogleApiClient appears designed for only a single instance. It's best to instantiate it only once in onCreate, then perform connections and disconnections using the single instance.

Naveen Kumar M
  • 7,497
  • 7
  • 60
  • 74
0

call connect() method in onStart()method

 @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

I think I found the root of the problem and it has nothing to do with the API. I have faced this issued every time I install the app. By the way just like the most popular comment I only have one googleApiClient upon pause and resume. What I noticed is that the permission request to get geolocation access pops up. As you know in your activity this is going to turn into a pause, and once the popup is gone it resumes your activity. Most likely your googleClient is also chained to those events to disconnect and connect. You can tell there is no connection once the permission is accepted and you are about to perform the googleApiClient task.

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

You can skip disconnecting and connecting as you set a flag which is true before permission and once the googleApiClient task is completed or granted is 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;
                    }
                });
    }

We could also split doing permission alone, and if granted then make the task call. Ok, I am going to confess I am using a fragment, and I reinstalled the app even rotated the screen on permissions and once granted, the result showed up. I hope this helps other people.

  • You don't have to uninstall the app. Simply go to setting/application manager/your app/ permissions and turn any off, then test the app again.
Juan Mendez
  • 2,658
  • 1
  • 27
  • 23
0

Moving GoogleApiClient from onStartCommand to onCeate resolved my issue

-1

I had this issue when I accidentaly but googleApiClient.connect() in oncreate and onresume. Just removed it from oncreate.

Tooroop
  • 1,824
  • 1
  • 20
  • 31
-4

moving the googleApi creation to onCreate resolved the issue for me.