Shared publicly  - 
 
Here are a series of steps you can use in order to integrate an Android app with the Google Play Services, particularly for the sake of accessing a user's Google Drive documents.  See below for a link to some sample code that ties it all together.

=======================================================

Step 1: Create an account for Google API Services, and access your Google APIs Console.

Create an entry for your application, -- "Create" a new "Project" if you don't have one already, then create an OAuth2 key "for installed applications" (assuming you're writing an Android app).  This generates a "Client ID" which you'll use in about 15 seconds.  Part of this process involves obtaining the SHA1 fingerprint of my debug key, which I obtained by using the jre7 version of keytool to read the debug.keystore file.  This allowed me to use the "Drive-initiated authorization" listed at https://developers.google.com/drive/about-auth#drive-initiated_authorization because I'm not intending to override any other phase of the OAuth2 process or involve any other APIs that aren't in Drive.  Remember to change this to the actual signed key once you make the release version of your APK.

Back in "Services", enable the Google Drive API and Google Drive SDK, and this will activate an option in your sidebar called "Drive SDK".  You must fill this page out with the pertinent data relating to your application.  This data includes the following:

* Put in an Application Icon.

* The Client ID is something you must generate when you create an OAuth 2.0 key in general.  Just copy that Client ID into the appropriate box.

* Make up a URL for the "Open URL."

* Throw in mime types you care about. Most folks might want to specify actual MIME types that the app is allowed to open, but for now, I only want to open up the reserved Google document types (e.g. application/vnd.google-apps.spreadsheet), which the SDK Panel won't let me specify as a MIME type to open.  If you're only interested in the document types Drive lets you create within itself, check the "Import: Allow users to open files that can be converted to a format that this app can open" box.  Check out https://developers.google.com/drive/enable-sdk -- especially the "Setting MIME types and extensions" section for more details.

* Add some Google API Scopes.  There are two required for Drive apps: https://www.googleapis.com/auth/userinfo.email and https://www.googleapis.com/auth/userinfo.profile.  https://www.googleapis.com/auth/drive.file should be included by default, but it may be prudent to still list it here anyway.  There are some others listed at https://developers.google.com/drive/scopes.  One basic one worth including in many cases is https://www.googleapis.com/auth/drive, which allows access to all files on the user's Dtive.  For read-only access to all documents, use https://www.googleapis.com/auth/drive.readonly.

Make sure to save your changes and then check the top (PgUp) to see if any of the input was invalid.  Make any necessary changes until Google notes your changes were saved successfully.


Step 2: Watch this Google IO 2012 presentation, or thumb through the slides: https://docs.google.com/presentation/d/1LrEKp2PqESsES3upS1xsSARz35KS-9QHnYFTKvS2yzM/preview#slide=id.p19

While this will help you write your code, there are definitely some key pieces missing from it, and also things that will cause errors once you think everything's been implemented.  Here are the pitfalls:

* Slide 17 has a typo in the unbolded area which is corrected in the bolded area in slide 18 -- Context does not know what startActivityForResult is.  Activity does, so since I usually make it available as a class variable, the asynchronous process knows what it is without me having to pass it in.

* The 'setQ("mimeType=text/plain")' method invocation mentioned in slide 36, when used just as written, seems to produce an error: "Invalid Value".  It becomes apparent from looking at the XML message that the error came from the value in "q"; it seemed to work better once I put 'setQ("mimeType=\"text/plain\"")' -- note the escaped quotes around text/plain.  However, this query is optional.  

* Finally, and this is very important, is the line:

return GoogleAuthUtil.getToken(ctx, account.name, "oauth2:" + DriveScopes.DRIVE_READONLY);

Note that, in the presentation, it's listed as DriveScopes.DRIVE_FILE.  This only gives you access to the files the user has already created with the app.  This may be what you want in some instances, but for my app, I need DRIVE_READONLY.  DriveScopes.DRIVE gives the program full, unfettered R/W access to any user files, which is beyond what I need.  This was described above in the "Google API Scopes" area.

=======================================================

Once this has been done, and the considerations above have been taken (which may not be all the ones I had to make, but the sample code definitely works), you'll be able to use Google Play Services to connect to Google Drive.

Oh, by the way, here are the relevant pieces of a Java activity I wrote that does all this: http://one-dollar.us/DriveActivity.java  Note it doesn't take care of practically any exception cases properly, notify the user what the heck's going on while it's fetching the files, or even fetch the files if the user has to tap the "Yes, I really want to do this" button.  I also suspect there are probably some code paths that aren't necessary in here, or are unreachable because I put in the capability to do things 2 different ways and it only ever uses one.  The good news is that the most important feature works!

=======================================================

Example code relating to GoogleAuthUtil, also features nice asynchronous wrapper: https://developers.google.com/android/google-play-services/reference/com/google/android/gms/auth/GoogleAuthUtil  I got some more ideas from here https://developers.google.com/drive/examples/java#making_authorized_api_requests, but this page didn't end up being too useful.

This piece of code provided some insight as to how to possibly include the authentication token into the http://code.google.com/p/google-oauth-java-client/wiki/OAuth2#Servlet_authorization_code_flow
About Authorization. All requests from Google Drive applications must be authorized by an authenticated user. Special Google Drive requirements for the OAuth 2.0 web server flow are described in this ...
7
3
Rtest Rtest's profile photoDaniel Kim's profile photoHugues Latour's profile photoNilesh Raut's profile photo
13 comments
 
may I know what is the MyApp.accountName?
Can you include a working Android project example instead of 1 single java file?
I had been trying for days but still failed
I read your reply on stackoverflow but that does not help
thanks in advance
 
In my code, "MyApp" is a class that basically provides global variables.  MyApp.accountName is a public static String, and at first it's simply the String of the account name (such as "awesomeDevDude@gmail.com"). At this point, you could use AccountManager.KEY_ACCOUNT_NAME and "account.name" just the same way wherever they're in scope.  Then, it becomes the actual OAuth token once you get into the onPostExecute() section of the AsyncTask.  The last thing that happens is getDriveFiles() accesses the files -- this method calls getDriveService(), which expects MyApp.accountName to be the OAuth token.  I suppose I should clear this up in the future since it gets a little ambiguous.  Regardless, it's nothing you set for yourself.

Anyway, not sure how much the full code will help you, as most of the complicated parts lie in how you set up the Google APIs Console.  One thing I'm discussing w/someone else right now is how to configure the "Client ID for installed applications" section in the "API Access" panel.  They chose to make an "Other" app instead of an "Android" app.  So in this panel, if you've already created your OAuth 2.0 key but have an incorrectly-configured app, you should click on "Create another client ID..." button, choose "Installed application", then "Android", then fill in your package name and SHA1 key.  To get the SHA1 key, use something like this: 

C:\Program Files\Java\jre7\bin\keytool.exe -list -keystore debug.keystore

Note you must use the JRE7 version of keytool, as the JRE6 version produces an MD5 fingerprint instead.  I actually created a new binary from new code (stripped out a bunch of proprietary stuff), and in fact, it didn't work because I need to add another Client ID for this particular package.  If you need something more, please invite me to a chat and we can discuss it in person.

(In fact, if you need to "create another client ID", you might have to kill your project in APIs Console and start it over.  Seems like Google has some bugs to work out.)
 
Thanks alot for the reply!
It was very helpful, especially the second part
I was getting error 403 and error 401 when I playing around with the client ID
i tried set my client ID in the code as seen from some example in stackoverflow, but as claudio mentioned we should not set the client ID in code.
I will try your suggestion by tonight, probably will need to kill my project in API console because I already created 3 client ID for "Android installed applications"
I will feed back to you if everything goes well =) Thanks!

also, you should mention which jars you put in libs folder in your tutorial
It took me quite awhile to figured it out =x
 
Seems like I cant add you into a chat eventho I added you into my circle
Anyway, I am still getting error 403
I tried your suggestion, using jre7 to create the SHA1 key
But I am not sure where to find a .keystore file
So I am using my google play keystore file to generate the SHA1 key

Then I recreate new API project in google console
Done everything, using your 1dollar code
Added those api jars, mostly v1.12.0
and google-api-services-drive-v2-rev9-1.8.0-beta.jar

Then I am getting error 403 now

1 problem that I do not understand is, why dont we need to insert our CLIENT ID in code?
How can the server side know under which API project is the authtoken generated. (now it is generated only by user google account)

a guy in stackoverflow
http://stackoverflow.com/questions/12164024/android-open-and-save-files-to-from-google-drive-sdk/12321331#12321331
he said he successfully auth with googldrive using his code
In his code, he did driveRequest.setKey(CLIENT ID)
But in your code, you didnt.
However, as Claudio Cherubino mentioned in another post, we should not set CLIENT ID like this, instead we should let play services to authenticate

sorry for the lost post on your wall
and thanks for your reply
 
I'm happy you figured it out!  Hopefully you can use your knowledge to make a cool app and help answer any Drive questions people have. :-)
 
madam i found this type of error.java.lang.RuntimeException: Unable to resume activity {com.example.android.notepad/com.example.android.notepad.Preferences}: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.google.android.gms.common.account.CHOOSE_ACCOUNT (has extras) }
please help me wht i  do now
 
Here are a couple things to try:
1. You can only use this on a real device.  It won't work on an emulator.
2. If you're using a Service defined in your Android Manifest, remember to define an intent filter in it, like this:
    <intent-filter>
        <category android:name="android.intent.category.DEFAULT" />
        <action android:name="android.accounts.AccountAuthenticator" />
    </intent-filter>
3. Lots of things have changed since I did hard-core Android development.  Try searching Google; plenty of others have hit this problem.

Also, my profile picture is of a woman competing on a game show (and looking baffled by the question), but I'm a man.
 
Hello All

Is there anybody can please provide the source code. Thanks in advance because I already spend too much time for this . I am not able to upload the icon of my application also . So Please help me out .
 
Hi Om, check this out: http://stackoverflow.com/questions/12164024/android-open-and-save-files-to-from-google-drive-sdk/12321331#comment18575553_12321331  This Stack Overflow page details the "official" way Google tells you to add this capability, which they wrote after I made this blog post.  I can't seem to find sample code for my method that's already been posted anywhere & verified to work for people.  If you have problems with Google's method, you can ping me or Claudio Cherubino on G+ who works at Google.
 
Hi Stephen Wylie

Thanks for your reply, Now I checked few applications those who shows a login page to retrieve the credentials from user. I want to implement the same in my application,  Do you have any idea about it. How are they doing that ? Please help me out.

Regards
Om
 
Hi StephenWylie
I am working on google drive integration, It is working properly, but when i try to run on another device and using for another account it showing error
i.e. com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException, please give me any suggestion to solve this..
Thanks in advance
 
Hi StephenWylie

I have followed all the steps on android developer site to integrate google drive API in android application. I created Client ID on developer console with debug key as well as release key. But I am getting the error "Unfortunately, google play services has stopped." What should be the reason behind this? I have spent many hours searching on google for this issue, but can't find solution. 

Does the Drive API setting is required for android app? Or should I put the Client ID in manifest file? Please help me.

Thanks in advance.
Add a comment...