authenticator.xml の account type について
authenticator.xml
に、AccountManager
に登録されるアカウント認証にまつわるメタデータを記述しますよね。
このとき、android:accountType
という文字列属性の値に、以下のように書いたことはありませんか?
<authenticator
android:accountType="@string/account_type"/>
Build Variant ごとにリソースが別れてくれれば、リリース版とデバッグ版で Account Type が切り替わってくれるのでそれぞれにアカウントが分けられて便利!というノリで、このように書きたくなりますが、実は罠があります。
突然の bind failure
デバッグをしていると、アプリを何度もインストールしなおしたりすることがあります。そんな時、アカウントの作成を実行していると、唐突に見慣れない例外が飛んでくることがあります。
android.accounts.AuthenticatorException: bind failure
at android.accounts.AccountManager.convertErrorToException(AccountManager.java:1437)
at android.accounts.AccountManager.access$400(AccountManager.java:138)
at android.accounts.AccountManager$BaseFutureTask$Response.onError(AccountManager.java:1342)
at android.accounts.IAccountManagerResponse$Stub.onTransact(IAccountManagerResponse.java:69)
at android.os.Binder.execTransact(Binder.java:320)
at dalvik.system.NativeStart.run(Native Method)
しかも、再現性があるわけではなく、例外が飛ぶ時と飛ばない時があります。
例外のメッセージも、bind failure としか出ないので、なんのこっちゃい、という感じです。
authenticator のメタデータがうまく登録されていない
この例外が起きる時、システムで何が起こっているかと言うと、authenticator.xml に書いたメタデータがうまく登録できていない状態にあります。
Android の場合、Account は Account Type に紐付けられて管理されますので、先述の例外の"bind failure"とはまさに、紐付ができないことを示していることになります。
つまり、authenticator.xml
のandroid:accountType
が正常に登録されていない、ということです。
実際、dumpsys コマンドでアカウントに関する情報を表示すると、期待したとおりに account type が設定されていないものが確認できます(上記例外が発生している状況の場合のみ)。
なぜこれが起こるのか、定かな情報はまだありませんが、android:accountType
に文字列の参照を渡した場合に、その参照がうまく解決されず、リソース ID がそのまま文字列として使われてしまうことがあるようです。
再現性のない問題ですので、もしauthenticator.xml
を準備することがあるのであれば、文字列リソースではなく、Build Variant ごとにauthenticator.xml
を用意するのが得策です。