LoginSignup
26
28

More than 5 years have passed since last update.

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

Posted at

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に記述するだけで、ちゃんと受信できていました。

26
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
28