原文:http://developer.android.com/training/sync-adapters/creating-authenticator.html
Sync Adapter 框架假定我們的 Sync Adapter 在同步數(shù)據(jù)時,設(shè)備存儲端關(guān)聯(lián)了一個賬戶镶摘,且服務(wù)器端需要進(jìn)行登錄驗證捎拯。因此,我們需要提供一個叫做授權(quán)器(Authenticator)的組件作為 Sync Adapter 的一部分钮莲。該組件會集成在 Android 賬戶及認(rèn)證框架中忿磅,并提供一個標(biāo)準(zhǔn)的接口來處理用戶憑據(jù)另患,比如登錄信息。
即使我們的應(yīng)用不使用賬戶芳绩,我們?nèi)匀恍枰峁┮粋€授權(quán)器組件掀亥。在這種情況下,授權(quán)器所處理的信息將被忽略妥色,所以我們可以提供一個包含了方法存根(Stub Method)的授權(quán)器組件搪花。同時我們需要提供一個綁定Service,來允許 Sync Adapter 框架調(diào)用授權(quán)器的方法嘹害。
這節(jié)課將展示如何定義一個能夠滿足 Sync Adapter 框架要求的 Stub 授權(quán)器撮竿。如果我們想要提供可以處理用戶賬戶的實際的授權(quán)器,可以閱讀:AbstractAccountAuthenticator笔呀。
添加一個 Stub 授權(quán)器組件
要在應(yīng)用中添加一個 Stub 授權(quán)器幢踏,首先我們需要創(chuàng)建一個繼承AbstractAccountAuthenticator的類室叉,在所有需要重寫的方法中摇展,我們不進(jìn)行任何處理,僅返回 null 或者拋出異常带射。
下面的代碼片段是一個 Stub 授權(quán)器的例子:
/*
* Implement AbstractAccountAuthenticator and stub out all
* of its methods
*/publicclassAuthenticatorextendsAbstractAccountAuthenticator{// Simple constructorpublicAuthenticator(Context context){super(context);? ? }// Editing properties is not supported@OverridepublicBundleeditProperties(
AccountAuthenticatorResponse r, String s){thrownewUnsupportedOperationException();? ? }// Don't add additional accounts@OverridepublicBundleaddAccount(
AccountAuthenticatorResponse r,
String s,
String s2,
String[] strings,
Bundle bundle)throwsNetworkErrorException{returnnull;? ? }// Ignore attempts to confirm credentials@OverridepublicBundleconfirmCredentials(
AccountAuthenticatorResponse r,
Account account,
Bundle bundle)throwsNetworkErrorException{returnnull;? ? }// Getting an authentication token is not supported@OverridepublicBundlegetAuthToken(
AccountAuthenticatorResponse r,
Account account,
String s,
Bundle bundle)throwsNetworkErrorException{thrownewUnsupportedOperationException();? ? }// Getting a label for the auth token is not supported@OverridepublicStringgetAuthTokenLabel(String s){thrownewUnsupportedOperationException();? ? }// Updating user credentials is not supported@OverridepublicBundleupdateCredentials(
AccountAuthenticatorResponse r,
Account account,
String s, Bundle bundle)throwsNetworkErrorException{thrownewUnsupportedOperationException();? ? }// Checking features for the account is not supported@OverridepublicBundlehasFeatures(
AccountAuthenticatorResponse r,
Account account, String[] strings)throwsNetworkErrorException{thrownewUnsupportedOperationException();? ? }}
將授權(quán)器綁定到框架
為了讓 Sync Adapter 框架可以訪問我們的授權(quán)器微渠,我們必須為它創(chuàng)建一個綁定服務(wù)搭幻。這一服務(wù)提供一個 Android Binder 對象,允許框架調(diào)用我們的授權(quán)器逞盆,并且在授權(quán)器和框架間傳遞數(shù)據(jù)檀蹋。
因為框架會在它第一次需要訪問授權(quán)器時啟動該Service,所以我們也可以使用該服務(wù)來實例化授權(quán)器纳击。具體而言续扔,我們需要在服務(wù)的Service.onCreate()方法中調(diào)用授權(quán)器的構(gòu)造函數(shù)。
下面的代碼樣例展示了如何定義綁定Service:
/**
* A bound Service that instantiates the authenticator
* when started.
*/publicclassAuthenticatorServiceextendsService{? ? ...// Instance field that stores the authenticator objectprivateAuthenticator mAuthenticator;@OverridepublicvoidonCreate(){// Create a new authenticator objectmAuthenticator =newAuthenticator(this);? ? }/*
* When the system binds to this Service to make the RPC call
* return the authenticator's IBinder.
*/@OverridepublicIBinderonBind(Intent intent){returnmAuthenticator.getIBinder();? ? }}
添加授權(quán)器的元數(shù)據(jù)(Metadata)文件
若要將我們的授權(quán)器組件集成到 Sync Adapter 框架和賬戶框架中焕数,我們需要為這些框架提供帶有描述組件信息的元數(shù)據(jù)纱昧。該元數(shù)據(jù)聲明了我們?yōu)?Sync Adapter 創(chuàng)建的賬戶類型以及系統(tǒng)所顯示的 UI 元素(如果希望用戶可以看到我們創(chuàng)建的賬戶類型)。在我們的項目目錄/res/xml/下堡赔,將元數(shù)據(jù)聲明于一個 XML 文件中识脆。我們可以自己為該文件按命名,通常我們將它命名為authenticator.xml善已。
在這個 XML 文件中灼捂,包含了一個標(biāo)簽,它有下列一些屬性:
android:accountType
Sync Adapter 框架要求每一個適配器都有一個域名形式的賬戶類型换团∠こ恚框架會將它作為 Sync Adapter 內(nèi)部標(biāo)識的一部分。如果服務(wù)端需要登陸艘包,賬戶類型會和賬戶一起發(fā)送到服務(wù)端作為登錄憑據(jù)的一部分的猛。
如果我們的服務(wù)端不需要登錄,我們?nèi)匀恍枰峁┮粋€賬戶類型(該屬性的值用我們能控制的一個域名即可)想虎。雖然框架會使用它來管理 Sync Adapter卦尊,但該屬性的值不會發(fā)送到服務(wù)端。
android:icon
指向一個包含圖標(biāo)的Drawable資源舌厨。如果我們在res/xml/syncadapter.xml中通過指定android:userVisible="true"讓 Sync Adapter 可見岂却,那么我們必須提供圖標(biāo)資源。它會在系統(tǒng)的設(shè)置中的賬戶(Accounts)這一欄內(nèi)顯示裙椭。
android:smallIcon
指向一個包含微小版本圖標(biāo)的Drawable資源躏哩。當(dāng)屏幕尺寸較小時,這一資源可能會替代android:icon中所指定的圖標(biāo)資源揉燃。
android:label
指明了用戶賬戶類型的本地化字符串震庭。如果我們在res/xml/syncadapter.xml中通過指定android:userVisible="true"讓 Sync Adapter 可見,那么我們需要提供該字符串你雌。它會在系統(tǒng)的設(shè)置中的賬戶這一欄內(nèi)顯示器联,就在我們?yōu)槭跈?quán)器定義的圖標(biāo)旁邊。
下面的代碼樣例展示了我們之前為授權(quán)器創(chuàng)建的 XML 文件:
在 Manifest 文件中聲明授權(quán)器
在之前的步驟中婿崭,我們已經(jīng)創(chuàng)建了一個綁定服務(wù)拨拓,將授權(quán)器和 Sync Adapter 框架連接了起來。為了讓系統(tǒng)可以識別該服務(wù)氓栈,我們需要在 Manifest 文件中添加標(biāo)簽渣磷,將它作為的子標(biāo)簽:
標(biāo)簽配置了一個可以被android.accounts.AccountAuthenticator這一 Action 所激活的過濾器,這一 Intent 會在系統(tǒng)要運(yùn)行授權(quán)器時由系統(tǒng)發(fā)出授瘦。當(dāng)過濾器被激活后醋界,系統(tǒng)會啟動AuthenticatorService竟宋,即之前用來封裝授權(quán)器的Service。
標(biāo)簽聲明了授權(quán)器的元數(shù)據(jù)形纺。android:name屬性將元數(shù)據(jù)和授權(quán)器框架連接起來丘侠。android:resource指定了我們之前所創(chuàng)建的授權(quán)器元數(shù)據(jù)文件的名字。
除了授權(quán)器之外逐样,Sync Adapter 框架也需要一個 Content Provider蜗字。如果我們的應(yīng)用并沒有使用 Content Provider,那么可以閱讀下一節(jié)課程學(xué)習(xí)如何創(chuàng)建一個 Stub Content Provider脂新;如果我們的應(yīng)用已經(jīng)使用了 ContentProvider挪捕,可以直接閱讀:創(chuàng)建 Sync Adapter。