2012/01/29

[android]AppWidgetを複数扱う

EjectSD、というAndroidのアプリを公開している。
何をするものかというと、SDカードのマウント/アンマウントをするAppWidgetだ。
デスクトップに置く際、マウントポイントを設定してもらい、アイコンをタッチすると、マウント/アンマウント動作をするというものだ。

 

シンプルといえばシンプルなのだが、ここに至るまでは面倒だった。
Acer A500で作っていたのだが、マウント/アンマウントのインテントが飛んでこないのだ。
それより面倒だったのは、SDカードのマウントポイントがよくわからないこと。
getExternalStorageDirectory()で取ってこれる、ということになっているのだが、いろいろとメモリの配置などの関係から、このAPIでは期待するパスが取って来れないことがあるのだ。

そこら辺を適当に処理して、今に至っている。

しかし、最近はSDカードだけでなく、USBメモリもさせることが多い。
要望として「両方なんとかしたい」というものがあった。
まあ、そうだろうねぇ。

一番簡単な対策は、別名にしたアプリをもう1つ公開することだ。
アイコンも別の形にすれば、見分けは付くだろう。
ただこの方法は、あんまり格好がよろしくない。
なんというか「負けた」感じがするのだ。

そんなわけで、土日で複数扱えるように対応していた。


簡単だろうと思っていたのだが、あまり把握していないこともあって、難儀した。

まず、パスの入力。
ListPreferenceを使っているのだが、これはデフォルトのプリファレンスに保存する。
これをAppWidgetごとにしなくてはならない。
考えたあげく、デフォルトのプリファレンスが書き換わったときのListenerで個別に書き写す、というやり方にした。
格好が悪い。。。

 

それ以上に困ったのは、アイコンの更新。
クリックしたアイコンの処理だけしたいのだが、なんか上書きされている。
これは検索するといろいろ情報が出てきた。
出てきたのだが、まねするとインテントが受け取れなくなった。。。

まねしたのは、AppWidgetのIDをURIとしてsetData()する方法だったのだが、インテントフィルタをちゃんと書いてなかったので受け取れなかった(のだろう)。
めんどくさかったので、putExtras()でやるようにした。

 

そして、マウント/アンマウントインテントの受け取り。
mountやumountすると、その結果がインテントでブロードキャストされる。
それをonReceive()で受けとるのだが、そのインテントには当然AppWidgetのID情報など載っていない。
どうしたもんだか・・・と考えたが、もう全部のインスタンスを更新することにした。
AppWidgetManager.getInstance(context).getAppWidgetIds(componentName)としてIDの配列を受け取り、全部に対してupdateAppWidget()してやった。
onUpdate()の中では、IMountService.getVolumeState(path)でマウント状態を取得してアイコンを差し替えている。

 

残るは、過去との互換。
EjectSDはデフォルトのプリファレンス、今回は個別のプリファレンスだ。
うまく切り替えられるように作るべきか・・・と迷ったが、あきらめた。
別のアプリにしてしまった。
パスが1つでいいのなら、前ので十分だしね。


今回、A500がandroid3.2になってからだったが、MOUNTやUNMOUNTのインテントが飛んでくるようになった。
特にインテントフィルタ周りは何もしていないのだが・・・。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。