1 page.title=Creating a Stub Authenticator 2 3 trainingnavtop=true 4 @jd:body 5 6 7 <div id="tb-wrapper"> 8 <div id="tb"> 9 10 <h2>This lesson teaches you to</h2> 11 <ol> 12 <li> 13 <a href="#CreateAuthenticator">Add a Stub Authenticator Component</a> 14 </li> 15 <li> 16 <a href="#CreateAuthenticatorService">Bind the Authenticator to the Framework</a> 17 </li> 18 <li> 19 <a href="#CreateAuthenticatorFile">Add the Authenticator Metadata File</a> 20 </li> 21 <li> 22 <a href="#DeclareAuthenticator">Declare the Authenticator in the Manifest</a> 23 </li> 24 </ol> 25 26 <h2>You should also read</h2> 27 <ul> 28 <li> 29 <a href="{@docRoot}guide/components/bound-services.html">Bound Services</a> 30 </li> 31 </ul> 32 33 <h2>Try it out</h2> 34 35 <div class="download-box"> 36 <a href="http://developer.android.com/shareables/training/BasicSyncAdapter.zip" class="button">Download the sample</a> 37 <p class="filename">BasicSyncAdapter.zip</p> 38 </div> 39 40 </div> 41 </div> 42 <p> 43 The sync adapter framework assumes that your sync adapter transfers data between device storage 44 associated with an account and server storage that requires login access. For this reason, the 45 framework expects you to provide a component called an authenticator as part of your sync 46 adapter. This component plugs into the Android accounts and authentication framework and 47 provides a standard interface for handling user credentials such as login information. 48 </p> 49 <p> 50 Even if your app doesn't use accounts, you still need to provide an authenticator component. 51 If you don't use accounts or server login, the information handled by the authenticator is 52 ignored, so you can provide an authenticator component that contains stub method 53 implementations. You also need to provide a bound {@link android.app.Service} that 54 allows the sync adapter framework to call the authenticator's methods. 55 </p> 56 <p> 57 This lesson shows you how to define all the parts of a stub authenticator that you need to 58 satisfy the requirements of the sync adapter framework. If you need to provide a real 59 authenticator that handles user accounts, read the reference documentation for 60 {@link android.accounts.AbstractAccountAuthenticator}. 61 </p> 62 63 <h2 id="CreateAuthenticator">Add a Stub Authenticator Component</h2> 64 <p> 65 To add a stub authenticator component to your app, create a class that extends 66 {@link android.accounts.AbstractAccountAuthenticator}, and then stub out the required methods, 67 either by returning {@code null} or by throwing an exception. 68 </p> 69 <p> 70 The following snippet shows an example of a stub authenticator class: 71 </p> 72 <pre> 73 /* 74 * Implement AbstractAccountAuthenticator and stub out all 75 * of its methods 76 */ 77 public class Authenticator extends AbstractAccountAuthenticator { 78 // Simple constructor 79 public Authenticator(Context context) { 80 super(context); 81 } 82 // Editing properties is not supported 83 @Override 84 public Bundle editProperties( 85 AccountAuthenticatorResponse r, String s) { 86 throw new UnsupportedOperationException(); 87 } 88 // Don't add additional accounts 89 @Override 90 public Bundle addAccount( 91 AccountAuthenticatorResponse r, 92 String s, 93 String s2, 94 String[] strings, 95 Bundle bundle) throws NetworkErrorException { 96 return null; 97 } 98 // Ignore attempts to confirm credentials 99 @Override 100 public Bundle confirmCredentials( 101 AccountAuthenticatorResponse r, 102 Account account, 103 Bundle bundle) throws NetworkErrorException { 104 return null; 105 } 106 // Getting an authentication token is not supported 107 @Override 108 public Bundle getAuthToken( 109 AccountAuthenticatorResponse r, 110 Account account, 111 String s, 112 Bundle bundle) throws NetworkErrorException { 113 throw new UnsupportedOperationException(); 114 } 115 // Getting a label for the auth token is not supported 116 @Override 117 public String getAuthTokenLabel(String s) { 118 throw new UnsupportedOperationException(); 119 } 120 // Updating user credentials is not supported 121 @Override 122 public Bundle updateCredentials( 123 AccountAuthenticatorResponse r, 124 Account account, 125 String s, Bundle bundle) throws NetworkErrorException { 126 throw new UnsupportedOperationException(); 127 } 128 // Checking features for the account is not supported 129 @Override 130 public Bundle hasFeatures( 131 AccountAuthenticatorResponse r, 132 Account account, String[] strings) throws NetworkErrorException { 133 throw new UnsupportedOperationException(); 134 } 135 } 136 </pre> 137 <h2 id="CreateAuthenticatorService">Bind the Authenticator to the Framework</h2> 138 <p> 139 In order for the sync adapter framework to access your authenticator, you must create a bound 140 Service for it. This service provides an Android binder object that allows the framework 141 to call your authenticator and pass data between the authenticator and the framework. 142 </p> 143 <p> 144 Since the framework starts this {@link android.app.Service} the first time it needs to 145 access the authenticator, you can also use the service to instantiate the authenticator, 146 by calling the authenticator constructor in the 147 {@link android.app.Service#onCreate Service.onCreate()} method of the service. 148 </p> 149 <p> 150 The following snippet shows you how to define the bound {@link android.app.Service}: 151 </p> 152 <pre> 153 /** 154 * A bound Service that instantiates the authenticator 155 * when started. 156 */ 157 public class AuthenticatorService extends Service { 158 ... 159 // Instance field that stores the authenticator object 160 private Authenticator mAuthenticator; 161 @Override 162 public void onCreate() { 163 // Create a new authenticator object 164 mAuthenticator = new Authenticator(this); 165 } 166 /* 167 * When the system binds to this Service to make the RPC call 168 * return the authenticator's IBinder. 169 */ 170 @Override 171 public IBinder onBind(Intent intent) { 172 return mAuthenticator.getIBinder(); 173 } 174 } 175 </pre> 176 177 <h2 id="CreateAuthenticatorFile">Add the Authenticator Metadata File</h2> 178 <p> 179 To plug your authenticator component into the sync adapter and account frameworks, you need to 180 provide these framework with metadata that describes the component. This metadata declares the 181 account type you've created for your sync adapter and declares user interface elements 182 that the system displays if you want to make your account type visible to the user. Declare this 183 metadata in a XML file stored in the {@code /res/xml/} directory in your app project. 184 You can give any name to the file, although it's usually called {@code authenticator.xml}. 185 </p> 186 <p> 187 This XML file contains a single element <code><account-authenticator></code> that 188 has the following attributes: 189 </p> 190 <dl> 191 <dt> 192 <code>android:accountType</code> 193 </dt> 194 <dd> 195 The sync adapter framework requires each sync adapter to have an account type, in the form 196 of a domain name. The framework uses the account type as part of the sync adapter's 197 internal identification. For servers that require login, the account type along with a 198 user account is sent to the server as part of the login credentials. 199 <p> 200 If your server doesn't require login, you still have to provide an account type. For the 201 value, use a domain name that you control. While the framework uses it to manage your 202 sync adapter, the value is not sent to your server. 203 </p> 204 </dd> 205 <dt> 206 <code>android:icon</code> 207 </dt> 208 <dd> 209 Pointer to a <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable</a> 210 resource containing an icon. If you make the sync adapter visible by specifying the 211 attribute <code>android:userVisible="true"</code> in <code>res/xml/syncadapter.xml</code>, 212 then you must provide this icon resource. It appears in the <b>Accounts</b> section of 213 the system's Settings app. 214 </dd> 215 <dt> 216 <code>android:smallIcon</code> 217 </dt> 218 <dd> 219 Pointer to a <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable</a> 220 resource containing a small version of the icon. This resource may be used instead of 221 <code>android:icon</code> in the <b>Accounts</b> section of the system's Settings app, 222 depending on the screen size. 223 </dd> 224 <dt> 225 <code>android:label</code> 226 </dt> 227 <dd> 228 Localizable string that identifies the account type to users. If you make the sync adapter 229 visible by specifying the attribute <code>android:userVisible="true"</code> in 230 <code>res/xml/syncadapter.xml</code>, then you should provide this string. It appears in the 231 <b>Accounts</b> section of the system's Settings app, next to the icon you define for the 232 authenticator. 233 </dd> 234 </dl> 235 <p> 236 The following snippet shows the XML file for the authenticator you created previously: 237 </p> 238 <pre> 239 <?xml version="1.0" encoding="utf-8"?> 240 <account-authenticator 241 xmlns:android="http://schemas.android.com/apk/res/android" 242 android:accountType="example.com" 243 android:icon="@drawable/ic_launcher" 244 android:smallIcon="@drawable/ic_launcher" 245 android:label="@string/app_name"/> 246 </pre> 247 248 <h2 id="DeclareAuthenticator">Declare the Authenticator in the Manifest</h2> 249 <p> 250 In a previous step, you created a bound {@link android.app.Service} that links the authenticator 251 to the sync adapter framework. To identify this service to the system, declare it in your app 252 manifest by adding the following 253 <code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code> 254 element as a child element of 255 <code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>: 256 </p> 257 <pre> 258 <service 259 android:name="com.example.android.syncadapter.AuthenticatorService"> 260 <intent-filter> 261 <action android:name="android.accounts.AccountAuthenticator"/> 262 </intent-filter> 263 <meta-data 264 android:name="android.accounts.AccountAuthenticator" 265 android:resource="@xml/authenticator" /> 266 </service> 267 </pre> 268 <p> 269 The 270 <code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code> 271 element sets up a filter that's triggered by the intent action 272 {@code android.accounts.AccountAuthenticator}, which sent by the system to run the 273 authenticator. When the filter is triggered, the system starts {@code AuthenticatorService}, 274 the bound {@link android.app.Service} you have provided to wrap the authenticator. 275 </p> 276 <p> 277 The 278 <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data></a></code> 279 element declares the metadata for the authenticator. The 280 <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code> 281 attribute links the meta-data to the authentication framework. The 282 <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#rsrc">android:resource</a></code> 283 element specifies the name of the authenticator metadata file you created previously. 284 </p> 285 <p> 286 Besides an authenticator, a sync adapter also requires a content provider. If your app doesn't 287 use a content provider already, go to the next lesson to learn how to create a stub content 288 provider; otherwise, go to the lesson <a href="creating-sync-adapter.html" 289 >Creating a Sync Adapter</a>. 290 </p> 291