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><android-sdk>/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 < 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><android-sdk>/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>