Androidでは、Intent.ACTION_BOOT_COMPLETEDなど、AndroidManifest.xmlに<intent-filter>を記述するだけでOSや他のアプリが発行するインテントを受け取ることができます。
(PackageManagerのqueryBroadcastReceivers()でリストアップされるようになる)
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_LOW"/>
</intent-filter>
</receiver>
一方、Intent.ACTION_SCREEN_ONなどはContext.registReceiverで明示的に登録しないと受け取れるようになりません。
@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フラグが付けられているかどうか、のようでした。
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に記述するだけで、ちゃんと受信できていました。