最近遇到一个问题,在作培训时,屡试不爽的广播消息居然存在接收不到广播的状况。经了解后发现,Android O 已对隐式广播添加限制。so,下面总结下 Android 中广播相关。android
广播注册分为静态注册和动态注册,静态注册的广播,能够在程序没被启动时,接收到全局广播消息。而动态注册广播,只有在程序启动后接收广播消息。git
定义好广播消息后,在 AndroidManife.xml 中注册便可,示例中,添加多个 Action。github
<receiver android:name="com.flueky.demo.DemoReceiver" android:permission="com.flueky.demo.permission.Demo_Receiver">
<intent-filter android:priority="999">
<action android:name="com.flueky.app.Demo_Receiver" />
</intent-filter>
<intent-filter>
<action android:name="com.flueky.demo.TEST_RECEIVER1" />
</intent-filter>
<intent-filter>
<action android:name="com.flueky.demo.TEST_RECEIVER2" />
</intent-filter>
</receiver>
复制代码
动态注册指在 Activity 或 Service 中注册,并在 Activity 或 Service 销毁时,须要注销。安全
// 注册广播
registerReceiver(testReceiver, new IntentFilter("com.flueky.demo.TEST_RECEIVER1"));
// 注销广播
unregisterReceiver(testReceiver);
复制代码
因为动态注册的广播能够经过定义内部类的方式实现,所以,动态 注册的广播能够同宿主 Activity 或 Service 进行交互。app
应用发出广播后,全部注册了广播 Action 接收到广播的前后顺序是未知的,则叫发送了无序广播。this
Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
复制代码
应用发出广播后,全部注册了广播 Action 接收到广播的前后顺序是固定的,则叫发送了无序广播。spa
Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendOrderedBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
复制代码
<!--定义优先级-->
<intent-filter android:priority="999">
<action android:name="com.flueky.app.Demo_Receiver" />
</intent-filter>
复制代码
有序广播接收器中传递消息和终止广播以下:code
//非有序广播,不不作下面的操做
if (!isOrderedBroadcast())
return;
// 获取前一个广播传递的消息
Bundle bundle = getResultExtras(true);
String received = bundle.getString("received");
Log.d(TAG, "onReceive: 广播发送 "+(received==null?"null":received));
// 将消息传递给下一个待接收的广播。
bundle.putString("received","已被 send 接收");
setResultExtras(bundle);
// 终止广播
abortBroadcast();
复制代码
发送有序广播和无序广播后,设备中的其余应用只须要注册了接收广播的 Action ,均可以接收到广播消息。为了只在本身应用中接收到广播消息,Google 前后给出了两种方案。其中一种是本地广播,经过 v4 包提供了 LocalBroadcastManager 类,注册、注销和发送广播。xml
// 注册本地广播
LocalBroadcastManager.getInstance(this).registerReceiver(testReceiver, new IntentFilter("com.flueky.demo.TEST_RECEIVER2"));
// 发送本地广播
LocalBroadcastManager.getInstance(this).sendBr oadcast(new Intent("com.flueky.demo.TEST_RECEIVER2"));
// 注销本地广播
LocalBroadcastManager.getInstance(this).unregisterReceiver(testReceiver);
复制代码
本地广播只能经过动态注册的方式,并且由 LocalBroadcastManager 注册的广播只能接收 LocalBroadcastManager 发送的广播。get
在 Android 8.0 以上,使用全局广播必须给广播接收器添加上权限。发送广播时须要使用广播接收器申明的权限,并且,发送广播的应用须要在 AndroidManifest.xml 中申明权限。
具体作法是:发送广播的应用清单文件类容以下:
<!--定义一个权限-->
<permission android:name="com.flueky.demo.permission.Demo_Receiver" android:protectionLevel="signature" />
<!--申明使用这个权限-->
<uses-permission android:name="com.flueky.demo.permission.Demo_Receiver" />
复制代码
代码以下:
// 发送带权限的广播,有序广播和无序广播都行。
Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
复制代码
接收广播应用的清单文件以下:
<!--使用自定义的权限,包括下面注册广播时,使用的 permission 属性。-->
<uses-permission android:name="com.flueky.demo.permission.Demo_Receiver" />
<receiver android:name="com.flueky.demo.DemoReceiver" android:permission="com.flueky.demo.permission.Demo_Receiver">
<intent-filter android:priority="1000">
<action android:name="com.flueky.app.Demo_Receiver" />
</intent-filter>
</receiver>
复制代码
最后,发送广播和接收广播的应用必须使用同一个签名文件。由于自定义权限的安全级别是 signature。
源码地址。
以为有用?那打赏一个呗。去打赏