Android開發(fā):創(chuàng)建自定義帳戶類型
到目前為止我們已經(jīng)討論了如何訪問Google API,它使用由谷歌定義的賬戶和用戶。如果你有自己的線上服務,而它卻沒有谷歌賬戶或用戶,那么你將如何做?其實可以相對直接地在用戶設備上安裝一個新 的賬戶類型。這節(jié)課解釋如何創(chuàng)建一個和內(nèi)建賬戶一樣能工作的自定義帳戶類型。
實現(xiàn)你的自定義帳戶代碼
首先你需要一種獲取用戶憑據(jù)的方法。這有可能像一個詢問用戶名和密碼的對話框一樣簡單。或者它可能是一個更奇特的程序,比如一次性密碼或生物識別掃描。無論哪種方法,你有責任去實現(xiàn)這些需求:
- 收集用戶憑據(jù)
- 在服務器上驗證這些憑據(jù)
- 在設備商保存憑據(jù)
通常情況下,以上三個需求都可以在一個activity中處理。我們稱之為“驗證者activity”。
因為他們都需要和賬戶管理* ( AccountAuthenticatorActivity * ,通過它你可以專注去創(chuàng)建你自己的自定義身份驗證。
至于如何處理驗證者activity的前兩個需求,即憑證收集和驗證,這完全取決于你。(如果假定只有一種方法來實現(xiàn)它,那么很顯然我們就沒必要去做“自定義”賬戶類型。)第三個需求有一個典型的,而且頗為簡單的實現(xiàn)方式:
- final Account account = new Account(mUsername, your_account_type);
- mAccountManager.addAccountExplicitly(account, mPassword, null);
對安全更注意一些
理解* AccountManager *不是一種加密服務或者密鑰鏈這件事非常重要。它僅僅按照你傳遞的內(nèi)容用'''明文'''來存儲。在大部分設備上,這不是一個典型的顧慮,因為設備把他們存儲在只有根用戶才能訪問的數(shù)據(jù)庫中。但是在已經(jīng)被Root過的設備上,通過'_adb連接可以讓任何人讀取憑據(jù)信息。
因此,你不能直接傳遞用戶的真實密碼給* android.os.Bundle) AccountManager.addAccountExplicitly()* 。 相反,你應該存儲加密的安全令牌來保障限制攻擊者的使用。如果你的用戶憑證需要保護一些敏感信息,你應該謹慎考慮做出相似的事情。
** 記住:** 當涉及到安全有關代碼,請按照“流言終結(jié)者(Mythbusters)”規(guī)則:不要在家里嘗試這個!在執(zhí)行任何自定義代碼之前請一定要咨詢安全專業(yè)人士。
既然安全免責聲明是不合適的,那么現(xiàn)在是時候回去工作了。你已經(jīng)理解了自定義帳戶代碼的核心,剩下的就是去實現(xiàn)它了。
繼承AbstractAccountAuthenticator
為了讓* AccountManager 能夠和你的自定義用戶賬戶代碼一起工作,你需要一個實現(xiàn)了 AccountManager * 所需要的接口的類。這個類就是''“驗證類”(authenticator class)_。
建立一個驗證類的最簡單的方法是繼承* AbstractAccountAuthenticator 并且實現(xiàn)其中的抽象方法。如果你已經(jīng)學習了之前的課程, AbstractAccountAuthenticator * 的抽象類方法可能看起來比較熟悉:他們的功能剛好與你在前一課中調(diào)用的賬戶信息和授權令牌的方法相反。
正確地實現(xiàn)一個驗證類要求一連串單獨的代碼段。首先,* AbstractAccountAuthenticator * 有七個你必須重寫的抽象方法。其次,你需要在你的application menifes(將在下一節(jié)講到)中為'''"android.accounts.AccountAuthenticator"'''添加一個* intent filter * 。最后,你必須提供兩個XML資源,其中包括你的自定義帳戶類型的名稱和系統(tǒng)將在這個類型賬戶后面顯示的圖標。
你可以查找一個“一對一向?qū)?rdquo;來實現(xiàn)一個成功的驗證類和在* AbstractAccountAuthenticator * 文檔中的XML文件。同樣在SampleSyncAdapter示例程序中有一個簡單的實現(xiàn)方法。
如果你已讀過SampleSyncAdapter的代碼,你就會發(fā)現(xiàn)有很多個方法在一個bundle鐘返回一個intent。而這個intent和 將被用于運行你的自定義的驗證activity的是同一個intent。如果你的驗證activity需要任何特殊的初始化參數(shù),你可以使用* Intent.putExtra()) * 來將他們添加進該intent中。
創(chuàng)建一個驗證服務
既然你已經(jīng)有了一個驗證類,你需要一個地方來讓它運行。賬戶驗證在多個應用中必須是可用的,并且能夠在后臺運行,所以他們自然需要運行在一個* 服務Service * 中。我們稱之為驗證服務。
你的驗證服務一定要非常簡單。它需要做的僅僅是在* onCreate()) 方法中創(chuàng)建一個你的驗證類的實例,并且調(diào)用 getIBinder()) 和 onBind()) * 方法。* SampleSyncAdapter示例程序 *中有一個很好的驗證服務的例子。
不要忘記在你的manifest文件中添加一個* * 標簽和一個AccountAuthenticator intent的intent filter(過濾器),并且聲明這個賬戶驗證器:
- <service ...>
- <intent-filter>
- <action android:name="android.accounts.AccountAuthenticator" />
- </intent-filter>
- <meta-data android:name="android.accounts.AccountAuthenticator"
- android:resource="@xml/authenticator" /></service>
發(fā)布你的服務
你已經(jīng)完成了!系統(tǒng)現(xiàn)在可以在那些大牌賬戶類型比如"Google"和"Corporate"當中認出你的賬戶類型。你可以使用* Accounts & Sync(賬戶與同步)* 設置頁面來添加一個賬戶,而且那些需要你自定義類型的賬戶的軟件能夠像任何其他賬戶類型一樣美劇和驗證你的賬戶類型。
當然,這些全都是假設你的賬戶服務被正確的安裝在設備上的。如果只有一個程序需要訪問這個服務,那么就這就會很簡單,只需要在應用中捆綁這個服務就 可以了。但是如果你想讓你的賬戶服務被用于不止一個應用,那么事情就會變得棘手了。因為你不想把服務綁定到每一個的應用上,并且在設備上占用大量的空間來 保存多個副本。
一種解決方法把這個服務換成一個小的,有特殊目的的APK。當一個應用想要使用你的自定義帳戶類型,它可以檢查這個設備看你的自定義帳戶類型有沒有 運行。如果沒有,它能夠帶領用戶到Google Play下載這個服務。這剛開始看起來似乎是一個大麻煩,但是同讓每一個應用程序在使用自定義賬戶類型時重復輸入憑據(jù)的方案對比來看,這很顯然要簡單得多。