2

I am using Google Cross Client Identity. Procedure which I had followed for this is:

a) Create a project in Google API Console. b) Generate Client-Id for installed app(Android) c) Generate Client-Id for web application. d) I have to use Google Drive of user at server-end(offline) after he/she verifies it at Android end.

For this I create scope like this:

String CLIENT_ID = "60000000007.apps.googleusercontent.com"; String scope = "server:client_id:"+CLIENT_ID+":api_scope:"+DriveScopes.DRIVE+" "+"https://www.googleapis.com/auth/plus.login";

Now I have to retrieve Authentication Code, which I have to forward to my server end. For this here is my full source code:

package com.example.googleaccess;

import java.io.IOException;

import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.plus.PlusClient;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.services.drive.DriveScopes;


public class MainActivity extends Activity {

    private String accountName = null;
    private GoogleAccountCredential credential;
    private int REQUEST_ACCOUNT_PICKER = 2;
    private int REQUEST_AUTHORIZATION = 11;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String CLIENT_ID = "60000000007.apps.googleusercontent.com";
        String scope = "server:client_id:"+CLIENT_ID+":api_scope:"+DriveScopes.DRIVE+" "+"https://www.googleapis.com/auth/plus.login";
        credential = GoogleAccountCredential.usingOAuth2(MainActivity.this, scope);
        startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
        GooglePlayServicesUtil.isGooglePlayServicesAvailable(MainActivity.this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return false;
    }

    class Async extends AsyncTask<Void, Void, Void> {

        Context credential = null;

        public Async(Context credential) {
            this.credential = credential;
        }

        @Override
        protected Void doInBackground(Void... params) {
            getAccessToken(credential);
            return null;
        }

    }

    public void getAccessToken(Context mContext) {

        try {

            String token = credential.getToken();
            Log.d("Token", "token:"+token);
        } catch (GooglePlayServicesAvailabilityException playEx) {
            playEx.getMessage();
            playEx.printStackTrace();

          }catch (UserRecoverableAuthException e) {
            e.printStackTrace();
            Log.d("Token", "token:"+e.getCause());

            startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("Token", "token:"+e.getMessage());
        } catch (GoogleAuthException e) {
            e.printStackTrace();
            Log.d("Token", "token:"+e.getMessage());
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == REQUEST_ACCOUNT_PICKER) {
            if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
            accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);

                if (accountName != null) {
                  credential.setSelectedAccountName(accountName);

                  new Async(getApplicationContext()).execute();
                }
              }
        }

        if(requestCode == REQUEST_AUTHORIZATION) {
            if (resultCode == Activity.RESULT_OK) {
                data.getExtras();
                new Async(getApplicationContext()).execute();
              } else {
                  startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
              }
        }
    }


}

Here I am handling UserRecoverableAuthException so that user could verify the app.

Everything work's fine n this code, when asked for permission to access data I allow it through device. But again I get the screen to verify app as getToken() always through same Exception. I don't know where I am lacking.

Also my code work's fine if I have to retrieve only access token using scope:

String scope = "oauth2:"+DriveScopes.DRIVE;

There is also an weird problem I am facing this code work's fine on emulator 4.2 Google API 17 version. But not on any device.

Here is my Logcat outfor this code:

07-23 18:03:36.992: W/GLSActivity(9639): [qq] Status from wire: NeedPermission status: NEED_PERMISSION
07-23 18:03:37.414: W/System.err(9626): com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission
07-23 18:03:37.414: W/System.err(9626):     at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
07-23 18:03:37.414: W/System.err(9626):     at com.example.googleaccess.MainActivity.getAccessToken(MainActivity.java:84)
07-23 18:03:37.414: W/System.err(9626):     at com.example.googleaccess.MainActivity$Async.doInBackground(MainActivity.java:67)
07-23 18:03:37.421: W/System.err(9626):     at com.example.googleaccess.MainActivity$Async.doInBackground(MainActivity.java:1)
07-23 18:03:37.421: W/System.err(9626):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
07-23 18:03:37.421: W/System.err(9626):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
Sagar Trehan
  • 2,401
  • 2
  • 24
  • 32

1 Answers1

0

This question has also been asked here:

Android Google+ integration - repeated UserRecoverableAuthException

No solution has been found yet, but the investigation is ongoing.

Community
  • 1
  • 1
Lee
  • 3,972
  • 22
  • 17
  • Is there be any alternative to used for this? – Sagar Trehan Jul 23 '13 at 14:57
  • May be reason behind it is that my device not able to register app in account, even after user pressed OK button. – Sagar Trehan Jul 24 '13 at 07:41
  • Why GOOGLE make products without testing it properly on all devices? Now to whom I should asked for help. – Sagar Trehan Jul 24 '13 at 07:45
  • Hey is anybody finds it's solution. I have to implement it in my app – Sagar Trehan Jul 26 '13 at 19:23
  • Since when did the GoogleAuthUtil.getToken() method start throwing a GoogleAuthException with message "BadUsername" for an email that is not registered on a device, instead of the previous exception IllegalArgumentException with message "Non existing account 'email_address'" ? http://developer.android.com/reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context , java.lang.String, java.lang.String) – Etienne Lawlor Nov 06 '13 at 02:34
  • when you DEBUG you are not using the correct keystore... so the sha1 of your DEBUG is different! so you need to have another access key in your https://console.developers.google.com/ -> api credentialsl..! it will work in appstore! but not on debug ;) – Sebastiaan van Dorst Jan 27 '15 at 11:18