• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Authorization
2page.tags="AccountManager","oauth2"
3@jd:body
4
5<div id="qv-wrapper">
6  <div id="qv">
7    <h2>In this document</h2>
8    <ol>
9    <li><a href="#choose">Choosing an Account</a></li>
10    <li><a href="#obtain">Obtaining an Access Token</a></li>
11    <li><a href="#handle">Handling Exceptions</a></li>
12    <li><a href="#use">Using the Access Token</a></li>
13    </ol>
14  </div>
15</div>
16
17<p>
18    Google Play services offers a standard authorization flow for all Google APIs and
19    all components of Google Play services. In addition, you can leverage the authorization
20    portion of the Google Play services SDK to gain authorization to services that are not yet supported
21    in the Google Play services platform by using the access token to manually make API
22    requests or using a client library provided by the service provider.
23</p>
24
25<p>For implementation details, see the sample in <code>&lt;android-sdk&gt;/extras/google-play-services/samples/auth</code>,
26which shows you how to carry out these basic steps for obtaining an access token.</p>
27
28<h2 id="choose">Choosing an Account</h2>
29<p>
30    Google Play services leverage existing accounts on an Android-powered device
31    to gain authorization to the services that you want to use. To obtain an access token,
32    a valid Google account is required and it must exist on the device. You can ask your users which
33    account they want to use by enumerating the Google accounts on the device or using the
34    built-in
35<a href="{@docRoot}reference/com/google/android/gms/common/AccountPicker.html">{@code
36AccountPicker}</a>
37    class to display a standard account picker view. You'll need the
38    {@link android.Manifest.permission#GET_ACCOUNTS}
39    permission set in your manifest file for both methods.
40</p>
41<p>
42    For example, here's how to gather all of the Google accounts on a device and return them
43    in an array. When obtaining an access token, only the email address of the account is
44    needed, so that is what the array stores:
45</p>
46
47<pre>
48private String[] getAccountNames() {
49    mAccountManager = AccountManager.get(this);
50    Account[] accounts = mAccountManager.getAccountsByType(
51            GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
52    String[] names = new String[accounts.length];
53    for (int i = 0; i &lt; names.length; i++) {
54        names[i] = accounts[i].name;
55    }
56    return names;
57}
58</pre>
59<h2 id="obtain">Obtaining an Access Token</h2>
60<p>
61  With an email address and the service scope you can now obtain an access token.
62</p>
63<p class="note"><strong>Note:</strong> Specify <code>"oauth2:<em>scope</em>"</code> for a single scope or
64  <code>"oauth2:<em>scope1</em> <em>scope2</em> <em>scope3</em>"</code> for multiple scopes.</p>
65
66There are two general
67  ways to get a token:</p>
68
69    <ul>
70      <li>Call one of the two overloaded <a
71      href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context, java.lang.String, java.lang.String)"
72      >{@code GoogleAuthUtil.getToken()}</a> methods in a foreground activity where you can
73        display a dialog to the user to interactively handle authorization errors.</li>
74      <li>Call one of the three <a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle)"
75      >{@code getTokenWithNotification()}</a>
76        methods if you are trying to gain authorization in a background service or sync adapter so that a
77        notification is displayed if an error occurs.</a></li>
78    </ul>
79
80    <h3>Using getToken()</h3>
81    The following code snippet obtains an access token with an email address, the scope that you want to use for the service, and a {@link android.content.Context}:
82
83<pre>
84HelloActivity mActivity;
85String mEmail;
86String mScope;
87String token;
88
89...
90try {
91    token = GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
92} catch {
93    ...
94}
95</pre>
96
97<p>Call this method off of the main UI thread since it executes network transactions. An easy way to do this
98  is in an {@link android.os.AsyncTask}.
99  The sample in the Google Play services SDK shows you how to wrap this call in an AsyncTask.
100  If authorization is successful, the token is returned. If not, the exceptions described in
101<a href="#handle">Handling Exceptions</a>
102  are thrown that you can catch and handle appropriately.
103</p>
104
105  <h3>Using getTokenWithNotification()</h3>
106  <p>If you are obtaining access tokens in a background service or sync adapter, there
107  are three overloaded
108  <a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle)"
109      >{@code getTokenWithNotification()}</a> methods
110  that you can use:</p>
111  <ul>
112    <li><a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle)"
113    >{@code getTokenWithNotification(Context context, String accountName, String scope, Bundle extras)}</a>:
114    For background services. Displays a notification to the user when authorization errors occur.</li>
115    <li><a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle, android.content.Intent)"
116    >{@code getTokenWithNotification(Context context, String accountName, String scope, Bundle extras, Intent callback)}</a>:
117    This method is for use in background services. It displays a notification to the user
118    when authorization errors occur. If a user clicks the notification and then authorizes the
119    app to access the account, the intent is broadcasted. When using this method:
120    <ul>
121     <li>Create a {@link android.content.BroadcastReceiver} that registers the intent and handles
122it appropriately</li>
123     <li>In the app's manifest file, set the <a
124     href="{@docRoot}guide/topics/manifest/receiver-element.html#exported"><code>android:exported</code></a>
125     attribute to <code>true</code> for the broadcast receiver</li>
126     <li>Ensure that the intent is serializable using the {@link
127android.content.Intent#toUri toUri(Intent.URI_INTENT_SCHEME)} and
128    {@link android.content.Intent#parseUri parseUri(intentUri, Intent.URI_INTENT_SCHEME)} methods.</li>
129   </ul>
130    <li><a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle, java.lang.String, android.os.Bundle)"
131    >{@code getTokenWithNotification(Context context, String accountName, String scope, Bundle extras, String authority, Bundle syncBundle)}</a>:
132This method is for use in sync adapters. It displays a notification to the user when
133errors occur. If a user clicks the notification and then authorizes the
134app to access the account, the sync adapter retries syncing with the information
135    contained in the <code>syncBundle</code> parameter.</li>
136  </ul>
137
138   <p>See the sample in <code>&lt;android-sdk&gt;/extras/google-play-services/samples/auth</code> for implementation details.</p>
139
140
141
142
143<h2 id="handle">Handling Exceptions</h2>
144<p>
145    When requesting an access token with
146    <a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context, java.lang.String, java.lang.String)"
147    >{@code GoogleAuthUtil.getToken()}</a>,
148    the following exceptions can be thrown:
149</p>
150<ul>
151    <li>
152<a href="{@docRoot}reference/com/google/android/gms/auth/UserRecoverableAuthException.html"
153>{@code UserRecoverableAuthException}</a>:
154        This exception is thrown when an error occurs that users can resolve, such as not yet granting access to their accounts or if they changed their password.
155        This exception class contains a {@link android.app.Activity#getIntent getIntent()}
156        method that you can call to obtain an intent that you can use with
157{@link android.app.Activity#startActivityForResult startActivityForResult()}
158        to obtain the user's resolution. You will need to handle the
159{@link android.app.Activity#onActivityResult onActivityResult()}
160        callback when this activity returns to take action based on the user's actions.
161  </li>
162  <li>
163<a href="{@docRoot}reference/com/google/android/gms/auth/GooglePlayServicesAvailabilityException.html"
164>{@code GooglePlayServicesAvailabilityException}</a>:
165        This exception is a special case of <a href="{@docRoot}reference/com/google/android/gms/auth/UserRecoverableAuthException.html"
166        >{@code UserRecoverableAuthException}</a>
167        and occurs when the actual Google Play services APK is not installed or unavailable.
168        This exception provides additional client support to
169        handle and fix this issue by providing an error code that describes the exact cause of the problem.
170        This exception also contains an intent that you can obtain and use to start
171        an activity to resolve the issue.
172    </li>
173    <li>
174<a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthException.html">{@code
175GoogleAuthException}</a>:
176        This exception is thrown when the authorization fails, such as when an invalid scope is
177        specified or if the email address used for authorization is actually not on the user's
178        device.
179    </li>
180    <li>
181<a href="{@docRoot}reference/com/google/android/gms/auth/UserRecoverableNotifiedException.html"
182>{@code UserRecoverableNotifiedException}</a>:
183        This exception is thrown when the authorization fails using one of the
184<a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getTokenWithNotification(android.content.Context, java.lang.String, java.lang.String, android.os.Bundle)"
185      >{@code getTokenWithNotification()}</a> methods and if the error
186        is recoverable with a user action.
187    </li>
188</ul>
189<p>
190    For more information on how to handle these exceptions and code snippets, see the reference
191    documentation for the
192<a href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html">{@code
193GoogleAuthUtil}</a> class.
194</p>
195
196
197
198
199<h2 id="use">Using the Access Token</h2>
200<p>
201    Once you have successfully obtained a token, you can use it to access Google services.
202    Many Google services provide client libraries, so it is recommended that you use these when
203    possible, but you can make raw HTTP requests as well with the token. The following example
204    shows you how to do this and handle HTTP error and success responses accordingly:
205</p>
206
207<pre>
208URL url = new URL("https://www.googleapis.com/oauth2/v1/userinfo?access_token="
209        + token);
210HttpURLConnection con = (HttpURLConnection) url.openConnection();
211int serverCode = con.getResponseCode();
212//successful query
213if (serverCode == 200) {
214    InputStream is = con.getInputStream();
215    String name = getFirstName(readResponse(is));
216    mActivity.show("Hello " + name + "!");
217    is.close();
218    return;
219//bad token, invalidate and get a new one
220} else if (serverCode == 401) {
221    GoogleAuthUtil.invalidateToken(mActivity, token);
222    onError("Server auth error, please try again.", null);
223    Log.e(TAG, "Server auth error: " + readResponse(con.getErrorStream()));
224    return;
225//unknown error, do something else
226} else {
227    Log.e("Server returned the following error code: " + serverCode, null);
228    return;
229}
230</pre>
231
232<p>
233    Notice that you must manually invalidate the token if the response from the server
234    signifies an authorization error (401). This could mean the access token
235    being used is invalid for the service's scope or the token may have expired. If this is the
236    case, obtain a new token using <a
237href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context, java.lang.String, java.lang.String)"
238>{@code GoogleAuthUtil.getToken()}</a>.
239</p>