Android:デバイスIDの取得

取り敢えずnexus9で起動したアプリを見てあることに気づいた。というか思い出した。
確かLolipopだとdeviceIdをLogCatから見つけられないから、testDviceに追加する
方法がわからなかったんだった。まあどうせ1000回表示したとしても1円だし、年に一回、
最低振込金額に到達すれば良い方なので余り気にしなくてもいいような気がしないでも
ないが、余計な事で怒られるのも嫌なので改めてぐぐる。

android - How can I get device ID for Admobにあった、md5()メソッドを利用する方法で
nexus9のdeviceIdを取得出来たみたいだったので、早速addTestDevice()にidを追加する。
テスト用のバナーになった。ひゃっほいヽ( ・∀・)ノ ←歓喜する俺氏。

返す刀で、

String deviceId = md5(android_id).toUpperCase();
        mAdRequest.addTestDevice(deviceId);

みたいに前もって取得したidをaddTestDevice()するのではなく動的にdeviceIdを
取得してaddTestDevice()してみる。テスト用のバナーになった。
ひゅーひゅーだよ ひゅーひゅーかきーん(・∀・)
↑歓喜の余りよくわからないことを言い出す俺氏。年齢がかなりいってることが分かる。

sol25で試す。
 
 
 
 
 
あれ(´・ω・`)?
テスト用バナーが表示されず、実際の広告が…
キャッシュとかされてるのだろうかと何度か試したが、事態は変わらず。
nexus9で再び試すとテスト用バナーが(・∀・)
sol25で再び試すと実際の広告が(´・ω・`)

ここで4.0.xを載せているnovo7でも試す。
 
 
 
 
 
やっぱり実際の広告が…_| ̄|○

もしかしてサンプルコードのmd5算出部分が間違えてるんじゃないの(・∀・)?と
失礼な疑念を抱き、色々とぐぐる。いくつかのサイトを眺めてみたが
 
 
 
 
 
よくわからない(・∀・)


仕方がないので取り敢えず、算出されたdeviceIdをコピペしてみる。

84D38FF70AB5889E8FB12E44734AFE08

特におかしなところも見当たらない

LogCatで取得済みのidは

84D38FF7AB5889E8FB12E44734AFE8

なので同一か…
 
 
 
 
 
いや、ちょっと待て(;・´ω・`)

84D38FF70AB5889E8FB12E44734AFE08
84D38FF7AB5889E8FB12E44734AFE8

並べてみて気づいたが、ちょっと長いぞ。なんか0が2つ多い。
なんかの法則で0が2つついておかしくなるに違いない(`・ω・´)
↑実はこの時、大きい勘違いをしてる俺氏。0付加されているのが正しい値で、
LogCatから取得した値。無い方がmd5()メソッドで取得した値。
色々調べてるうちに2つの値を取り違えたみたい(ノ∀`)

名探偵俺氏、その確証を得る為にnovo7のdeviceIdを取得して比較。

2F5820181984FD634C5344329B170C1
2f58201819840fd634c5344329b170c1

あれ、0が一つ多いだけだね(´・ω・`)


まあ何にしてもおかしいのでぐぐり再開。
取り敢えずmd5変換に種類があるのだろうかとぐぐったがそんなことはない模様。
php等でmd5変換をしてくれるページなどで試してみたが、md5()で算出される値と同じ。

Android4系以前とlolipop以降の差なんだろうかとも考えたがlolipop搭載端末は一台しか
持っていないのでその説を検証するすべがない。うーんと思いながら値を眺めたり、
md5変換のコードが載っているページを読んでいて、ふとある部分に目が行く。

//MD5 ハッシュ関数<br />
    private static String hashByte2MD5(byte []hash) {<br />
        StringBuffer hexString = new StringBuffer();<br />
        for (int i = 0; i &lt; hash.length; i++) {<br />
            if ((0xff &amp; hash[i]) &lt; 0x10) {<br />
                hexString.append(&quot;0&quot; + Integer.toHexString((0xFF &amp; hash[i])));<br />
            } else {<br />
                hexString.append(Integer.toHexString(0xFF &amp; hash[i]));<br />
            }<br />
        }

<pre><code>    return hexString.toString();  
}  
</code></pre>

 if ((0xff &amp; hash[i]) &lt; 0x10) {<br />
                hexString.append(&quot;0&quot; + Integer.toHexString((0xFF &amp; hash[i])));<br />

の部分だ。

そう言えば余分な文字は”0”だヽ(`Д´)ノ!
つまり10以下の値の時は結果が二桁になるように”0”を付加してるんじゃないか( ・´ω・`)?
↑”0x”がついてるので正確には15以下です。しかもそう思うにしても10じゃなくて9以下です。

よっしゃと思いmessageDigestの値を見る。
-124, -45, -113, -9, 10, -75, -120, -98, -113, -79, 46, 68, 115, 74, -2, 8

ビンゴや(・∀・)


勢いに乗ってnovo7のmessageDigestの値を見る。
47, 88, 32, 24, 25, -124, 15, -42, 52, -59, 52, 67, 41, -79, 112, -63

あるぇー(・3・)? 10以下がないお(´・ω・`)

予想が外れたことに意気消沈するも、

0が付加されるのは”15”…
元の値は”f”……
判定式は”0x10”………
 
 
 
16進数やないかΣ(゚∀゚;)

とようやく自分の初歩的な勘違いに気づいた(ノ∀`)

何はともあれAndroidのdeviceIdはF以下の値には0付加しないという規則があるのか
という結論に到達したが、これが勘違いによる正反対の結論であることに気がつくのは数時間後のお話…(ヽ'ω`)


取り敢えず、カッコ悪いがmd5()メソッドを

String tempString = &quot;&quot;;
for (int i=0; i&lt;messageDigest.length; i++){
     tempString = Integer.toHexString(0xFF &amp; messageDigest[i]);

<pre><code> if(tempString.length()&amp;lt;2){
    hexString.append(&amp;quot;0&amp;quot; + tempString);
 }else{
    hexString.append(tempString);
 }
</code></pre>

}

みたいに改変。StringBufferを使ってるコードでStringを使う俺氏、鬼畜(・∀・)
とか思って参考にしたコードの上の回答を見てみたら

String h = Integer.toHexString(0xFF & messageDigest[i]);
  while (h.length() < 2)
    h = "0" + h;
hexString.append(h);

みたいな感じで0付加するコードが載ってた…_| ̄|○
まあでも最初の段階でこのコードを読んでもわけが分からなかっただろうし、
同じようなコーディングだからいいか(・∀・)

AdRequestの方もちょっと修正。直にaddTestDevice()の中でgetDeviceId()を
呼んでもいいけど今の所はLogに書き込みたいのでこれでいい。

String tempString = getDeviceId();
Log.d(TAG, tempString);
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)       //エミュレータ
.addTestDevice(tempString)
.build();
adView.loadAd(adRequest);
private String getDeviceId(){
  String android_id = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
  String deviceId = md5(android_id).toUpperCase(Locale.ENGLISH);

return deviceId;
}

取り敢えずはこれでsol25とnexus9でテスト用バナーを確認。

だがしかしnovo7では表示されず(´・ω・`)
よくよく考えみたら、novo7上でこのコードではテスト用バナーも実際の広告も
表示されているところを見たことがなかったので他の問題か。でもゲームベースでは
表示されたしなと思って文字列で静的指定をするとテスト用バナーが表示された…
わけがわからないのでもう一度デバッグで動的指定を試すとテスト用バナーが表示された…
本当にわけがわからない…(ヽ'ω`)

まあ一応動的指定は出来るようになったようだ…


で、まあいつものパターンで日本語でぐぐったら、日本語の答えがあったりする…(ヽ'ω`)
AdMob テストで使う、デバイスIDを取得

ここのページのリンクを辿ってJavaDocを読んだけど、ANDROID_IDって

A 64-bit number (as a hex string) that is randomly generated when the user first sets up the device and should remain constant for the lifetime of the user's device. The value may change if a factory reset is performed on the device.

Note: When a device has multiple users (available on certain devices running Android 4.2 or higher), each user appears as a completely separate device, so the ANDROID_ID value is unique to each user.

Constant Value: "android_id"
Settings.Secure | Android Developers

デバイスをファクトリーリセットすると変わる可能性があるんだねぇ。
加えて複数ユーザー機能を使ってる場合、ユーザー毎にANDROID_IDは一意的なんだねぇ。
ANDROID_IDから取得出来るStringの内容を見てないから断言出来ないけど、複数
ユーザー機能を使用しているデバイスからは複数のデバイスIDが取得出来るのかな?
それともANDROID_IDから取得出来るStringは同一なんだろうか。謎だ…(ヽ'ω`)