3

I am writing an Android (version ICS) app. which uploads data to the Google Drive. The app uses oauth2 to acquire the access token.

First step: acquire authorization token.

    String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/drive";
    // Step 1
    accountManager.getAuthToken(
        account,                                // Account retrieved using getAccountsByType("com.google")
        AUTH_TOKEN_TYPE,                        // Auth Token Type
        options,                                // Authenticator-specific options
        this,                                   // Your activity
        new OnTokenAcquired(),                  // Callback called when a token is successfully acquired
        new Handler(new OnAuthTokenError()));   // Callback called if an error occurs
}
private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
    @Override
    public void run(AccountManagerFuture<Bundle> result) {
        // Get the result of the operation from the AccountManagerFuture.
        Bundle bundle;
        try {
            bundle = result.getResult();

            authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);

            Log.d(TAG,"authToken:" + authToken);

            exchangeToken access = (exchangeToken) new exchangeToken().execute();

        } catch (OperationCanceledException e) {
            e.printStackTrace();
        } catch (AuthenticatorException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
} 

Success. An authorization token is acquired.

Step 2: Exchange authorization token for Access Token.

    private class exchangeToken extends AsyncTask<String, Void, Void> {

    @Override
    protected Void doInBackground(String... params) {
        HttpTransport transport = new NetHttpTransport();
        JsonFactory jsonFactory = new GsonFactory();
        String CLIENT_ID = "999999999999.apps.googleusercontent.com";
        String CLIENT_SECRET = "axXXXXXXXXXXXXXXX7";

        try { // Step 2: Exchange for an access and refresh token
            GoogleTokenResponse authResponse = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, CLIENT_ID, CLIENT_SECRET, authToken, CALLBACK_URL).execute();
            accessToken = authResponse.getAccessToken();
            Log.d("Get Access","Token:" + accessToken);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}  

Fail. The LogCat shows the following: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request

{

 "error":"unauthorized_client"

}

I have been able to access "Google Drive" on my Android tablet using the "Drive" app. so my email account is valid. May be the AUTH_TOKEN_TYPE is incorrect, but the Google Drive SDK is not clear what it must be. What am I missing?

user1417943
  • 121
  • 1
  • 3
  • 3

2 Answers2

1

You do not need to do the second step of exchanging the token. Android grants you an access token directly, it does not grant you an auth code which you would have to exchange for tokens.

This page on the Android documentation explains everything really well.

Nicolas Garnier
  • 12,134
  • 2
  • 42
  • 39
  • Assuming that accountmanager.getAuthToken returns an accessToken, I decided to test the com.google.api.services.drive.Drive package with the following code: – user1417943 May 28 '12 at 01:20
0

You know that for using the Drive API your users have to install your app on the Chrome(!) Webstore? Normally Documents List API is the better choice from Android.

HelmuthB
  • 471
  • 3
  • 10
  • 1
    Really, I don't see why an Android app should be installed on the – user1417943 May 28 '12 at 00:39
  • 1
    It is true. The thing is that currently the Drive API security model is per-file. This means that only the files that you will only be able to read the files that a user have opened from the Drive Web interface with your app. This does not work yet with Android but we are working on stuff (probably special intents that you will have to register against that triggers your app from the Drive Android app). OR also a wider scoped API. Indeed currently the best way the the Document List API, please search for other posts about this. – Nicolas Garnier May 29 '12 at 23:17
  • Not true. You can use the Drive API with the same scopes as the Docs List API and get the same persmissions. – pinoyyid Aug 31 '12 at 01:38
  • @Nivco would you be able to comment on http://stackoverflow.com/questions/15001778/getting-oauth2-credentials-for-use-in-an-android-application-with-a-google-drive/15002145#15002145 or more generally the question of whether Drive is suitable as a CMS—that is, where users can put data into drive documents and the documents are then used to populate an Android app? A client specifically requested this. – Andrew Wyld Feb 21 '13 at 18:47
  • 1
    Will do. By the way this answer is not correct anymore. The Drive API v2 is now a replacement to the older Google Docs list API and has a full access scope. – Nicolas Garnier Feb 21 '13 at 21:44