广播接收者登记清单与活动

我需要一些帮助来了解什么时候我可以期待我的广播接收机在刚刚在清单中注册的时候工作,而不必从正在运行的活动或服务注册。

因此,例如,如果我注册一个独立的接收器与以下意图filter它的作品没有一个服务/活动引用:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.blk_burn.standalonereceiver" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" /> <uses-permission android:name="android.permission.WAKE_LOCK"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <receiver android:name="TestReceiver"> <intent-filter> <action android:name="android.media.AUDIO_BECOMING_NOISY"/> </intent-filter> </receiver> </application> </manifest> 

但是,如果我用android.media.AUDIO_BECOMING_NOISYreplaceandroid.media.AUDIO_BECOMING_NOISY接收器不会被触发( Android文档 )

从我在这个网站上发现的,你必须注册这个接收器从一个已经运行的活动或服务( 邮政 )。

  • 任何人都可以告诉我为什么这不起作用,当调整清单中的意图filter,为什么你需要有一个服务运行在后台引用/注册接收器?

  • 有没有解决办法,以便我可以注册我的接收器在我的应用程序的清单使用intentfilterandroid.intent.action.HEADSET_PLUG

  • 我怎么能从android文档中识别哪些广播操作需要服务或活动注册,而不是在清单中有正确的filter?

如果您的接收器在清单中注册,并且您的应用程序未运行,则将创build一个新的进程来处理广播。 如果你在代码中注册它,它就和你注册它的活动/服务的生命有关。对于一些广播,如果创build一个新的应用程序进程,如果它不存在,或者有一些安全性,性能等方面的影响,因此您只能在代码中注册接收方。

至于HEADSET_PLUG广播,看来这个想法是,你已经运行的应用程序可以得到这个应用程序特定的UI,音量等的调整。如果你的应用程序没有运行,你不应该真正关心的耳机被拔掉。

AFAIK,没有一个单一的地方,所有的广播都汇总了这个信息,但是每个Intent应该在JavaDoc中有一个关于如何注册和使用它的评论,但是显然它缺less地方。 如果你为Intent.FLAG_RECEIVER_REGISTERED_ONLY grep Android源树,你应该能够编译一个列表。

像通常一样,广播接收器可以在清单文件AndroidManifest.xml中configuration。 以这种方式configuration的BroadcastReceiver称为静态注册。

您可以使用以下元素在清单文件中注册接收者:

 <receiver android:name=".ConnectivityChangeReceiver"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> 

嵌套元素用于指定接收器应对的事件。

Dyanmic Broadcast Recievers

作为替代,您可以在您的代码中dynamic注册您的BroadcastReceiver实现。 你只需要在Context对象上调用registerReceiver()方法。

registerReceiver()方法有两个参数:

registerReceiver()方法的参数

  • receiver:您要注册的BroadcastReceiver
  • filter: IntentFilter对象,用于指定接收者应该侦听哪个事件。

当你以这种方式注册你的接收器时,只要组件存在,Android就会向这个接收器发送事件,直到创build组件本身被破坏。

这是您正确处理生命周期的任务。 因此,当你dynamic添加一个接收者时,注意在你的Activity的onPause()方法中注销同一个接收者!

我build议在你的Activity的onResume()方法中注册接收者,并在你的onPause()方法中注销它:

 @Override protected void onPause() { unregisterReceiver(mReceiver); super.onPause(); } @Override protected void onResume() { this.mReceiver = new ConnectivityChangeReceiver(); registerReceiver( this.mReceiver, new IntentFilter( ConnectivityManager.CONNECTIVITY_ACTION)); super.onResume(); } 

何时使用哪种方法进行注册

使用哪种方法注册您的BroadcastReceiver取决于您的应用程序如何处理系统事件。 我认为基本上有两个原因,为什么你的应用程序想知道系统级事件:

  • 你的应用程序提供围绕这些事件的某种服务
  • 你的应用程序要慷慨反应,以改变状态

第一类的例子是一旦设备启动就需要工作的应用程序,或者安装应用程序时必须启动某种工作的应用程序。 电池Widget Pro或App2SD是这些types的应用程序很好的例子。 对于这种types,您必须在清单文件中注册BroadcastReceiver。

第二类的例子是指示你的应用程序可能依赖的情况发生变化的事件。 说你的应用程序依赖于build立的蓝牙连接。 您必须对状态更改做出反应 – 但只能在您的应用程序处于活动状态时进行。 在这种情况下,不需要静态注册的广播接收机。 dynamic注册的会更合理。

还有一些事件甚至不允许静态注册。 一个例子是每分钟播放一次Intent.ACTION_TIME_TICK事件。 这是一个明智的决定,因为静态接收器会不必要地耗尽电池。