28
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

AndroidでManifestにIntentFilterを記述してもBroadcast Intentが受け取れない

Androidでは、Intent.ACTION_BOOT_COMPLETEDなど、AndroidManifest.xmlに<intent-filter>を記述するだけでOSや他のアプリが発行するインテントを受け取ることができます。
(PackageManagerのqueryBroadcastReceivers()でリストアップされるようになる)

AndroidManifest.xml
        <receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BATTERY_LOW"/>
            </intent-filter>
        </receiver>

一方、Intent.ACTION_SCREEN_ONなどはContext.registReceiverで明示的に登録しないと受け取れるようになりません。

MyActivity.java
    @Override
    public void onResume() {
        super.onResume();
        registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver);
    }

この違いはBroadcast Intentを発行するとき、Intent.FLAG_RECEIVER_REGISTERD_ONLYフラグが付けられているかどうか、のようでした。

【BroadcastReceiverについて】

FLAG_RECEIVER_REGISTERD_ONLYが付与されているIntentを受け取るにはContext.registerReceiverが必要なようです。
ActivityやServiceなどのContextのライフサイクルにそってregisterとunregisterをしなければいけないので少し面倒ですが、余計なBroadcastを受け取らずに済みます。

Context.registerReceiverが必須なシステムのintent

システムが発行しているBroadcast Intentのなかだとどれが当たるんでしょう。。
githubのmasterを検索すれば見つかると思いますが、使いそうなものを自分用メモとして残しておきます。

Intent.ACTION_DREAMING_STARTED
Intent.ACTION_DREAMING_STOPPED
Intent.ACTION_SCREEN_ON
Intent.ACTION_SCREEN_OFF
Intent.ACTION_MANAGED_PROFILE_ADDED
Intent.ACTION_BATTERY_CHANGED
Intent.ACTION_POWER_CONNECTED
Intent.ACTION_TIME_TICK
Intent.ACTION_HEADSET_PLUG

AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG
AudioManager.ACTION_USB_AUDIO_ACCESSORY_PLUG
AudioManager.ACTION_ANALOG_AUDIO_DOCK_PLUG
AudioManager.ACTION_DIGITAL_AUDIO_DOCK_PLUG
AudioManager.ACTION_HDMI_AUDIO_PLUG

// あまり使わなそうなACTION
DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED
DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED
NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED  PowerManager.ACTION_POWER_SAVE_MODE_CHANGING
PowerManager.ACTION_POWER_SAVE_MODE_CHANGED
NetworkStatsService.ACTION_NETWORK_STATS_UPDATED    

結構ありますね。。
アプリを起動していないのにManifestに書かれただけで、頻繁に呼ばれることでシステムリソースを無駄に消費しないような工夫かと思います。
Intent.ACTION_BATTERY_CHANGEDやIntent.ACTION_SCREEN_ONなどは時々使いそうです。

Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOTという@hideなフラグもありましたが、端末ブート後には関係なさそうですね。
Intent.ACTION_DATE_CHANGEDなどはmanifestに記述するだけで、ちゃんと受信できていました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
28
Help us understand the problem. What are the problem?