13

ile jetonu almak için sessiz giriş yapın. Uygulamamda "Google Sign-In" kullanıyorum. Bu yüzden, kullanıcı e-postasını ve arka uçum için gereken kimlik belgesini almak için GoogleApiClient sınıfını kullanıyorum.GoogleApiClient

oturum açtığı, sonra ben (tabii ki) bir Faaliyet erişebilir ve ben GoogleApiClient builder.enableAutoManage arayarak UI yaşam döngüsü şeyler halledeyim o Aktivite kullandığınızda (myActivity, ...)

Bu iyi çalışıyor. Bununla birlikte, sonraki bir aşamada (birkaç gün sonra) yeni bir jeton almam gerekiyor (bir sebepten dolayı buraya daha fazla girmeyeceğim). Kullanıcı etkileşimi olmadan bu belirteci sessizce almak istiyorum. Ancak, bu yeni etikete ihtiyacım olan kodumda herhangi bir Etkinlik örneğine erişimim yok. Yani, yukarıda bahsedilen aramayı yapmak için yapamıyorum, yani "builder.enableAutoManage". Ve ben çok arama yapmazsam, o zaman sessiz girişin işe yaramadığını fark ettim.

Aşağıdaki kodu ekledim. Şimdi, "silentLogin" yöntemine bir göz atın. Kullanıcı olarak aldığım belirti asıl oturumda bir saatten daha kısa olduğu sürece "pendingResult.isDone" ifadesi doğru olarak döner ve önbelleğe alınmış jeton alınabilir. Ancak, kullanıcı olarak aldığım belirteci gerçek oturumda yaptıysa, bir saatten büyükse, o zaman "pendingResult.setResultCallback" çağrısı yapılır. ANCAK "onResult" yöntemi ASLA ARAYIR ve yeni jeton. Bir etkinlikten tam olarak aynısını yaparsam (ve bu da "builder.enableAutoManage" çağrısını yaparsanız) bu sorun oluşmaz.

Yani, herkes yanlış ve daha da önemlisi ne yapıyorum biliyor - nasıl bu sorunu çözmek ve bir faaliyet örneğine erişimi olmayan yeni bir jetonu almak üzere? Ben com.google.android.gms kullanıyorum

: play-hizmetler-kimlik doğrulama: 8.4.0

package com.google.samples.quickstart.signin; 

import android.content.Context; 
import android.os.Bundle; 
import android.util.Log; 

import com.google.android.gms.auth.api.Auth; 
import com.google.android.gms.auth.api.signin.GoogleSignInAccount; 
import com.google.android.gms.auth.api.signin.GoogleSignInOptions; 
import com.google.android.gms.auth.api.signin.GoogleSignInResult; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.Scopes; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.OptionalPendingResult; 
import com.google.android.gms.common.api.ResultCallback; 
import com.google.android.gms.common.api.Scope; 

/** 
* Use this class to login with google account using the OpenId oauth method. 
*/ 
public class GoogleLoginStackOverflow { 
    private static final String TAG = GoogleLoginIdToken.class.getName(); 
    private static final String SERVER_CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com"; 

    private GoogleApiClient mGoogleApiClient; 
    private Context mContext; 

    private GoogleLoginStackOverflow(Context appContext) { 
     this.mContext = appContext; 
     createGoogleClient(); 
    } 

    /** 
    * Performs a silent sign in and fetch a token. 
    * 
    * @param appContext Application context 
    */ 
    public static void silentLogin(Context appContext) { 
     GoogleLoginStackOverflow googleLoginIdToken = new GoogleLoginStackOverflow(appContext); 
     googleLoginIdToken.silentLogin(); 
    } 

    private void createGoogleClient() { 
     GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
       .requestProfile() 
       .requestScopes(new Scope(Scopes.PROFILE)) 
       .requestIdToken(SERVER_CLIENT_ID) 
       .requestEmail() 
       .build(); 

     mGoogleApiClient = new GoogleApiClient.Builder(mContext) 
       .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { 
        @Override 
        public void onConnectionFailed(ConnectionResult connectionResult) { 
         System.out.println("onConnectionFailed = " + connectionResult); 
         onSilentLoginFinished(null); 
        } 
       }) 
       .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { 
        @Override 
        public void onConnected(Bundle bundle) { 
         System.out.println("onConnected bundle = " + bundle); 
         onSilentLoginFinished(null); 
        } 

        @Override 
        public void onConnectionSuspended(int i) { 
         System.out.println("onConnectionSuspended i = " + i); 
         onSilentLoginFinished(null); 
        } 
       }).addApi(Auth.GOOGLE_SIGN_IN_API, gso) 
       .build(); 
    } 

    private void silentLogin() { 
     OptionalPendingResult<GoogleSignInResult> pendingResult = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); 
     if (pendingResult != null) { 
      if (pendingResult.isDone()) { 
       // If the user's cached credentials are valid, the OptionalPendingResult will be "done" 
       // and the GoogleSignInResult will be available instantly. 
       Log.d(TAG, " ---------------- CACHED SIGN-IN ------------"); 
       System.out.println("pendingResult is done = "); 
       GoogleSignInResult signInResult = pendingResult.get(); 
       onSilentLoginFinished(signInResult); 
      } else { 
       System.out.println("Setting result callback"); 
       // If the user has not previously signed in on this device or the sign-in has expired, 
       // this asynchronous branch will attempt to sign in the user silently. Cross-device 
       // single sign-on will occur in this branch. 
       pendingResult.setResultCallback(new ResultCallback<GoogleSignInResult>() { 
        @Override 
        public void onResult(GoogleSignInResult googleSignInResult) { 
         System.out.println("googleSignInResult = " + googleSignInResult); 
         onSilentLoginFinished(googleSignInResult); 
        } 
       }); 
      } 
     } else { 
      onSilentLoginFinished(null); 
     } 
    } 

    private void onSilentLoginFinished(GoogleSignInResult signInResult) { 
     System.out.println("GoogleLoginIdToken.onSilentLoginFinished"); 
     if (signInResult != null) { 
      GoogleSignInAccount signInAccount = signInResult.getSignInAccount(); 
      if (signInAccount != null) { 
       String emailAddress = signInAccount.getEmail(); 
       String token = signInAccount.getIdToken(); 
       System.out.println("token = " + token); 
       System.out.println("emailAddress = " + emailAddress); 
      } 
     } 
    } 
} 
+0

Simge dediğinizde, nasıl bir jeton sorabilir miyim? – zIronManBox

+0

Google API'sinden istediğim jeton bir kimlik jetonudur (GoogleSignInAccount.getIdToken()) –

cevap

8

sorun buldum. Ben işlevi

OptionalPendingResult<GoogleSignInResult> pendingResult = Auth.GoogleSignInApi.silentSignIn(googleApiClient); 

(o bekleyen sonuç döndürür beri) benim için mGoogleApiClient bağlamak için gittiğini sanıyordum. Ancak, bu durum ve ben sadece silentLogin yönteminin başında görüşme

ConnectionResult result = mGoogleApiClient.blockingConnect(); 

eklemek için gerekli yukarıda çözmek için değildi. doğrudur yukarıdaki cevap

Tada'

22

Evet (ve sonra tabii ki daha sonra kesmek ve ayrıca emin çağrı ana iş parçacığı farklı bir iş parçacığı yapılır olun). Genel olarak, herhangi bir veriyi size iade etmeden önce herhangi bir GoogleApiClient'in bağlanması gerekir. enableAutoManage, onStart()/onStop() sırasında otomatik olarak connect()/disconnect() öğesini çağırmanıza yardımcı olur. AutoManage kullanmıyorsanız, el ile bağlanmanız gerekir().

Ve daha da iyisi, bir nihayet bloğu kesmek gerekir.

Eğer UI iş parçacığı üzerinde değildir varsayarsak.

try { 
    ConnectionResult result = mGoogleApiClient.blockingConnect(); 
    if (result.isSuccess()) { 
     GoogleSignInResult googleSignInResult = 
      Auth.GoogleSignInApi.silentSignIn(googleApiClient).await(); 
    ... 
    } 
} finally { 
    mGoogleApiClient.disconnect(); 
} 

Ve ayrıca, biraz kodunuzu temizlemek için: 1.yapılandırma aşağıdan inşa gso yukarıdaki yapıştırılan kod aynıdır:

GoogleSignInOptions gso = 
    new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
     .requestIdToken(SERVER_CLIENT_ID) 
     .requestEmail() 
     .build(); 
    Geçerli mantık geçerli
  1. , addOnConnectionFailedListener/addConnectionCallbacks adb log dışındaki yardımcı olmuyor. Belki sadece onları tamamen kaldırmak?
+0

numaralı telefonu arayarak alabileceğiniz tek belirteç türüdür. Cevabınız için teşekkür ederim Isabella! –

+3

Google dokümanları her zaman muhteşem bir şekilde başarısız oluyor. ApiClient.connect'in girişimde bulunmadan önce veya sonra çalıştırılması kesinlikle kesin değildir. Aslında, şarkı ve bağlantıyı bölmenin yeni modeli, karmaşıklığı arttırdı, azaltmadı. Herhangi bir oranda, teşekkürler için İsmail teşekkürler, bu da bana yardımcı oldu! – Creos

+0

Bence Google dokümantasyonunun her zaman muhteşem bir şekilde başarısız olduğunu söylemek oldukça cesur bir ifade. – rupps

İlgili konular