カテゴリー: Android

Fragmentがよくわからない(´・ω・`)

一応、ViewPagerにListFragmentを乗せてListViewのアイテムをクリックすると
音楽再生がされるようになった。回転しても問題ない。

アルバム別とアーティスト別は詳細項目を表示せずに、全ての曲を再生するという形にして
みたが、何かそれはおかしいと気付き、各アルバム、各アーティスト用のフラグメントを
用意してみようと試みる。

だがここで一週間弱はまる…(ヽ'ω`)
そして今も完全には解決しているわけではない…_| ̄|○


色んなサイトを巡って読むのに疲れた…__◯_
ようやくreplaceを使って新しいFragmentを表示出来た(・∀・)と思ったら
前のFragmentが何故か残ったまま……サイトによっては上に来る背景色を
不透明にして下のFragmentのenabledをfalseにするみたいなことが書いて
あって「( ´・ω・)エ?」となる。俺氏はFragmentを理解していない又は勘違いしている
という可能性が高いのだが「なんだこの糞仕様は(´・ω・`)」とがっくり来る。
何かしらの理由があってこういう仕様なんだろうけど。
FragmentStatePagerAdapterを使えばいいのだろうか?
それともsetRetainInstance(true)の絡み?

Android: Replaced Fragment Is Still Visible
T.Yokoyamaのブログ: Support Packageを使ってFragmentを利用する

Fragment#replaceを使わずに一気にFragmentを交換するというのもあってコードを
眺めていたら一旦Fragmentを全部削除して差し替え済みのListを渡す形になっていて
「なんという力業…( ;・´ω・`)ゴクリッ」と思ったが、replace自体が

処理としては、同じ containerViewId に追加されている全ての Fragment に対して remove(Fragment) を呼び、それから add(containerId, fragment, tag) を呼ぶのと同じ
Android FragmentTransaction のまとめ

という形みたいなので、replaceからして力業なんかΣ(゚∀゚;)


というわけでFragment関連のドキュメントを読みすぎてFragment酔いになり、
加えてFragmentManagerのバックスタック?ってアクティビティ内で一つだけ
っぽいのも気になり、何故か「Activityをフリックして切り替えるコードが
確かあったから、複数のFragmentじゃなくて複数のActivityにすれば
FragmentManagerのバックスタックも個別になるんじゃね(・∀・)?
左右の無限ループも可能になるし」と血迷う。

またActivityやGestureDetectorなどを調べたり、コードを移植するのに
長い時間を費やす……___ 

お試しだから決め打ちでいいのに、何故か汎用的にしようとし更に時間を…

具体的にはActivityManagerみたいなクラスを作って、getPackageInfoで
得た文字列を、フリック対象のActivityを指定する為のActivityの
名前(正確にはstartWithで使用するプリフィックス)でふるいにかけて出来た
パッケージ名込の文字列のArrayListを渡して、そのままのArrayListと
lastIndexOf(".")で切り分けたActivityの名前のみのArrayListにして、
GestturaDetectorの左(右)へのフリック時にgetLocalClassName()で得た名前を
ActivityManagerへ送ってAcitivity名のArrayListの位置から現在位置と左(右)の
パッケージ名込のAcitivity名を取得して、その名前からClass#forName()で得た
クラスでインテントを作成して左(右)のActivityを起動するという……
なんだか書いていてよくわからなくなってきた…( ´・ω・)

そこまでやってListFagmentを乗っけた ← イマココ


これにはまってて翻訳はDevice Compatibilityまでしか訳せてない…(ヽ'ω`)
全然関係ないけどこのページのCompatibilityは互換性じゃなくて適合性で
訳した方がすっきりしたな。

覚え書き

E/ActivityThread(2733):
Activity com.example.musicplayer.MusicPlayerActivity 
has leaked ServiceConnection 
com.example.musicplayer.MusicPlayerActivity$1@44ac5bd8 
that was originally bound here

色々なパターンで出るらしいが今回の場合はunBindしてないサービスを再びbindしようと
していたのが原因みたい。あとonDestroyでunBindしていない場合にも発生した。


QCMediaPlayer mediaplayer NOT present

android - Why MediaPlayer throws NOT present error when creating instance of it? - Stack Overflow

It means your platform does not support QCMediaPlayer. 
QCMediaPlayer provides extended APIs and interfaces to get 
and set MPD attributes for DASH protocol in compatible 
Snapdragon builds. So, this error should not affect on 
media playing in normal case

”あなたのプラットフォームがQCMediaPlayerをサポートしていないことを意味します。QCMediaPlayerはSnapdragon互換ビルド?でDASHプロトコル用のMPD属性を取得や設定する為の拡張されたAPIやインターフェースを提供します。従って、このエラーは通常の場合メディア再生に影響しないはずです。”

みたいな感じなので、無視していいみたい。SOL25がsnapdragon搭載だから出てるのかな?



MediaPlayer Should have subtitle controller already set

Should have subtitle controller already set というエラー - Google グループ
Should have subtitle controller already set Mediaplayer error Android - Stack Overflow
Android MediaPlayer warning: Should have subtitle controller already set - Stack Overflow

kitkat(4.4)以降で出るようになった模様。subtitle controllerが動画の字幕関連の
ものらしく、音楽再生には関係ないらしい。二番目のページで空のSubtitleControllerを
作ってMediaPlayerにセットするという回避法らしきものがあったけれども、面倒なので
試していない(ノ∀`) 歌詞ファイルでも読み込んで適切な時に歌詞をくれるなら意味が
ありそうだが、そんな機能はあるんだろうか?


MediaPlayer.create() と setAudioStreamType() は相性が悪い

何を調べてる時にヒットしたのか忘れたが、こういうこともあるのか。


stop called in state 1

元にしたチュートリアルのServiceのonUnbind()と同じ

mp.stop();
mp.release();

にしていたが、終了方法が違う場合にエラーが出た。

idleかなんかの状態でstop()を呼んでるのがいけなかったらしい。
stop()をreset()にしたら、エラーは出なくなったがこれでいいんだろうか?
そもそもrelease()が呼び出せる状態がanyだからreset()する必要はあるのか?
謎だ。


ViewPagerでの無限ループ移動が出来るかどうかぐぐった。
→ あるにはあったが、なんだかようわからんのでパス(´・ω・`)
→ ViewPagerにListFragmentを載せる方法がわからなくて四苦八苦
→ 色々ドキュメントを読んでようやくわかる∩(・ω・)∩
→ 画面回転時にアクティビティが再作成されてService内で色々とエラー地獄
→ MediaPlayerをunBindせずreleaseもせずやろうとするも違うエラー地獄
→ android:configChanges="orientation|screenSize"を指定して自分で
レイアウトをいじる方法を探すかと思う(´・ω・`)
→ 指定したらエラーが消えて何故か画面回転してもきちん横長なレイアウト?になる
→ フシギ(・∀・) ←イマココ

なんで大丈夫なんだろうか。大元がmatch_parentなViewPagerだけで中身が
setRetainInstance(true)してるFragmentだからレイアウトが関係ないと
いうことなんだろうか。基礎知識がないのでよくわからないw

今回の件でようやくAndroidの基礎的な部分を調べ始めた(ノ∀`)


仕事探さなきゃといいながらこんなことやったり、Androidの基礎編とか
訳し始めながら、ソリティ馬やったり、ねこあつめでまんぞくさんの為に
高級カリカリを用意したりする日々。これではいけませんね…( ´・ω・)

Phone UIとTablet UIの判別方法がよくわからない(´・ω・`)


未だによくわかってない(´・ω・`)

高解像度の端末用にゲームの画面を拡大しようとしていてあることに気づく。

novo7 advanced(4.0.4)
novo7

sol25(4.4.2)
sol25

ナビゲーションバーの位置が違う( ;・´ω・`) ナニコレ…


ぐぐってみたらPhone UIとTablet UIという違いがあるのかΣ(゚∀゚;)

これどうやったら違いを判別出来るのよとぐぐったがよくわからない(´・ω・`)
そもそもピクセルとかdpiとかdipという言葉を何となくわかったつもりでは
あったが実は全然理解出来てないことが発覚Σ(゚∀゚;)

取り敢えず
DisplayMetrics
スマートフォンと画面解像度・ピクセル密度
に目を通して何となく分かったつもりになったけど、
そらで説明しろと言われると出来ないと思うw

build.propのro.sf.lcd_densityをいじくると切り替えられるらしい…
これは判別とは関係ないな。
Nexus 7をタブレットUIで使う方法。
カーネル入替なしでどれだけできるか
LCD densityをいじってXperiaの情報量を増やす


更にぐぐっていくとAndroidのソースでの判別式が(・∀・)
Ice Cream Sandwich を Tablet 向け、Phone 向けにビルドする方法

PhoneWindowManager.javaの

int shortSizeDp = shortSize
                * DisplayMetrics.DENSITY_DEFAULT
                / DisplayMetrics.DENSITY_DEVICE;

mStatusBarCanHide = shortSizeDp < 600;

でmStatusBarCanHideがtrueならphone UIらしい。
しかしよくわからない(ノ∀`)

同じブログの他のエントリを読む。
Android 4.4 ( KitKat ) の Phone UI と Tablet UIでは

int shortSizeDp = shortSize 
                * DisplayMetrics.DENSITY_DEFAULT
                / density;

という式があった。shortSizeが短辺でDisplayMetrics.DENSITY_DEFAULTが160と
いうことはわかったがdensityであれ?っとなる。純粋にdensityというと一桁の数値
なのでそれを代入すると600以下になることはあり得ないような…

metrics.densityDpiで割るとちょうど良いような感じがするので試してみたら、
上手く行った…っぽい。auの端末一覧にある数値を幾つか当てはめてみたら
タブレットらしいASUS MeMO Pad 8 AST21が1200x160/320=600でそれ以外は
ほとんど360とかで合ってる…っぽい。

Libオブジェクトというグローバルオブジェクトのようなゴテゴテのstatic変数の
固まりを使っているので全然オブジェクト志向じゃないプログラムをしているのが
ばれてしまうが、うちでは起動時に

DisplayMetrics metrics = new DisplayMetrics();
Lib.getWindowManager().getDefaultDisplay().getMetrics(metrics);

int shortSize = Lib.getCurrentWidth()<Lib.getCurrentHeight() ? Lib.getCurrentWidth():Lib.getCurrentHeight();
int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / metrics.densityDpi;
Lib.setmNavigationBarCanMove(shortSizeDp < 600);

みたいな感じにして判別箇所でif(Lib.ismNavigationBarCanMove())するようにした。
一応機能しているっぽいけど、本当に正しいのかどうかよくわからない(ノ∀`)

試してないけど、これでも判別は出来るのかな?
タブレットとスマートフォンで処理やレイアウトを切り替える

Could not parse mediation config -2

解決はしていないが今のところ無理という結論で納得することにした(´・ω・`)

詳しく読んでないのでアレだが、多分うちと違う内容くさい。
Android admob interstital not loaded if not used with a banner

ただ240x320がどうたらという部分を読んでエミュレータで実験してみた。

android 2.3.3 240x400
240x400-interstitial240x400-interstitial-2

→OK

android 2.3.3 240x320、android 4.0 240x320
240x320-interstitial240x320-android4-interstitial

→NG

単純にこれだけを見ると240x320でテストデバイスに追加されている場合に
エラーが発生しているようにも思えるけどどうなんだろう?

android - Google Play services version issue! Working app with admob ads has stopped showing ads
の内容が似ているような気がするけど解決してないみたいだし。
GooglePlayサービスだかのバージョンが関係してるんだろうか?

英語じゃないと駄目とかレイアウト絡みの問題という記述もあったけど、
どうもうちのパターンとは違うみたいだった。

まあ何はともあれ現段階では240x320サイズでTestAdは表示されないと
認識しておけばいいか(´・ω・`)