ANDROID_IDでエミュレータを判定する方法はFroyoからは使えない

Androidアプリケーションにおいてエミュレータで実行しているか否かを検出するために以下のコードがよく使われる。

String android_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
if (android_id == null) {
    //エミュレータ
} else {
    //実機
}

Secure.ANDROID_IDはリファレンスには以下のように記述されている。

public static final String ANDROID_ID 

Since: API Level 3 A 64-bit number (as a hex string) that is randomly generated on the device's first boot and should remain constant for the lifetime of the device. (The value may change if a factory reset is performed on the device.) 

ファクトリリセットされた後の初回起動時に乱数生成された64bitの16進数がセットされるとある。ネットではAndroid Marketにアクセスされた際に付与されるという記述も散見されるが、リファレンスが正しいとすれば「生成された数値がAndroid Marketでも使われる」ではないだろうか。

コードに話を戻すと機器毎に乱数値が戻るはずの所エミュレータでは何度起動しても取得される値はnullであり、今まではそれを利用してエミュレータか否かを判断していた訳だ。

ところが最新のAnrdoid 2.2(Froyo)で実行するとエミュレータでは固定で"9774D56D682E549C"※という値を返すように変わっており今まで通りの判定ができない。つまりこの方法は使えないということになる。

代替えとしては、

    • Activity内にて
boolean isEmulator = false; 
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
if ( tm != null ) { 
    String devId = tm.getDeviceSoftwareVersion(); 
    isEmulator = ( devId == null ); 
} 
//isEmulatorが真ならばエミュレータ

という手も使えるらしいのだが、マニフェストにPHONE_STATEパーミションの許可が必要になってしまうのが嫌だ。
さてどうしたものか。

※私の環境ではという話。ひょっとしたら他の環境、OSでは違うのかもしれない。