This guide tells you how to authorize with Google and use Google REST APIs when you want your app to access Google APIs with the user's Google account over HTTP. However, in some cases, there are other approaches that might make more sense for your app:
- REST APIs are used by your server. If you only make REST API calls from a server that you manage and use to support your app, see Enable Server-Side API Access for instructions on how to authorize on your Android client.
- Use Google APIs for Android. We provide Google APIs for Android for several Google products, and these are usually easier to use than REST APIs. We recommend that you use those APIs instead (for example, Google Fit, Games and Drive), and that you follow API-specific instructions for authentication.
Configure build dependencies
The first step is to configure build dependencies in your app's root-level
build.gradle
file. In this example, we are using the -auth
API split in
the Google Play services SDK to avoid loading the entire SDK into the app.
// Google Play services Auth split compile 'com.google.android.gms:play-services-auth:17.0.0' // Google Api Client library and Android extension compile 'com.google.api-client:google-api-client:1.22.0' compile 'com.google.api-client:google-api-client-android:1.22.0' // Change to the API you want to access: // Below is just an example for People REST API access compile 'com.google.apis:google-api-services-people:v1-rev4-1.22.0'
Use the Google-Provided authorization UI for REST API access
You no longer need to spend time building an authorization UI to implement
account selection, authorization and API access for Google APIs. Instead, you
can save yourself time by giving users of your Android app a Google-provided
authorization UI that handles all of this, by using the
GoogleSignInClient
object.
Specify scopes
To specify scopes, create a
GoogleSignInOptions
object with the new scopes that you want to request by calling
GoogleSignInOptions.Builder.requestScopes
.
To see a list of valid OAuth scope values for Google services, see
OAuth 2.0 Scopes for Google APIs.
When designing your app, you should request OAuth scope access incrementally. This means that you request access to only the scopes that your app needs in an appropriate context and at the time they are needed, so the user understands why these scopes are being requested.
For example, for a document scanning app, at initial sign-in time you should
only request basic scopes by using
GoogleSignInOption.DEFAULT_SIGN_IN
.
Then, prompt the user for Drive file access only when the user tries to save the
document to Google Drive. Finally, request access to the user's contacts only
when the user tries to send the doc to their contacts.
This aligns with the
runtime permissions model
in Android Marshmallow and newer OS versions. By following these best practices
when
Requesting Additional Scopes,
you help to foster user trust in your app, and increase the chances that they
will choose to grant your app access to requested OAuth scopes.
The following example code shows how to use
GoogleSignInOptions
to select a user account and authorize specific scopes:
Scope SCOPE_CONTACTS_READ = new Scope("https://www.googleapis.com/auth/contacts.readonly"); Scope SCOPE_EMAIL = new Scope(Scopes.EMAIL); if (!GoogleSignIn.hasPermissions( GoogleSignIn.getLastSignedInAccount(getActivity()), SCOPE_CONTACTS_READ, SCOPE_EMAIL)) { GoogleSignIn.requestPermissions( MyExampleActivity.this, RC_AUTHORIZE_CONTACTS, GoogleSignIn.getLastSignedInAccount(getActivity()), SCOPE_CONTACTS_READ, SCOPE_EMAIL); } else { getContacts(); } ... @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { if (RC_AUTHORIZE_CONTACTS == requestCode) { getContacts(); } } }
You can get an Android
Account
object as part of your Google Sign-In result, and you can later instantiate a
GoogleAccountCredential
object with it. When you use
GoogleAccountCredential
,
the REST API client library code can handle underlying OAuth token retrieval on
your behalf.
Use GoogleAccountCredential and the client library for REST API access
The following is an example of accessing the People REST API with the
GoogleAccountCredential
object.
private void getContacts() { GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(MyExampleActivity.this); if (account) { GetContactsTask task = new GetContactsTask(account.getAccount()); task.execute(); } } /** Global instance of the HTTP transport. */ private static HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport(); /** Global instance of the JSON factory. */ private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); private class GetContactsTask extends AsyncTask<Void, Void, List<Person>> { Account mAccount; public GetContactsTask(Account account) { mAccount = account; } @Override protected List<Person> doInBackground(Void... params) { List<Person> result = null; try { GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2( MyExampleActivity.this, Collections.singleton( "https://www.googleapis.com/auth/contacts.readonly") ); credential.setSelectedAccount(mAccount); People service = new People.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName("REST API sample") .build(); ListConnectionsResponse connectionsResponse = service .people() .connections() .list("people/me") .execute(); result = connectionsResponse.getConnections(); } catch (UserRecoverableAuthIOException userRecoverableException) { // Explain to the user again why you need these OAuth permissions // And prompt the resolution to the user again: startActivityForResult(userRecoverableException.getIntent(),RC_REAUTHORIZE); } catch (IOException e) { // Other non-recoverable exceptions. } return result; } @Override protected void onCancelled() { ... } @Override protected void onPostExecute(List<Person> connections) { ... } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); if (requestCode == RC_AUTHORIZE_CONTACTS || requestCode == RC_REAUTHORIZE) { if (resultCode == RESULT_OK) { getContacts(); } } }
You can find the complete REST API sample code included in the Google Sign-In Quickstart on Github: RestApiActivity.java
Exception handling
If you already went through the authorization steps using
Auth.GoogleSignInApi
and it succeeded, UserRecoverableAuthIOException
is usually not expected.
However, a user might choose to revoke OAuth permission from your application
even if they had authorized it previously. In those cases,
UserRecoverableAuthIOException
will be thrown in the code shown above. You can
explain to the user again why you need the permission, prompt them for
resolution, and retry.
To test out this revocation scenario, go to Settings -> Google -> Connected Apps and revoke access there. For Android Lollipop and earlier OS versions, go to Google Settings -> Connected Apps.