广播接收机寄存器在清单与活动

我需要一些帮助来理解我的广播接收器在刚刚在清单中注册时和必须从正在运行的活动或服务中注册时什么时候能够正常工作。

例如,如果我用下面的意图过滤器注册一个独立的接收器,它不需要服务/活动引用就可以工作:

<?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.intent.action.HEADSET_PLUG代替 android.media.AUDIO_BECOMING_NOISY,接收器就不会被触发(Android 文档)

根据我在这个网站上发现的情况,您必须从已经在运行的活动或服务(邮局)中注册该接收器。

  • 有人能告诉我为什么这不工作时,只是调整你的意图过滤器在清单和为什么你需要有一个服务在后台运行,引用/注册接收方?

  • 是否有一个工作周围,以便我可以只注册我的接收器在我的应用程序的清单使用意图过滤器与 android.intent.action.HEADSET_PLUG

  • 如何识别 机器人文档中哪些广播操作需要服务或活动注册它们,而不是仅仅在清单中使用正确的过滤器?

62236 次浏览

如果您的接收器在清单中注册,而您的应用程序没有运行,则将创建一个新进程来处理广播。如果您在代码中注册它,那么它将与您注册它的活动/服务的生命周期绑定在一起。对于某些广播,如果不存在新的应用程序进程,或者存在一些安全性、性能等方面的问题,那么创建新的应用程序进程就没有意义,因此您只能在代码中注册接收方。

至于 HEADSET_PLUG广播,似乎你已经在运行的应用程序可以让它对 UI、音量等进行特定于应用程序的调整。如果你的应用程序没有运行,你不应该真的关心耳机被拔掉。

AFAIK,没有一个地方可以为所有的广播总结这些信息,但是每个意图应该在 JavaDoc 中有一个关于如何注册和使用它的评论,但是显然它缺乏地方。如果您对 仅接收方的 Android 源代码树进行 grep,那么您应该能够编译一个列表。

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

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

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

嵌套元素用于指定接收方应该响应的事件。

动态广播接收机

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

RegisterReceiver ()方法接受两个参数:

RegisterReceiver ()方法的参数

  • 接收器: 要注册的 BroadcastReceiver
  • Filter: 指定接收方应该侦听哪个事件的 InentFilter 对象。

当您以这种方式注册接收器时,只要组件存在,它就会一直存在,并且 Android 向该接收器发送事件,直到创建组件本身被销毁。

正确处理生命周期是您的任务。因此,当您动态添加接收方时,请注意在 Activity 的 onPuse ()方法中注销相同的接收方!

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

@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 取决于应用程序如何处理系统事件。我认为基本上有两个原因,为什么你的应用程序想知道系统范围的事件:

  • 你的应用程序为这些事件提供了某种服务
  • 您的应用程序希望对状态更改作出优雅的反应

第一个类别 的例子是需要在设备启动时立即工作的应用程序,或者在安装应用程序时必须启动某种工作的应用程序。电池组件专业版或 App2SD 是这类应用程序的好例子。对于此类型,必须在 Manifest 文件中注册 BroadcastReceiver。

第二类 的例子是一些事件,它们标志着应用程序可能依赖的环境发生了变化。假设您的应用程序依赖于已建立的蓝牙连接。你必须对状态变化做出反应——但仅限于当你的应用程序处于活动状态时。在这种情况下,不需要静态注册的广播接收器。动态注册的更合理。

还有一些事件甚至不允许静态注册。这方面的一个例子是每分钟广播一次的 Inent.ACTION _ TIME _ TICK 事件。这是一个明智的决定,因为静态接收器将不必要地消耗电池。