インストーレーションを区別するアプリケーション

公式ブログのエントリ「Installations Identifying App」をはてブtwitter連携使って投げたら、なんかすごい勢いでクリックされたみたいなので訳してみた。誤訳とかあったら教えて。

インストーレーションを区別するアプリケーション

Tim Brayが投稿


この投稿の内容は、本ブログの執筆者たちがいつも不思議に感じていることについて内部での議論から生まれました

Androidのグループでは、信頼でき安定した端末識別子を取得するのに問題があるという不満を開発者から時折聞く。これは私たちを少し不安にさせる。なぜなら、そのような識別子を追跡することは良いアイディアではないと考えるし、開発者の目的を達成するのにより良い方法があるからだ。

インストーレーションを追跡

開発者がアプリケーションのインストーレーションを個別に追跡したいと考えるのは一般的だし、完全に理にかなっている。TelephonyManager.getDeviceId() を呼び出して、その値を識別に使うのは、ぱっと見よさそうに思えるかも知れない。これには問題がある。

  • 挙動が信頼できない。(後述)
  • きちんと動作したとしても、端末の初期化(工場出荷時への初期化)しても残るので、悲惨な間違いを犯してしまう危険性がある。例えばユーザが端末を初期化して、他の人に渡した時。


インストーレーションを追跡するには、例えばUUIDを識別子として使うことが出来る。アプリケーションがインストール後に初めて起動したときに、新しいのを作るだけだ。以下はInstallation.id(Context context)という静的メソッドを持つ"installation"というクラスの雛形だ。インストールに関連したデータをINSTALLATIONファイルにもっと書き込むこのができるのは容易に想像がつくだろう。

Installationクラスのソースコードは元記事を参照

端末を識別

アプリケーションが端末を識別する必要があるとして、実際のハードウェアデバイスIDを使うとどうなるだろう。これはトリッキーな問題だ。


過去、すべてのAndroid端末が電話だった頃は、事は単純だった。ネットワークの種類にに応じて、電話機のIMEI、MEID、ESNをTelephonyManager.getDeviceId()が返すことが必須だった。そしてその値はその端末に一意に決まる。

  • 電話以外: 携帯電話のハードウェアを持っていないWiFiのみの端末や音楽再生機は、この種のユニークな識別子を持っていない。
  • 固定値: この識別子を持っている端末では、端末初期化や工場出荷時への初期化をしても値が変わらない。それでも、アプリケーションからみて同じ端末であると扱わなければいけないかどうかは不明だ。
  • 特権: READ_PHONE_STATEパーミッションが必要になり、携帯電話機能を使わないし必要もないなら、厄介だ。
  • バグ: 実装に問題がある製品がいつくかあることが分かっていて、0や*といったゴミデータを返す。

物理アドレス

端末のWiFiBluetoothのハードウェアから物理アドレスを取得することも考えられるだろう。しかし、ユニークな識別子として利用するのは推奨しない。まず、すべての端末がWiFiを搭載しているわけではない。また、WiFiの電源が入っていない場合、ハードウェアが物理アドレスを報告しないかもしれない。

シリアル番号

Android 2.3 (Gingerbread)以降では、シリアル番号がandroid.os.Build.SERIALが使える。携帯電話機能のない端末ではユニークな端末IDを返す。つまり、いくつかの端末ではこの方法が使える。

ANDROID_ID

ANDROID_ID、より正確に言うとSettings.Secure.ANDROID_IDは、64bit幅で、端末が最初に起動したときに生成され、端末に保存される。端末が初期化されるとリセットされる。


ANDROID_IDはユニークな端末識別子として良い選択に思える。しかし、適切でない面もある。

  • Android 2.2 (Froyo)以前のリリースでは、100%信頼できるものではない
  • 主要なメーカーのある人気の端末で、少なくとも1つ広く知られたバグがあった。その端末はすべての製品が同じANDROID_IDを持っている。

まとめ

ごく一般的に言って、アプリケーションは物理的な端末を識別する必要はなく、インストールされたことを区別すればいい。運よくそれは単純だ。


特定の端末を識別するのを避けることには、良い理由が多くある。どうしてもというのであれば、ANDROID_IDを使用するのはベストプラクティスだ。ただし、最近の機種に限定され、過去の端末に対応するにはバッドノウハウが必要になる。