authenticator.xml の accountType の文字列を strings.xml に入れてはいけない

  • 8
    Like
  • 0
    Comment
More than 1 year has passed since last update.

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.xmlandroid:accountTypeが正常に登録されていない、ということです。

実際、dumpsys コマンドでアカウントに関する情報を表示すると、期待したとおりに account type が設定されていないものが確認できます(上記例外が発生している状況の場合のみ)。

なぜこれが起こるのか、定かな情報はまだありませんが、android:accountTypeに文字列の参照を渡した場合に、その参照がうまく解決されず、リソース ID がそのまま文字列として使われてしまうことがあるようです。

http://stackoverflow.com/questions/3774282/securityexception-caller-uid-xxxx-is-different-than-the-authenticators-uid

再現性のない問題ですので、もしauthenticator.xmlを準備することがあるのであれば、文字列リソースではなく、Build Variant ごとにauthenticator.xmlを用意するのが得策です。