Using Google Play services with Google Tasks API - android

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();
...

Related

Any way to call Google Play store API in .net app to get additional subscripiton and transaction details

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.

Using Google Drive API with One-Tap Sign-In on Android

I implemented Google's One-Tap Sign-Up/In in my Android application through which I obtain credential of type SignInCredential by using oneTapClient.getSignInCredentialFromIntent(result.data). I can further obtain the idToken from this SignInCredential object.
Further, I want to access user's Google Drive using the Drive API (I have enabled the API and selected the required scopes from the API Console) which I assume requires me to implement OAuth2 flow somewhat like this:
val cred = GoogleAccountCredential.usingOAuth2(this,Collections.singleton(Scopes.DRIVE_FILE))
cred.selectedAccount
val googleDriveService = com.google.api.services.drive.Drive.Builder(AndroidHttp.newCompatibleTransport(), GsonFactory(), cred )
.setApplicationName(getString(R.string.app_name))
.build()
My question is what do I do with the idToken obtained from the One-Tap flow? Am I supposed to pass it to the OAuth2 call in some way? I referred this oauth2 documentation and these docs of Google API Clients for Java but both of them don't answer the aforementioned question. And how do I further "recieve" the oauth token, if any?
Thanking you in advance.
One-Tab is a service oriented towards account creation and login. As described by the overview docs:
With just one tap, they (users) get a secure, token-based, passwordless account with your service, protected by their Google Accoun
On the other hand, if you want to interact with the APIs as an user, then you would need to use an OAuth 2.0. approach in order to handle the authentication flow. This service is independent of One-Tap, so you need different tokens per each. If you need to work with the Drive API, you can follow this quickstart to develop a working OAuth 2.0 token flow.

Android Google Drive Rest API: skip consent screen (hardcoded account)

I was trying to use Google Drive to sync some media files (video/images) and show them in my android app.
I've managed to make it all work fine but according to the docs (or at least from a first read) it looks like there must always be a consent screen where the user, after choosing his google account, agrees with the app getting data from his drive.
The point is that I'd like to 'hardcode' an account that programatically agrees to that since our app is always going to take the media from the same account.
Is that possible??
PD: Don't suggest any other storage service, Drive is a client's requirement.
To avoid the user consent, you can use a Service Account.
It's stated in the link that, Google APIs such as the Prediction API and Google Cloud Storage can act on behalf of your application without accessing user information. In these situations your application needs to prove its own identity to the API, but no user consent is necessary. Similarly, in enterprise scenarios, your application can request delegated access to some resources.
For these types of server-to-server interactions you need a service account, which is an account that belongs to your application instead of to an individual end-user. Your application calls Google APIs on behalf of the service account, and user consent is not required. (In non-service-account scenarios, your application calls Google APIs on behalf of end-users, and user consent is sometimes required.)
You can also check this related SO questions for more infor mation.
How to use Google Drive SDK in Android project with hardcoded credentials
Why does Google OAuth2 re-ask user for permission when i send them to auth url again
Finally I've managed to make it work altogether:
Create a service account credential from your google developers console.
Download your credential in json format.
Copy the file into assets/res/raw.
Rename your json into something without weirds chars (Ex: driveserviceprivatekey.json).
List item
InputStream privateJsonStream = dashboardActivity.getResources().openRawResource(R.raw.driveserviceprivatekey);
GoogleCredential serviceCredential = GoogleCredential.fromStream(privateJsonStream).createScoped(Arrays.asList(SCOPES));
Now you can use your drive service as follows:
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
this.mService = new com.google.api.services.drive.Drive.Builder(
transport, jsonFactory, null)
.setHttpRequestInitializer(credential)
.build();

Authorizing my application to use an Existing Folder

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

Access to Google API - GoogleAccountCredential.usingOAuth2 vs GoogleAuthUtil.getToken()

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.

Categories

Resources