Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Silent Google Sign In in android background service

I am running a background service in my android app. I use the IdToken that I get from the sign in activity to authenticate at the backend server. The service is running in START_STICKY mode, so even when the app is closed, the service keeps running in the background to get any notifications from the backend server. The problem I'm facing is when the IdToken expires, I am not able to renew it in the service itself. The callback function does not receive any result if the token has expired. If the token has not expired yet, it gets the result instantaneously.

Here is the code for the signIn function and handleSignIn function.

private void signIn() {
        new Thread(new Runnable() { public void run() {
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .requestIdToken("<My server_client_id>")
                .build();
        GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(context)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();

        OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn
                (mGoogleApiClient);
        if (opr.isDone()) {
            // If the user's cached credentials are valid, the OptionalPendingResult will be "done"

            // and the GoogleSignInResult will be available instantly.
            Log.d(TAG, "Got cached sign-in");
            GoogleSignInResult result = opr.get();
            handleSignInResult(result);
        } else {
            // 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.
            Log.d(TAG, "had to sign in again");
            opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
                @Override
                public void onResult(GoogleSignInResult googleSignInResult) {
                    Log.d(TAG, "got result");
                    handleSignInResult(googleSignInResult);
                }
            });
        }}}).start();
    }
like image 585
sarasgupta Avatar asked Jan 07 '16 11:01

sarasgupta


People also ask

How do I turn off background services on Android?

Stop Services Running in BackgroundOpen Settings of the phone. Now, go to the Developer Options. Tap on Running Services. Tap on the app for which you want to limit battery usage, now tap on stop.

How do I open background activity?

Intent intent = new Intent(myActivity. this, myActivity. class); PendingIntent contentIntent = PendingIntent. getActivity(this, REQUEST_CODE, intent, 0); notification.


1 Answers

Try moving the

opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
            @Override
            public void onResult(GoogleSignInResult googleSignInResult) {
                Log.d(TAG, "got result");
                handleSignInResult(googleSignInResult);
            }
        });

to before its if statement. I know the google docs say to have it the way you do and I did the same until I realized that the ResultCallback will never get called if it only gets initialized in the else block, after opr has already run.

Your code should look like this after following my suggestion:

private void signIn() {
    new Thread(new Runnable() { public void run() {
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken("<My server_client_id>")
            .build();
    GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(context)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();

    OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn
            (mGoogleApiClient);
    opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
            @Override
            public void onResult(GoogleSignInResult googleSignInResult) {
                Log.d(TAG, "got result");
                handleSignInResult(googleSignInResult);
            }
        });}}).start();
}
like image 109
Elliott Avatar answered Oct 10 '22 00:10

Elliott