web-dev-qa-db-fra.com

Exception "GoogleApiClient n'est pas encore connecté" dans l'application Distribution.

Je développe une application Android qui convertit le contenu sur Chromecast . Parfois, dans mon implémentation com.google.Android.gms.common.api.GoogleApiClient.ConnectionCallbacks dans la méthode onConnected, je reçois un 

Java.lang.IllegalStateException: GoogleApiClient is not connected yet.

exception.

Voici la trace de la pile:

    FATAL EXCEPTION: main
 Process: com.joaomgcd.autocast, PID: 13771
 Java.lang.IllegalStateException: GoogleApiClient is not connected yet.
    at com.google.Android.gms.internal.eg.a(Unknown Source)
    at com.google.Android.gms.common.api.GoogleApiClient.b(Unknown Source)
    at com.google.Android.gms.cast.Cast$CastApi$a.launchApplication(Unknown Source)
    at com.joaomgcd.autocast.media.MediaConnectionCallbacks.onConnected(MediaConnectionCallbacks.Java:37)
    at com.google.Android.gms.internal.dx.b(Unknown Source)
    at com.google.Android.gms.common.api.GoogleApiClient.bn(Unknown Source)
    at com.google.Android.gms.common.api.GoogleApiClient.f(Unknown Source)
    at com.google.Android.gms.common.api.GoogleApiClient$2.onConnected(Unknown Source)
    at com.google.Android.gms.internal.dx.b(Unknown Source)
    at com.google.Android.gms.internal.dx.bT(Unknown Source)
    at com.google.Android.gms.internal.dw$h.b(Unknown Source)
    at com.google.Android.gms.internal.dw$h.b(Unknown Source)
    at com.google.Android.gms.internal.dw$b.bR(Unknown Source)
    at com.google.Android.gms.internal.dw$a.handleMessage(Unknown Source)
    at Android.os.Handler.dispatchMessage(Handler.Java:102)
    at Android.os.Looper.loop(Looper.Java:136)
    at Android.app.ActivityThread.main(ActivityThread.Java:5017)
    at Java.lang.reflect.Method.invokeNative(Native Method)
    at Java.lang.reflect.Method.invoke(Method.Java:515)
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:779)
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:595)
    at dalvik.system.NativeStart.main(Native Method)

Cela ne semble se produire que si je m'étais déjà connecté à GoogleApiClient auparavant et que je me connecte une seconde fois. Entre les 2 appels, je me déconnecte du client api avec le code ci-dessous.

Je suppose que c'est un bug. Ai-je raison? Puisque je suis dans la méthode onConnected, le GoogleApiClient devrait déjà être connecté.

Que puis-je faire pour le contourner? Devrais-je attendre un moment que le GoogleApiClient soit vraiment connecté?

Je le fais dans un service et voici les bits pertinents:

quand le service commence:

mMediaRouter.addCallback(mMediaRouteSelector, mediaCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);

mediaCallback a ce code:

@Override
    public void onRouteAdded(MediaRouter router, RouteInfo route) {
        super.onRouteAdded(router, route);
        if (route.getDescription().equals("Chromecast")) {
            ...
            mSelectedDevice = com.google.Android.gms.cast.CastDevice.getFromBundle(route.getExtras());

            ...
                castClientListener = new CastListener(context, apiClient);

                Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions.builder(mSelectedDevice, castClientListener);
                ...
                apiClient.set(new GoogleApiClient.Builder(context).addApi(Cast.API, apiOptionsBuilder.build()).addConnectionCallbacks(connectionCallback).addOnConnectionFailedListener(new MediaConnectionFailedListener(context)).build());
                apiClient.get().connect();
        }

    }

connectionCallback a ce code:

@Override
    public void onConnected(final Bundle arg0) {
        ...
            Cast.CastApi.launchApplication(apiClient, UtilAutoCast.CHROMECAST_APP_ID, false).setResultCallback(connectionCallback);
        ...
    }

Le code ci-dessus est la partie où le crash se produit.

Et quand j'arrête le service, je lance ce code:

if (mMediaRouter != null) {
    mMediaRouter.removeCallback(mediaCallback);
    mMediaRouter = null;
}
if (apiClient != null) {
    Cast.CastApi.stopApplication(apiClient);
    if (apiClient.isConnected()) {
        apiClient.disconnect();
        apiClient = null;
    }
}

Merci d'avance.

12
joaomgcd

API Google pour Android> GoogleApiClient

Vous devez instancier un objet client dans la méthode onCreate (Bundle) de votre activité puis appeler connect () dans onStart () et disconnect () dans onStop (), quel que soit l'état.

L'implémentation de GoogleApiClient semble conçue pour une seule instance. Il est préférable de ne l'instancier qu'une seule fois dans onCreate, puis de réaliser des connexions et des déconnexions à l'aide d'une seule instance. 

Je suppose que seule une GoogleApiClient peut être connectée, mais plusieurs instances reçoivent le rappel onConnected

Dans votre cas, il est probablement correct de ne pas appeler connect dans onStart, mais seulement dans onRouteAdded

Je pense que ce problème est très similaire à Fatal Exception: Java.lang.IllegalStateException GoogleApiClient n'est pas encore connecté

7
mattm

Avez-vous déclaré après<meta>tag 

<application ...> 
... 
    <meta-data
        Android:name="com.google.Android.gms.version"
        Android:value="@integer/google_play_services_version" />
... 
</application>

J'ai juste oublié d'écrire afin que vous puissiez également rester avec cette raison.

Je vous remercie.

5
Pratik Butani

Depuis l'application de démonstration ( Googlecast exemple d'application CastHelloText-Android ) du récepteur est lancé surRouteSelected (et non surRouteAdded comme vous le faites dans votre code). J'essaierais de changer ça. Au cas où cela ne fonctionnerait pas, j’ajouterais des lignes de journal dans chaque méthode liée à la connexion et à la session, et je verrais ce qui se passe.

Autre astuce: j'ai eu un blocage lors de l’arrêt de l’application (dans le cas où l’appareil de chromecast est physiquement débranché). La solution est de mettre Cast.CastApi.stopApplication(apiClient); dans if (apiClient.isConnected()).

2
Drez

Il semble que vous appeliez GoogleApiClient avant qu'il ne soit connecté

déplace cette ligne dans onCreate ()

// First we need to check availability of play services
    if (checkPlayServices()) {

        // Building the GoogleApi client
        //buildGoogleApiClient();
        try {
            mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();

            mGoogleApiClient.connect();
        }catch (IllegalStateException e)
        {
            Log.e("IllegalStateException", e.toString());
        }
        createLocationRequest();
    }

J'espère que ça vous aide.

0
Deepak