使用sync adapte(二)创建一个Authenticator

Sync adapter框架假设我们sync adapter传输数据在关联一个账户的设备内存和需要登录权限的服务器内存直接。由于这个原因,框架期望我们提供一个组件叫做认真器作为我们sync adapter的一部分。这个组件插入安卓账户和权限框架并且提供一个标准的接口处理用户认证比如登录信息。
即使我们的应用不实现账目,仍然需要提供一个认证器组件。如果不使用账户或者服务器登录,认证器处理的信息被忽略,所以我们可以提供一个认证器组件包含存根(stub)方法实现。我们也需要提供一个bound service允许sync adapter框架调用这个认证器方法(认证器组件需要一个存根方法和一个service?)。
这课展示如何定义一个我们用来满足sync adapter框架需求的存根认证器的所有部分。如果我们需要提供一个真正的认证器处理用户账户,阅读AstractAccoutAutherticator参考文档。
AbstractAccountAuthenticator
创建一个AccountAuthenticators的抽象基类。为了成为一个AccountAuthenticator,必须实现这个类,提供抽象方法的实现并且写一个service在服务的onBind(Intent)方法中返回getBinder的结果(??怎么做,看下面吧)当被一个有ACTION_AUTHENTICATOR_INTENT动作的intent激活的时候。这个服务必须指定下面的intent filter和metadata标签在AndroidManifest.xml文件中
 
使用我们自己的资源替换icons和label。android:accountType属性必须一个唯一string标识我们的authenticator,同时也是用户在AccountManager调用的时候的同一个string,并且它也相当于我们账户的类型。One user of the android:icon is the "Account & Sync" settings page and one user of the android:smallIcon is the Contact Application's tab panels.
Preference属性指向一个PreferenceScreen xml层级包含一系列PreferenceScreens可以被激活用来管理认证器,一个例子是:
 
实现任何抽象方法的标准模式是下面:
如果提供的参数足够认证器完全满足请求,然后他会这么做并且返回一个包含结果的Bundle
如果认证器需要从用户获得信息满足请求,然后他会创建一个intent给一个活动,活动会提示用户要信息并且然后执行请求。这个intent必须在Bundel中作为key KEY_INTENT返回。
活动需要在他完成时返回最终的结果,所以intent必须包含AccountAuthenticatorResponse作为KEY_ACCOUNT_MANAGER_RESPONSE。活动必须在他完成调用onResult(Bundle)或者onError(int, String).。
如果认证器不能同时执行请求并且返回一个结果,然后他可能会选择返回null,然后使用AccountManagerResponse发送这个结果当他完成这个请求
下面每一个authenticator抽象方法的描述不会描述可能的异步
The following descriptions of each of the abstract authenticator methods will not describe the possible asynchronous nature of the request handling and will instead just describe the input parameters and the expected result.
When writing an activity to satisfy these requests one must pass in the AccountManagerResponse and return the result via that response when the activity finishes (or whenever else the activity author deems it is the correct time to respond). The AccountAuthenticatorActivity handles this, so one may wish to extend that when writing activities to handle these requests.


Add a Stub Authenticator Component
________________________________________
要添加一个存根认证器组件到应用中,创建一个类继承AbstractAccountAuthenticator,然后实现要求的方法,要么返回null要么抛出异常。
/*
 * Implement AbstractAccountAuthenticator and stub out all
 * of its methods
 */
public class Authenticator extends AbstractAccountAuthenticator {
    // Simple constructor
    public Authenticator(Context context) {
        super(context);
    }
    // Editing properties is not supported
    @Override
    public Bundle editProperties(
            AccountAuthenticatorResponse r, String s) {
        throw new UnsupportedOperationException();
    }
    // Don't add additional accounts
    @Override
    public Bundle addAccount(
            AccountAuthenticatorResponse r,
            String s,
            String s2,
            String[] strings,
            Bundle bundle) throws NetworkErrorException {
        return null;
    }
    // Ignore attempts to confirm credentials
    @Override
    public Bundle confirmCredentials(
            AccountAuthenticatorResponse r,
            Account account,
            Bundle bundle) throws NetworkErrorException {
        return null;
    }
    // Getting an authentication token is not supported
    @Override
    public Bundle getAuthToken(
            AccountAuthenticatorResponse r,
            Account account,
            String s,
            Bundle bundle) throws NetworkErrorException {
        throw new UnsupportedOperationException();
    }
    // Getting a label for the auth token is not supported
    @Override
    public String getAuthTokenLabel(String s) {
        throw new UnsupportedOperationException();
    }
    // Updating user credentials is not supported
    @Override
    public Bundle updateCredentials(
            AccountAuthenticatorResponse r,
            Account account,
            String s, Bundle bundle) throws NetworkErrorException {
        throw new UnsupportedOperationException();
    }
    // Checking features for the account is not supported
    @Override
    public Bundle hasFeatures(
        AccountAuthenticatorResponse r,
        Account account, String[] strings) throws NetworkErrorException {
        throw new UnsupportedOperationException();
    }
}


Bind the Authenticator to the Framework
为了让sync adapter框架访问我们的认证器,必须为他创建一个bound service。这个service提供一个安卓binder对象允许框架调用我们的认证器并且在认证器和框架之间传递数据。
因为框架第一次启动这个服务需要访问认证器,我们也可以使用服务去实例化认证器,通过调用认证器构造器在Service.onCreate()方法中。
下面的片段展示如何定义bound service:
/**
 * A bound Service that instantiates the authenticator
 * when started.
 */
public class AuthenticatorService extends Service {
    ...
    // Instance field that stores the authenticator object
    private Authenticator mAuthenticator;
    @Override
    public void onCreate() {
        // Create a new authenticator object
        mAuthenticator = new Authenticator(this);
    }
    /*
     * When the system binds to this Service to make the RPC call
     * return the authenticator's IBinder.
     */
    @Override
    public IBinder onBind(Intent intent) {
        return mAuthenticator.getIBinder();
    }
}
Add the Authenticator Metadata File
为了把我们的认证器组件插入sync adapter和用户框架,我们需要使用描述组件的metadata提供这些框架。Metadata声明了我们为sync adapter创建的账户类型并且声明了用户界面元素,系统会展示如果我们想让我们的账户类型对用户可见。声明这个metadata在XML文件保存在/res/xml/目录。可以给定任何名,虽然通常叫做authenticator.xml.
这个xml文件包含一个单元素<account_authenticator>有下面的属性:
android:accountType 
The sync adapter framework requires each sync adapter to have an account type, in the form of a domain name. The framework uses the account type as part of the sync adapter's internal identification. For servers that require login, the account type along with a user account is sent to the server as part of the login credentials. 
If your server doesn't require login, you still have to provide an account type. For the value, use a domain name that you control. While the framework uses it to manage your sync adapter, the value is not sent to your server. 
android:icon 
Pointer to a Drawable resource containing an icon. If you make the sync adapter visible by specifying the attribute android:userVisible="true" in res/xml/syncadapter.xml, then you must provide this icon resource. It appears in the Accounts section of the system's Settings app. 
android:smallIcon 
Pointer to a Drawable resource containing a small version of the icon. This resource may be used instead of android:icon in the Accounts section of the system's Settings app, depending on the screen size. 
android:label 
Localizable string that identifies the account type to users. If you make the sync adapter visible by specifying the attribute android:userVisible="true" in res/xml/syncadapter.xml, then you should provide this string. It appears in the Accounts section of the system's Settings app, next to the icon you define for the authenticator. 
The following snippet shows the XML file for the authenticator you created previously: 
 
Declare the Authenticator in the Manifest
在之前步骤中,我们创建了一个bonnd service连接认证器到sync adapter框架。为了让系统识别这个服务,在Manifest文件中添加一个service元素:
 
这个<intent-filter>元素设置了一个filter由android.accounts.AccountAuthenticator触发,由系统发送用来运行这个authenticator。当filter被触发,系统开启AuthenticatorService,我们提供的用来wrap Authenticator的bound service。
<meta-data>元素为Authenticator声明metadata。Android:name属性连接meta-data到Authentication框架。Android:resource元素指定我们之前创建的Authenticator metadata文件。
除了一个Authenticator,sync adapter也需要一个内容提供器,如果我们的应用不使用存在的内容提供器,参看如何创建一个stub 内容提供器http://blog.csdn.net/qingziguanjun1/article/details/51314443,否则参看创建一个Sync Adapter。

你可能感兴趣的:(使用sync adapte(二)创建一个Authenticator)