月別: 2015年5月

覚え書き 主にPreferenceActivity絡み

android用の神経衰弱ゲームを公開しました(・∀・)
The Match-up(Memory) game for android was released!

Google Play:
Mole's Match-up.

Introduction page:
Mole’s Match-upをリリースした∩( ・ω・)∩


XMLを使わずに動的にレイアウトを生成する時にidを付加する時にかぶらずにidを
付与する方法ってあるのかと思い、ぐぐる。

あまり詳しく目を通してないが以下のページで解決しそう。
上はid絡みの説明、下は実際のコード。
android – How can I assign an ID to a view programmatically?
Android: View.setID(int id) programmatically – how to avoid ID conflicts?

必要になったら改めて目を通そう。

関係ないが途中で出てきたAtomicIntegerってなんじゃらほいと思ったが、JavaDocを読んでも
よく分からない。他にヒットしたAtomicIntegerを追ってみたというエントリを読んで一瞬分かった
ような気になったが、多分本当は理解していないと思う(ノ∀`)


ようやく重い腰を上げてPreferenceActivity周りを調べ始める。
Android 設定画面を簡単に作る方法を読んだが、
PreferenceActivityの呼び出し部分がねぇΣ(゚∀゚;)

設定値を簡単に保存するプリファレンスの使い方 を見て、
単純にstartActivity()すればいいことに気づいた(ノ∀`)


まだまだ手を出す段階ではないがレイアウトのカスタムってどうすんだべ(´・ω・`)?と
思ってぐぐった。

PreferenceActivityのレイアウトカスタマイズ
PreferenceActivityのレイアウト変更

なるほど、PreferenceActivityはListActivityを継承してるのか。
そういやスクロールとか出来るもんな。必要はないけどただのListActivityということは
フリックで設定画面を切り替えることも出来るのか。必要があるかはともかくとして。


メソッド addPreferencesFromResource(int) は型 PreferenceActivity で使用すべきではありません
method addpreferencesfromresource(int) from the type preferenceactivity is deprecated
というような警告が出ているのが気になってぐぐった。

android – What to use instead of “addPreferencesFromResource” in a PreferenceActivity?

これまた詳しく読んでないけど、PreferenceFragmentという奴を使えばいいらしい。
文中にあったリンク、Example of using PreferenceFragmentからサンプルを
ダウンロードしてインポートした。
まあそんなに複雑な話じゃなくて普通のActivityとFragmentと変わらないのかな。

試してないけど日本語のサンプルもあった。後で試そう。
PreferenceFragmentについて


サンプルの途中で出てきたandroid.R.id.contentってなんだべ(´・ω・`)?
ファイル内を確かめてもそんなものは何処にもない。ぐぐる。

android – Get root view from current activity
Activityのビュー階層とコンテンツルート(View)を取得する
レイアウトの階層について(android.R.id.contentなど)
レイアウト(8)-Viewの階層構造をあやつる

ほほぅ(・∀・)
rootView用の予約済みidみたいなもんなのか。
今すぐ使うわけでもないが、これはいつか使うかもしれない情報だな。


連日更新なんかしたくないのに、色々と書き留めて置かないといけないことが多過ぎる…(ヽ’ω`)

これでもくらえ!バーニングブック!ヽ(`Д´)ノ -6

android用の神経衰弱ゲームを公開しました(・∀・)
The Match-up(Memory) game for android was released!

Google Play:
Mole's Match-up.

Introduction page:
Mole’s Match-upをリリースした∩( ・ω・)∩


アクティビティを訳した。
長いといえば長いがやけに時間がかかったな。
暑いから処理能力が落ち始めてるのだろうか(ヽ’ω`)

図の修正とテーブルの移植に手間取ったからか。
フローみたいなベクターグラフィックで表せる図はHTMLコードで生成出来て、その
ブラウザのロケール?等で表示される言語を変えるみたいなことが出来ても
良さそうな気がするんだけども、そういう機能はないんだろうか(´・ω・`)

テーブルは元ページにあったものを利用したけど、frame属性があると意図通りに
表示されないので削除した。そうしたら両サイドにも罫線というか枠線が表示
されるようになってしまったが(・3・)キニシナイ

そう言えばなんでテーブル内の緑字で表示させようとしている単語を<code>で2重に
覆ってるんだろ?一つじゃ駄目なのだろうか。或いは<code></code>の時と
<code><code></code></code>の時でページの生成時に
処理が違うとかあんのかな?


ついにFragmentのところに到達。長いけど、これからFragmentを使うから頑張って
急いで訳すべきだろうか。うーむ…(ヽ’ω`)

Android:デバイスIDの取得

android用の神経衰弱ゲームを公開しました(・∀・)
The Match-up(Memory) game for android was released!

Google Play:
Mole's Match-up.

Introduction page:
Mole’s Match-upをリリースした∩( ・ω・)∩


取り敢えず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 ハッシュ関数  
    private static String hashByte2MD5(byte []hash) {  
        StringBuffer hexString = new StringBuffer();  
        for (int i = 0; i < hash.length; i++) {  
            if ((0xff & hash[i]) < 0x10) {  
                hexString.append("0" + Integer.toHexString((0xFF & hash[i])));  
            } else {  
                hexString.append(Integer.toHexString(0xFF & hash[i]));  
            }  
        }  
          
        return hexString.toString();  
    }  

 if ((0xff & hash[i]) < 0x10) {  
                hexString.append("0" + Integer.toHexString((0xFF & hash[i])));  

の部分だ。

そう言えば余分な文字は”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 = "";
for (int i=0; i<messageDigest.length; i++){
     tempString = Integer.toHexString(0xFF & messageDigest[i]);

     if(tempString.length()<2){
        hexString.append("0" + tempString);
     }else{
        hexString.append(tempString);
     }
}

みたいに改変。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は同一なんだろうか。謎だ…(ヽ’ω`)

IllegalArgumentException: Service Intent must be explicit

android用の神経衰弱ゲームを公開しました(・∀・)
The Match-up(Memory) game for android was released!

Google Play:
Mole's Match-up.

Introduction page:
Mole’s Match-upをリリースした∩( ・ω・)∩


Google In-App billing, IllegalArgumentException: Service Intent must be explicit, after upgrading to Android L Dev Preview

nexus9(Lolipop)の方での動作もたまには見てみるかと思って実行したら、

java.lang.IllegalArgumentException: Service Intent must be explicit

みたいなエラーで速攻で落ちたΣ(゚∀゚;)

コードの方をチェックしたら、エラーになってるのはインテント絡みらしい。
こんな感じのインデントを飛ばしてる箇所。

OtherService.java
public static final String ACTION_STATE_CHANGED = "com.example.activityloopertest.ACTION_STATE_CHANGED";

OtherClass.java
startService(new Intent(OtherService.ACTION_STATE_CHANGED));

Android4系では動くのにLolipopでは落ちる(´・ω・`)
よくわからないのでぐぐる。
Google In-App billing, IllegalArgumentException: Service Intent must be explicit, after upgrading to Android L Dev Preview

ちゃんと読んでないのでよくわからない(ノ∀`)
Lolipopからexplicit intentじゃないと駄目みたいだが、そもそもexplicitだし…
取り敢えず途中にあったコードを参考に全ての上記のようなインテントの箇所を
修正してみた。

tempIntent = new Intent(MoleMusicPlayerService.ACTION_STATE_CHANGED);
tempIntent.setPackage(MainActivity.PACKAGENAME);
startService(tempIntent);

一応これで落ちなくはなった。setPackage()すれば良いと言うことなのかな?
よく分からない…(ヽ’ω`)