Home | History | Annotate | Download | only in sync-adapters
      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     &#64;Override
     84     public Bundle editProperties(
     85             AccountAuthenticatorResponse r, String s) {
     86         throw new UnsupportedOperationException();
     87     }
     88     // Don't add additional accounts
     89     &#64;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     &#64;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     &#64;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     &#64;Override
    117     public String getAuthTokenLabel(String s) {
    118         throw new UnsupportedOperationException();
    119     }
    120     // Updating user credentials is not supported
    121     &#64;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     &#64;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     &#64;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     &#64;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>&lt;account-authenticator&gt;</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 &lt;?xml version="1.0" encoding="utf-8"?&gt;
    240 &lt;account-authenticator
    241         xmlns:android="http://schemas.android.com/apk/res/android"
    242         android:accountType="example.com"
    243         android:icon="&#64;drawable/ic_launcher"
    244         android:smallIcon="&#64;drawable/ic_launcher"
    245         android:label="&#64;string/app_name"/&gt;
    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">&lt;service&gt;</a></code>
    254     element as a child element of
    255 <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>:
    256 </p>
    257 <pre>
    258     &lt;service
    259             android:name="com.example.android.syncadapter.AuthenticatorService"&gt;
    260         &lt;intent-filter&gt;
    261             &lt;action android:name="android.accounts.AccountAuthenticator"/&gt;
    262         &lt;/intent-filter&gt;
    263         &lt;meta-data
    264             android:name="android.accounts.AccountAuthenticator"
    265             android:resource="@xml/authenticator" /&gt;
    266     &lt;/service&gt;
    267 </pre>
    268 <p>
    269     The
    270 <code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</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">&lt;meta-data&gt;</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