发送广播给静态接收器
背景
Android 8.0
——从 Android 8.0(API 级别 26)开始,系统对清单声明的接收器施加了额外的限制。如果您的应用以 Android 8.0 或更高版本为目标平台,那么对于大多数隐式广播(没有明确针对您的应用的广播),您不能使用清单来声明接收器。当用户正在活跃地使用您的应用时,您仍可使用上下文注册的接收器。
方法一:
网上大多数的方法。
1.在发送的广播 intent 上设置好接收方的包名信息
var intent = Intent("com.hgw.test.diyBroadcast")
intent.component = ComponentName("com.example.myapplication2","com.example.myapplication2.MyReceiver")
sendBroadcast(intent)
1.结果,没有反应??
看log
2022-07-17 19:47:31.050 1740-1790/? W/WakePathChecker: MIUILOG-AutoStart, Service/Provider/Broadcast Reject userId= 0 caller= com.example.myapplication callee= com.example.myapplication2 classname=com.example.myapplication2.MyReceiver action=com.hgw.test.diyBroadcast wakeType=2
2022-07-17 19:47:31.050 1740-1790/? W/BroadcastQueueInjector: Unable to launch app com.example.myapplication2/10329 for broadcast Intent { act=com.hgw.test.diyBroadcast flg=0x10 cmp=com.example.myapplication2/.MyReceiver }: process is not permitted to weak path
网上查资料得知:
我的测试手机是小米手机,并且小米在应用上添加了一个设置“自启动”,需要把这个开关打开才能接受到广播。(暂时不知如何用代码上打开这个开关)
2.打开“自启动”开关后
如果还是没有反应的话,就改一下intent如下:
var intent = Intent("com.hgw.test.diyBroadcast")
intent.component = ComponentName("com.example.myapplication2","com.example.myapplication2.MyReceiver")
intent.addFlags(0x01000000);
sendBroadcast(intent)
据说是在两个不同包之间发广播的话就需要添加这个flag,但是我这边明明是两个不同包间发广播,却不需要加这个flag
参考链接: 解决Android 8.0及以上系统接收不到广播的问题
方法二:
上面方法是能明确接收方的包名才能发出的广播,对于不能明确包名的也就是需要隐式发送广播的,如下:
val action = "com.hgw.test.diyBroadcast"
val completeIntent = Intent(action)
completeIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
completeIntent.addFlags(0x01000000) // Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
sendBroadcast(completeIntent)
就多配置一个flag,其中的原因需要分析源码就不在此多做说明了。
各位有兴趣的可以参考一下这些连接:
链接: [ Android源码分析 ] 静态注册在源码中是如何实现的
其他,我自己在研究的时候用都的东西
通过adb发送广播
adb shell am broadcast -a com.android.test --es test_string "this is test string"
连接里面有更加详细的使用方式
参考链接: Android 通过adb shell am broadcast发送广播
广播接收的代码
AndroidManifest.xml
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.hgw.test.diyBroadcast"/>
</intent-filter>
</receiver>
MyReceiver
package com.example.myapplication2
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.v("myTest","my02 get action ---> " + intent.action)
}
}