建立自訂帳戶類型

到目前為止,我們已介紹過如何存取 Google API,這些 API 會使用 Google 定義的帳戶和使用者。如果您有自己的線上服務,但沒有 Google 帳戶或使用者,那您怎麼做?如此一來,當使用者的裝置安裝新的帳戶類型就相對簡單。本課程將說明如何建立自訂帳戶類型,運作方式與內建帳戶相同。

導入自訂帳戶程式碼

您必須先向使用者取得憑證,這可以是簡單的對話方塊,要求輸入名稱和密碼。或者是比較特殊的程序,例如動態密碼或生物特徵辨識掃描。無論哪種方式,您都必須負責實作符合以下條件的程式碼:

  1. 向使用者收集憑證
  2. 透過伺服器驗證憑證
  3. 將憑證儲存在裝置上

這三種規定通常可以由一個活動處理。這就是所謂的驗證器活動

這是因為驗證器活動需要與 AccountManager 系統互動,因此一般活動不會有某些要求。為協助您輕鬆正確設定,Android 架構提供基礎類別 AccountAuthenticatorActivity,您可以擴充該類別來建立自訂驗證器。

要如何因應驗證器活動的前兩個要求 (憑證收集和驗證),完全由您決定。(如果只能使用一種方法,那麼完全不需要「自訂」帳戶類型)。第三個規定是標準實作,而不是簡單的實作:

Kotlin

Account(username, your_account_type).also { account ->
    accountManager.addAccountExplicitly(account, password, null)
}

Java

final Account account = new Account(username, your_account_type);
accountManager.addAccountExplicitly(account, password, null);

聰明管理安全!

請務必瞭解,AccountManager 不是加密金鑰或金鑰鏈。隨您傳送帳戶憑證的方式,會以「純文字」形式儲存帳戶憑證。這在大多數裝置上並非很明顯的問題,因為這會將其儲存在僅限 Root 權限存取的資料庫中。但在已解鎖裝置上,任何擁有 adb 存取權的人都能讀取憑證。

瞭解這一點後,您不應將使用者的實際密碼傳送至 AccountManager.addAccountExplicitly()。我們建議改儲存經過加密編譯且只會用於攻擊者的安全權杖。如果您的使用者憑證是保護重要內容,請審慎考慮採取類似的做法。

注意:提供安全碼時,請遵循「迷思」規則:不要在家嘗試這種做法!導入任何自訂帳戶程式碼前,請先諮詢安全專家。

既然安全性免責事項已告一段落,請該回來查看。 您已經實作自訂帳戶程式碼的肉品,剩下的是管路程序。

擴充 AbstractAccountAuthenticator

如要讓 AccountManager 與您的自訂帳戶程式碼搭配使用,您需要一個實作 AccountManager 預期介面的類別。這個類別是「authenticator 類別」

如要建立驗證器類別,最簡單的方法就是擴充 AbstractAccountAuthenticator 並實作其抽象方法。如果您已完成先前的課程,AbstractAccountAuthenticator 的抽象方法應很熟悉:這與您在上一堂課呼叫的方法相反,可用於取得帳戶資訊和授權權杖。

正確實作驗證器類別需要多個單獨的程式碼。首先,AbstractAccountAuthenticator 有七個必須覆寫的抽象方法。第二,您需要將 "android.accounts.AccountAuthenticator"意圖篩選器新增至應用程式資訊清單 (如下一節所示)。最後,您必須提供兩個 XML 資源,其中包括自訂帳戶類型的名稱,以及系統會顯示在這類帳戶旁的圖示。

您可以在 AbstractAccountAuthenticator 說明文件中找到實作成功驗證器類別和 XML 檔案的逐步指南。

如果驗證器活動需要任何特殊初始化參數,您可以使用 Intent.putExtra() 將參數附加至意圖。

建立驗證器服務

現在您有了驗證器類別,需要可以存放驗證器類別。帳戶驗證器必須可供多個應用程式使用,並在背景中運作,因此自然需要在 Service 中執行。我們將這個方法稱為驗證器服務

驗證器服務非常簡單。您只需要在 onCreate() 中建立驗證器類別的執行個體,並在 onBind() 中呼叫 getIBinder() 即可。

別忘了將 <service> 標記新增至資訊清單檔案,並為 AccountAuthenticator 意圖新增意圖篩選器,並宣告帳戶驗證器:

<service ...>
   <intent-filter>
      <action android:name="android.accounts.AccountAuthenticator" />
   </intent-filter>
   <meta-data android:name="android.accounts.AccountAuthenticator"
             android:resource="@xml/authenticator" />
</service>

發行服務

大功告成!現在,系統會直接在所有大型帳戶類型 (例如「Google」和「公司」) 旁邊辨識您的帳戶類型。您可以透過「Account & Sync」(帳戶與同步處理) 設定頁面新增帳戶,而要求你自訂類型帳戶的應用程式將能夠列舉及驗證,就像使用其他帳戶類型一樣。

當然,上述所有事項都會假設帳戶服務已實際安裝在裝置上。如果只有一個應用程式會存取該服務,那就沒問題了,那就沒問題了,只要將服務封裝到應用程式中即可。不過,如果想讓多個應用程式使用帳戶服務,就成了一大挑戰。您不想將服務與所有應用程式組合在一起,並使服務重複佔用使用者的裝置空間。

解決方法是將服務放在一個特殊用途的小型 APK 中。當應用程式想要使用自訂帳戶類型時,可以檢查裝置是否可用您的自訂帳戶服務。如果沒有,則會引導使用者前往 Google Play 下載服務。這乍看上好像很困難,但其實比起為每個使用自訂帳戶的應用程式重新輸入憑證的替代方案,更新做法十分容易。