2015年3月23日月曜日

初心者がハマったインテントフィルター

夜な夜なアプリを書き換えててハマりました。

BroadcastReceiverが受信できる種類をあらかじめ指定するためにAndroidManifest.xmlでintent-filterで指定します。

実際に指定したメッセージがBroadcastReceiver内のonReceiveメソッドに届く訳ですが、この中で定義されているものとの比較処理がほぼ必ず入ります。(単一のものであったり、ただのイベントとして捕らえるのであれば比較すら不要かもしれませんが、そこまで横着したコードは今のところ目にしていません)

まずここで、manifestで記述する方法ですが、ほぼ直接テキストとして記述しています。
xmlリソースで定義しても良さそうですけど、SDK側から特にリソースという形で提供されていないのかな?見たことありません。

鶏の卵の話ですが、私の場合は先にコードが先行するのでプログラムコード上では、次のような形になっています。
if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
    :
    :
}
ではこの「WifiManager.WIFI_STATE_CHANGED_ACTION」 ってmanifestでどうかくんじゃ?って話になりますが、これって多分普通はプログラムソースをGo to/Declaration(Ctrl+B)とかで追っかけるのが普通なのかな?(今気がついた方法ですが(笑))
私はこれをぐぐってデベロッパーズガイドを参照するという方法を取っていました。
ドキュメントにはちゃんと書いてあるんですよ。一応ね。
それを参考にして実際に記述してみるとこのようになりました。
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
<action android:name="android.net.wifi.STATE_CHANGE"/>
</intent-filter>
さて、これは問題の無い例です。(実際には具体的な文字列を探すだけでも一苦労でしたけど(笑))
これはwifiのSSIDを表示するためのものですが、別のものはバッテリーの情報を探すものです。

同様に
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
    :
    :
}
と書いたので、manifest
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED"/>
</intent-filter>
って書いてみました。
実際に実行してもこれが待てど暮らせど一向にメッセージは受信しません。
javaパッケージ名がだめなのか?とかmanifestの記述している記述内容が間違っているのか?とか色々と確認したり、インストールしなおしたりと試行を繰り返しましたが全く変化がありません。

ためしにぐぐってみたりSDKを見て見ました。
ちゃんと書いてありましたよ…SDKに…
 Intent | Android Developers
 You can not receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver(). See ACTION_BATTERY_LOW, ACTION_BATTERY_OKAY, ACTION_POWER_CONNECTED, and ACTION_POWER_DISCONNECTED for distinct battery-related broadcasts that are sent and can be received through manifest receivers.

This is a protected intent that can only be sent by the system.
 「Content.registerReceiver()のみ登録できます。」とのこと。まじか(笑)
理由は下に書いてある通りですけど、なるほどね。

結果として今のところ良くも悪くもServiceを用いてインテントフィルターを設定してあげるのが良いということなんでしょう。
そもそもServiceのライフサイクルって厳密にどんな形で行われているのかというのが非常に気になってくる部分でもあります。

0 件のコメント:

コメントを投稿