DOC

Writing an Android Sync Provider

By Rick Greene,2014-04-05 19:44
8 views 0
Writing an Android Sync Provider

    http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/ http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-2/

    One of the highlights of the Android 2.0 SDK is that you can write custom sync providers to integrate with the system contacts, calendars, etc. The only problem is that there’s very little documentation on how it all fits together. And worse, if you mess up in certain places, the Android system will crash and reboot! Always up for a challenge, I’ve navigated through the sparse documentation, vague mailing list

    posts, and the Android source code itself to build a sync provider for our Last.fm app. Want to know how to build your own? Read on!

    Account Authenticators

    The first piece of the puzzle is called an Account Authenticator , which defines how the user’s account will appear in the “Accounts &; Sync” settings. Implementing an Account Authenticator requires 3 pieces: a service that returns a subclass of AbstractAccountAuthenticator from the onBind method, an activity to prompt the user to enter their credentials, and an xml file describing how your account should look when displayed to the user. You’ll also need to add the

    android.permission.AUTHENTICATE_ACCOUNTS permission to your AndroidManifest.xml. The Service

    The authenticator service is expected to return a subclass of

    AbstractAccountAuthenticator from the onBind method if you don’t, Android will

    crash and reboot when you try to add a new account to the system. The only method in AbstractAccountAuthenticator we really need to implement is addAccount, which returns an Intent that the system will use to display the login dialog to the user. The implementation below will launch our app’s main launcher activity with an action

    of “fm.last.android.sync.LOGIN” and an extra containing the

    AccountAuthenticatorResponse object we use to pass data back to the system after the user has logged in.

     AccountAuthenticatorService.java

     import fm.last.android.LastFm;

     import android.accounts.AbstractAccountAuthenticator;

     import android.accounts.Account;

     import android.accounts.AccountAuthenticatorResponse;

     import android.accounts.AccountManager;

     import android.accounts.NetworkErrorException;

     import android.app.Service;

     import android.content.Context;

     import android.content.Intent;

     import android.os.Bundle;

     import android.os.IBinder;

     import android.util.Log;

     /**

     * Authenticator service that returns a subclass of AbstractAccountAuthenticator

    in onBind()

     */

     public

     class AccountAuthenticatorService

     extends Service

     {

     private

     static

     final

     String TAG =

     ";AccountAuthenticatorService";

     ;

     private

     static AccountAuthenticatorImpl sAccountAuthenticator =

     null

     ;

     public AccountAuthenticatorService

     (

     )

     {

     super

     (

     )

     ;

     }

     public IBinder onBind

     ( Intent intent

     )

     {

     IBinder ret =

     null

     ;

     if

     ( intent.

     getAction

     (

     ) .

     equals

     ( android.

     accounts .

     AccountManager .

     ACTION_AUTHENTICATOR_INTENT

     )

     )

     ret = getAuthenticator

     (

     ) .

     getIBinder

     (

     )

     ;

     return ret

     ;

     }

     private AccountAuthenticatorImpl getAuthenticator

     (

     )

     {

     if

     ( sAccountAuthenticator ==

     null

     )

     sAccountAuthenticator =

     new AccountAuthenticatorImpl

     (

     this

     )

     ;

     return sAccountAuthenticator

     ;

     }

     private

     static

     class AccountAuthenticatorImpl

     extends AbstractAccountAuthenticator

     {

     private

     Context mContext

     ;

     public AccountAuthenticatorImpl

     (

     Context context

     )

     {

     super

     ( context

     )

     ;

     mContext = context

     ;

     }

     /*

     * The user has requested to add a new account to the system. We return an

    intent that will launch our login screen if the user has not logged in yet,

     * otherwise our activity will just pass the user's credentials on to the

    account manager.

     */

     @Override

     public Bundle addAccount

     ( AccountAuthenticatorResponse response,

     String accountType,

     String authTokenType,

     String

     [

     ] requiredFeatures, Bundle options

     )

     throws NetworkErrorException

     {

     Bundle reply =

     new Bundle

     (

     )

     ;

     Intent i =

     new Intent

     ( mContext, LastFm.

     class

     )

     ;

     i.

     setAction

     (

     ";fm.last.android.sync.LOGIN";

     )

     ;

     i.

     putExtra

     ( AccountManager.

     KEY_ACCOUNT_AUTHENTICATOR_RESPONSE , response

     )

     ;

     reply.

     putParcelable

     ( AccountManager.

     KEY_INTENT , i

     )

     ;

     return reply

     ;

     }

     @Override

     public Bundle confirmCredentials

     ( AccountAuthenticatorResponse response, Account account, Bundle options

     )

     {

     return

     null

     ;

     }

     @Override

Report this document

For any questions or suggestions please email
cust-service@docsford.com