Using the Android Drive API, when trying to connect using:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API).addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
getGoogleApiClient.connect();
I get the select an account screen and after selecting an account, I see this:
View and manage Google Drive files that you have opened or created
with this app
What if I what to access files created by other apps?
Is there a way for my application to ask for authorization of a specific folder?
Google Play Services client library provides an Android developer with APIs for seamless integration with the individual Google services.
The library also let your apps offers a consistent user interface to obtain authorization from users to access these services with their credentials.
Access to Google Drive Service
Google Play services client library ships with Google Drive Android API that provides access to the Google Drive service.
However, Google Drive Android API currently offers only drive.file and drive.appfolder authorization scopes which are limited in a way if your app needs access to all the contents on the user's drive.
To provide drive scope, you will need to use REST APIs offered by Drive API Client Library for Java. This library has a dependency on Google APIs Client Library for Java that offers generated client libs for access to individual Google services using REST APIs from any application (web, installed or Android)
Download the Drive API v2 Client Library for Java. The libs folder contains all the globally-applicable dependencies (Google APIs Client Library for Java) you might need across all application types (web, installed, or Android application).
For Android, you will need the following jars (as described in drive/readme.html) to sort out the dependencies
google-api-services-drive-v2-rev143-1.19.0.jar
google-api-client-1.19.0.jar
google-api-client-android-1.19.0.jar
google-http-client-1.19.0.jar
google-http-client-android-1.19.0.jar
google-http-client-gson-1.19.0.jar
google-oauth-client-1.19.0.jar
gson-2.1.jar
jsr305-1.3.9.jar
Authorization
Before accessing Google Drive (or any other Google) service, you need to authorize your application (using OAuth 2.0)
For applications using Google Play Services client library, this will be handled by GoogleApiClient.
However, if the service/Google API you want to use is not included in the Google Play services library, you can connect using the appropriate REST API to manually make requests or using a client library provided by the service provider, but you must obtain an OAuth 2.0 token.
For drive scope, you need to use Google APIs Client Library for Java and the generated client libraries (drive v2, in our case). To obtain an authorization token, you can either -
directly use the OAuth 2.0 library from Google APIs Client Library for Java (not preferred for android)
or leverage the authorization portion of the Google Play services library using GoogleAuthUtil and AccountPicker. Read Authorizing with Google for REST APIs. (GoogleAuthUtil.getToken() caches and manages token expiry and refresh itself. However, in case of network errors/server load, you might need to use an exponential back-off algorithm before retrying for the token so to not flood the server with requests. Refer 3)
or use the GoogleAccountCredential defined in google-api-client-android-1.19.0.jar that comes with Google APIs Client Library for Java. The package offers Utilities based on Google Play services and GoogleAccountCredential is just a wrapper around GoogleAuthUtil and AccountPicker. This would allow you to use the same consistent authorization flow and the standard account picker UI that comes with Google Play services client library while delegating the token management and using an exponential back-off strategy (as noted above) to GoogleAccountCredential. Refer 1 for an example.
Note that with the last two approaches, you are using both Google Play services client libraries (for authorization) and Google APIs Client Library for Java along with Drive API v2 Client Library for Java (for access to Google Drive service with drive authentication scope).
Package references
Google Play Services client library
Drive API Client Library for Java
Google API Client Library for Java 1.19.0
Also checkout -
http://www.techsfo.com/blog/2014/03/android-preparing-to-access-google-drive-with-an-app-part-1/
http://developer.samsung.com/android/technical-docs/Using-Google-APIs
Google Play services and OAuth Identity Tools
This answer also posted at my blog here.
Google Drive Android API only support two scopes:
drive.file: (https://www.googleapis.com/auth/drive.file)
Per-file access to files created or opened by the app
drive.appdata (https://www.googleapis.com/auth/drive.appdata)
Allows access to the Application Data folder
You need to use the Google Drive web service (https://developers.google.com/drive/v2/reference/) and your application must use the Google APIs Client Library for Java. (https://code.google.com/p/google-api-java-client)
The scope for full access: "https://www.googleapis.com/auth/drive"
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
credential.setSelectedAccountName(accountName);
Drive service = new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build();
Don't use the API provided by Google Play Services. It doesn't support DRIVE scope. Without DRIVE scope, you don't have enough privilege to access files created by other apps.
You may use DriveScopes.DRIVE, this is what I'm doing in my app. My android app needs to exchange data with my legacy desktop app.
You need to use API from Java Jar library. https://developers.google.com/drive/web/quickstart/quickstart-java A lot of JAR files need to be included, which will increase your final APK size. But, with the help of ProGuard, the size of APK is still manageable.
However, I foresee Google will soon enforce developers to use only Google Play Services, which is part of their business strategy. So, you need to have some sort of backup plan, in case that happens.
For further information, please refer to https://stackoverflow.com/questions/21807602/migration-strategy-for-google-drive-android-api-from-google-api-java-client-go and Plans for drive.appdata scope in android google drive API
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
I think you missed the addScope, I never worked with it myself but this is what i could find missing, when looking at the documentation.
documentation
Related
I've been trying for a while now to create an application where the users can sign in with their Google Account and the application will automatically upload some files into the users google drive.
So far I've managed to implement the Sign In mechanism but for the Google Drive integration I'm kind of confused if I should use a Service Account or not.
I've found this solution here Google Drive API implementation Xamarin Android but this way too old, and I can't find any updated solutions.
If anyone knows any solution or any suggestion I will appreciate it.
Think of serive accounts as a dummy user, this user can then be preauthorized to access some data.
You could share a folder on google drive with a service account and then the service account would have access to that folder on google drive.
Service accounts are intended for use by developers to access data they control.
If you are going to access the users account then you will need to use Oauth2, and request consent of the user to access their google drive account.
Unforuantatly it appears that Google Drive Android API used in the question you have linked is deprcated.
I can also tell you that the Google .net client library does not support Xamarin authorization.
I have real time notification configured for app and I do get response like Subscription Id and Purchase token, based on this reponse I want to call additinal api to get more data like subscription, purchase and transactional details. I need to call thise api in .net. Please let me know if such api exists and how to call it in .net.
Based on google documentation I see purchases.subscriptionsv2.get api but I don't know how to configured so that I can call it in .net app.
Thanks,
I'm familiar with developing against Google services although I'm unfamiliar with Play and its APIs
Google (automatically) exposes all its services (APIs) through machine-generated client libraries called API Client Libraries.
Here's the list for .NET. There are several for "Google Play".
Here's the .NET documentation for Android Developer API Client Library for .NET
Alternatively you can use APIs Explorer to browse all Google's services.
Here's the documentation for Google Play Android Developer API and subscriptionsv2 which includes the get method including its request|response bodies.
Lately, I have been working a lot with Google APIs on Android especially Analytics, AdSense and Tasks API.
I have seen some samples provided by Google where they use this statement to obtain a GoogleAccountCredential object
https://code.google.com/p/google-api-java-client/source/browse/tasks-android-sample/src/main/java/com/google/api/services/samples/tasks/android/TasksSample.java?repo=samples
credential =
GoogleAccountCredential.usingOAuth2(this, Collections.singleton(TasksScopes.TASKS));
However, If I go through the documentation such as:
http://developer.android.com/google/auth/http-auth.html
http://developer.android.com/google/play-services/auth.html
Both of them mention the below method to be used for obtaining a token:
token = GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
I am confused which one to use in which scenario and why. I have been using Method no. 1 successfully and without the need of persisting the token in preferences (I guess this is done by GoogleAccountCredential automatically)
Can anyone tell me why would anyone use the first method as opposed to second ?
How can I access the auth token in the first method ?
The Google APIs Client Library for Java is as the name suggests a library for accessing Google APIs and it is available for several platforms such as Java (in general) and Android while the Google Play Services and GoogleAuthUtil is only available on Android.
By looking at the wiki page of the project it is difficult to understand how Google APIs Client Library relates to GoogleAuthUtil since the wiki suggests that the AccountManager is used for handling Google accounts and it doesn't really mention GoogleAuthUtil at all.
However if you dig into the code and their issue tracker a bit you can see that the tasks sample you linked actually uses GoogleAuthUtil since version 1.12.0 of the Google APIs Client Library when support for GoogleAuthUtil was added.
The wiki is probably mention the AccountManager instead of GoogleAuthUtil since that was the way to do OAuth2 authentication before GoogleAuthUtil was available and because that part of the wiki has not been updated yet.
For more information on the differences between the AccountManager and GoogleAuthUtil please see: In a nutshell what's the difference from using OAuth2 request getAuthToken and getToken
In short Google APIs Client Library is a cross platform library for interacting with Google's services and the Android version is implemented by using GoogleAuthUtil.
Can anyone tell me why would anyone use the first method as opposed to second ?
Reasons for using Google APIs Client Library
If you are developing for some other platform than Android you can not use GoogleAuthUtil as it is an Android specific library.
If you are developing a cross platform application you can use the Google APIs Client Library in your shared code for for both Android and other platforms.
If you interact a lot with many of Google's services this library may make things easier for you.
If you are already using this and it works as wanted there isn't really any drawback to continue using it as it is a wrapper for GoogleAuthUtil so you get all the advantages of GoogleAuthUtil compared to using the AccountManager or some other library based on the AccountManager.
Reasons for using GoogleAuthUtil
Using this requires no other libraries or external dependencies than the Google Play Services
Your app's footprint should be smaller since you don't have to include additional libraries.
If your interaction with Google is limited it might be easier to just use the GoogleAuthUtil directly instead of going trough another library.
GoogleAuthUtil shouldn't be that hard to use as it is, so using a library that wraps around it to simplify it might not be that much easier to use.
I am confused which one to use in which scenario and why. I have been using Method no. 1 successfully ...
If you are using the Google APIs Client Library and it works fine for you I don't see any reason why you shouldn't continue using it.
However if I would create an Android (only) application that needed to interact with Google's services I would probably use GoogleAuthUtil directly.
... without the need of persisting the token in preferences (I guess this is done by GoogleAccountCredential automatically)
Yes I this is automatically handled by GoogleAuthUtil which is in turn used by GoogleAccountCredential.
How can I access the auth token in the first method ?
You should be able to call the method getToken() on the GoogleAccountCredential object.
Google Play Services client library is written specifically for Android devices to offer a seamless integration with individual Google services and a consistent user interface to obtain authorization from users to access these services with their credentials.
Google APIs Client Library for Java is a generic library to access Google Services from all application types (web, installed, or Android application).
Coming back to Android, if the Google API you want to use is not included in the Google Play services library, you can connect using the appropriate REST API, but you must obtain an OAuth 2.0 token.
To obtain a token, you can either -
directly use the OAuth 2.0 library from Google APIs Client Library for Java (not preferred for android)
or leverage the authorization portion of the Google Play services library using GoogleAuthUtil and AccountPicker. Read Authorizing with Google for REST APIs. (GoogleAuthUtil.getToken() caches and manages token expiry and refresh itself. However, in case of network errors/server load, you might need to use an exponential back-off algorithm before retrying for the token so to not flood the server with requests.)
or use the GoogleAccountCredential packaged in google-api-client-android-1.19.0.jar that comes with Google APIs Client Library for Java. The package offers Utilities based on Google Play services client libraries and GoogleAccountCredential is just a wrapper around GoogleAuthUtil and AccountPicker. This would allow you to use the same consistent authorization flow and the standard account picker dialog that comes Google Play services client library while delegating the token management to GoogleAccountCredential. Refer this for an example.
Method number one (com.google.api.client.googleapis.extensions.android.gms.auth.*) is part of Google's more general, cross platform account management flow, while method number two (com.google.android.gms.auth.GoogleAuthUtil) is Android specific. It looks like the various Android Google APIs, method two, wrap and simplify method one. For instance, the Google+ documentation, second paragraph, states "The Google+ Sign-In button authenticates the user and manages the OAuth 2.0 flow, which simplifies your integration with the Google APIs."
I would the Android specific method, token = GoogleAuthUtil.getToken(mActivity, mEmail, mScope), wherever possible.
I am trying to integrate my app with a Google API, say Google Tasks,
Before Google Play Services I would use the Google APIs Client Library for Java and the AccountManager to retrieve and access the OAUTH token for the API.
The pros of this methos is that I can:
Using the Java client APIs smoothly to access all the API methods my app may need.
the cons is that:
The Authentication Dialog is very bad looking and confusing to the user (As mentioned in Google IO Play services session)
I will need to add all kind of permissions to the app.
I guess 'Google play services' came to change all that:
No app permission is needed as its directly taken from the play services and then eventually from the user
It also offered the new beautiful AccountPicker that make authentication clearer to the user.
But the ease of access to the Java Client library API methods is lost!!! I have to create all the requests by myself.
The question is What is the best way to authenticate and request the OAUTH token using play services and after that continue to work with the Client library APIS to access the actual API methods?
You should be able to pass the result of GoogleAuthUtil.getToken (from Google Play Services) directly to GoogleCredential.setAccessToken (from the Google APIs Client Library).
An example of the latter can be found in TasksSample.java. In fact, since the AccountManager.getAuthToken and GoogleAuthUtil.getToken APIs are so similar, save for the asynchronous vs. synchronous difference, you should be able to modify that Tasks sample to use Google Play Services without too much difficulty.
Some very rough pseudocode would be:
...
// this should all be in a separate thread (e.g. AsyncTask)
final String token = GoogleAuthUtil.getToken(context, email, scope);
GoogleCredential credential = new GoogleCredential();
credential.setAccessToken(token);
Tasks service = new Tasks.Builder(transport, jsonFactory, credential)
.setApplicationName("Google-TasksAndroidSample/1.0")
.setJsonHttpRequestInitializer(new GoogleKeyInitializer(ClientCredentials.KEY))
.build();
List<String> result = new ArrayList<String>();
Tasks.TasksOperations.List listRequest = service.tasks().list("#default");
listRequest.setFields("items/title");
List<Task> tasks = listRequest.execute().getItems();
...
I am trying to access Google Drive files from my android app and my website.
I used two client ids, one for the android app (Client ID for installed applications) and the other one for the website (Client ID for web applications). Those client ids are belong to the same google apis project.
Both Android and web applications are working properly. They can upload and list files. (their scope: https://www.googleapis.com/auth/drive.file = Per-file access to files created or opened by the app)
Here is a problem,
Files that uploaded from Android app are not visible from web application...
I guess even if Android and web app have client ids from same google apis project, Google does not think they are one application service.
Is there any way to solve this problem?
I wonder if there is a way to use one same google apis client id to web and Android app, or grant permission to read and modify files from both apps.
This is a known limitation from Android's OAuth 2.0 flow that will be resolve with the release of the Google Play Services (coming soon).
Take a look at this Google I/O 2012 session to learn more about how this works: https://developers.google.com/events/io/sessions/gooio2012/121/
In the meantime, one workaround you can use is passing the API key along with each request using the ?key=<API_KEY> query parameter.