同步适配器框架假定您的同步适配器在设备存储空间之间传输数据 与需要登录访问权限的账号和服务器存储空间相关联。因此, 框架要求您在同步过程中提供一个名为身份验证器的组件 适配器。该组件可插入到 Android 账号和身份验证框架中, 提供了一个标准界面,用于处理登录信息等用户凭据。
即使您的应用不使用账号,您仍然需要提供身份验证器组件。
如果您不使用账号或服务器登录信息,则由身份验证器处理的信息为
因此您可以提供包含桩方法的身份验证器组件
实现。您还需要提供一个绑定 Service
,
允许同步适配器框架调用身份验证器的方法。
本节课介绍如何定义桩身份验证器的各部分
满足同步适配器框架的要求。如果您需要提供一个真实的
身份验证程序,请阅读有关
AbstractAccountAuthenticator
。
添加桩身份验证器组件
如需向应用添加桩身份验证器组件,请创建一个可以扩展
AbstractAccountAuthenticator
,然后为所需的方法打桩,
方法是返回 null
或抛出异常。
以下代码段展示了桩身份验证器类的一个示例:
Kotlin
/* * Implement AbstractAccountAuthenticator and stub out all * of its methods */ class Authenticator(context: Context) // Simple constructor : AbstractAccountAuthenticator(context) { // Editing properties is not supported override fun editProperties(r: AccountAuthenticatorResponse, s: String): Bundle { throw UnsupportedOperationException() } // Don't add additional accounts @Throws(NetworkErrorException::class) override fun addAccount( r: AccountAuthenticatorResponse, s: String, s2: String, strings: Array<String>, bundle: Bundle ): Bundle? = null // Ignore attempts to confirm credentials @Throws(NetworkErrorException::class) override fun confirmCredentials( r: AccountAuthenticatorResponse, account: Account, bundle: Bundle ): Bundle? = null // Getting an authentication token is not supported @Throws(NetworkErrorException::class) override fun getAuthToken( r: AccountAuthenticatorResponse, account: Account, s: String, bundle: Bundle ): Bundle { throw UnsupportedOperationException() } // Getting a label for the auth token is not supported override fun getAuthTokenLabel(s: String): String { throw UnsupportedOperationException() } // Updating user credentials is not supported @Throws(NetworkErrorException::class) override fun updateCredentials( r: AccountAuthenticatorResponse, account: Account, s: String, bundle: Bundle ): Bundle { throw UnsupportedOperationException() } // Checking features for the account is not supported @Throws(NetworkErrorException::class) override fun hasFeatures( r: AccountAuthenticatorResponse, account: Account, strings: Array<String> ): Bundle { throw UnsupportedOperationException() } }
Java
/* * 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(); } }
将身份验证器绑定到框架
为了让同步适配器框架能够访问身份验证器,您必须创建一个绑定 服务此服务提供了一个 Android binder 对象,允许框架 来调用身份验证器并在身份验证器和框架之间传递数据。
以下代码段展示了如何定义绑定 Service
:
Kotlin
/** * A bound Service that instantiates the authenticator * when started. */ class AuthenticatorService : Service() { // Instance field that stores the authenticator object private lateinit var mAuthenticator: Authenticator override fun onCreate() { // Create a new authenticator object mAuthenticator = Authenticator(getApplicationContext()) } /* * When the system binds to this Service to make the RPC call * return the authenticator's IBinder. */ override fun onBind(intent: Intent?): IBinder = mAuthenticator.iBinder }
Java
/** * 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(getApplicationContext()); } /* * 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(); } }
添加身份验证器元数据文件
要将身份验证器组件插入到同步适配器框架和账号框架中,您需要:
为这些框架提供描述组件的元数据。此元数据声明了
您为同步适配器创建的账号类型,并声明了界面元素
。声明
XML 文件中的元数据,该文件存储在应用项目的 /res/xml/
目录中。
您可以为该文件指定任何名称,但通常将它命名为 authenticator.xml
。
此 XML 文件包含一个 <account-authenticator>
元素,
具有以下属性:
-
android:accountType
-
同步适配器框架要求每个同步适配器都具有账号类型,形式为
域名。该框架将账号类型用作同步适配器的一部分。
内部标识。对于要求登录的服务器,账号类型以及
系统会将用户账号作为登录凭据的一部分发送到服务器。
即使服务器不要求提供登录信息,您仍然需要提供账号类型。对于 值,请使用由您控制的域名。虽然框架使用它来管理 同步适配器,则该值不会发送到您的服务器。
-
android:icon
-
指向可绘制对象的指针
包含图标的资源。如果您通过指定
res/xml/syncadapter.xml
中的android:userVisible="true"
属性, 那么您必须提供此图标资源。该 ID 会显示在 系统应用的“设置”应用。 -
android:smallIcon
-
指向可绘制对象的指针
资源,其中包含小版图标。该资源可用于代替
android:icon
(位于系统“设置”应用的账号部分), 具体取决于屏幕大小 -
android:label
-
用于向用户标识账号类型的可本地化字符串。如果您将同步适配器
指定属性
android:userVisible="true"
res/xml/syncadapter.xml
,则应提供此字符串。它出现在 系统“设置”应用的账号部分(位于您为 身份验证器。
以下代码段显示了您之前创建的身份验证器的 XML 文件:
<?xml version="1.0" encoding="utf-8"?> <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" android:accountType="example.com" android:icon="@drawable/ic_launcher" android:smallIcon="@drawable/ic_launcher" android:label="@string/app_name"/>
在清单中声明身份验证器
在上一步中,您创建了一个关联身份验证器的绑定 Service
同步适配器框架如需向系统识别此服务,请在您的应用中声明它
添加以下代码
<service>
元素作为
<application>
:
<service android:name="com.example.android.syncadapter.AuthenticatorService"> <intent-filter> <action android:name="android.accounts.AccountAuthenticator"/> </intent-filter> <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" /> </service>
通过
<intent-filter>
元素设置由 intent 操作触发的过滤器
android.accounts.AccountAuthenticator
,由系统发送,用于运行
身份验证器。当过滤器被触发时,系统会启动 AuthenticatorService
,
您提供的用于封装身份验证器的绑定 Service
。
通过
<meta-data>
元素声明身份验证器的元数据。通过
android:name
属性将元数据链接到身份验证框架。通过
android:resource
元素指定您之前创建的身份验证器元数据文件的名称。
除身份验证器之外,同步适配器还需要内容提供器。如果您的应用 已在使用 content provider,请继续学习下一课,了解如何创建桩内容 提供商;否则,请转到创建同步适配器一课。