API24模拟器下跨App发送自定义广播未被接收问题排查
自定义跨App广播接收失败排查(API 24)
问题现象
在API 24模拟器环境下,从App A向App B发送自定义广播时,App B无论通过清单声明还是上下文动态注册的方式,都无法接收到该广播;但两种注册方式均能正常接收系统广播。
相关代码
App A 广播发送代码
class MainActivity : AppCompatActivity() { private val TAG = "TestingApp2: MainActivity" override fun onCreate(savedInstanceState: Bundle?) { Log.d(TAG, "onCreate()") super.onCreate(savedInstanceState) val binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.btnSend.setOnClickListener{ Intent().also{ intent.setAction("duke.deviluke.testingapp2.CAN_YOU_HEAR_ME") intent.putExtra("data", "broadcast from app A") sendBroadcast(intent) Log.d(TAG, "Broadcast sent: " + intent.action) } } } }
App B 接收器相关代码
自定义BroadcastReceiver实现
class CustomBroadcast: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { Log.d(TAG, "onReceive()" + intent?.action) StringBuilder().apply { append("Action: ${intent?.action}\n") append("Extra: ${intent?.extras.toString()}") toString().also { Log.d(TAG, it) Toast.makeText(context, it, Toast.LENGTH_SHORT).show() } } } }
清单文件注册配置
<receiver android:name=".CustomBroadcast" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="duke.deviluke.testingapp2.CAN_YOU_HEAR_ME"/> </intent-filter> </receiver>
代码动态注册实现
private val CUSTOM_BROADCAST = "duke.deviluke.testingapp2.CAN_YOU_HEAR_ME" // custom br private val br2: BroadcastReceiver = CustomBroadcast() private val filter2 = IntentFilter(CUSTOM_BROADCAST) private val listenToBroadcastsFromOtherApps2 = true private val receiverFlags2 = if (listenToBroadcastsFromOtherApps2) { ContextCompat.RECEIVER_EXPORTED } else { ContextCompat.RECEIVER_NOT_EXPORTED } private fun registerCustomReceiver() { ContextCompat.registerReceiver(baseContext, br2, filter2, receiverFlags2) } override fun onCreate(savedInstanceState: Bundle?) { Log.d(TAG, "onCreate()") super.onCreate(savedInstanceState) setContentView(R.layout.activity_context) val binding = ActivityContextBinding.inflate(layoutInflater) setContentView(binding.root) registerCustomReceiver() }
排查与解决方案
针对API 24及以上的跨App广播问题,重点检查并调整以下几点:
修正动态注册的兼容性问题
ContextCompat.RECEIVER_EXPORTED是Android 12(API 31)才新增的标记,API 24环境下使用会导致注册失效。修改动态注册代码适配低版本:private fun registerCustomReceiver() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { ContextCompat.registerReceiver(baseContext, br2, filter2, ContextCompat.RECEIVER_EXPORTED) } else { baseContext.registerReceiver(br2, filter2) } }动态注册的接收器不受API 24隐式广播限制,只要App B进程存活就能接收。
处理API 24的隐式广播限制
Android 7.0(API 24)开始,清单注册的接收器无法接收普通隐式广播。解决方式有两种:- 发送显式广播:在App A中指定App B接收器的组件信息,明确目标应用:
binding.btnSend.setOnClickListener{ Intent().also{ intent -> intent.setAction("duke.deviluke.testingapp2.CAN_YOU_HEAR_ME") intent.putExtra("data", "broadcast from app A") // 替换为App B的实际包名和接收器完整类名 intent.component = ComponentName("com.example.appb", "com.example.appb.CustomBroadcast") sendBroadcast(intent) Log.d(TAG, "Broadcast sent: " + intent.action) } } - 保持动态注册:动态注册接收器不受该限制,确保App B在广播发送时处于运行状态即可。
- 发送显式广播:在App A中指定App B接收器的组件信息,明确目标应用:
验证Action一致性
确认App A发送的Action字符串与App B接收器配置的Action完全一致,注意大小写、包名前缀的拼写细节。确认基础配置正确性
- 检查App B清单中接收器的
android:exported="true"已正确设置,允许接收外部应用广播。 - 确认两个应用无自定义权限限制,若有则需在发送广播时添加对应权限声明。
- 检查App B清单中接收器的
调试辅助
- 检查App A的
Broadcast sent日志,确认广播已正常发送。 - 确保App B的
onReceive方法日志逻辑正常,且App B进程处于存活状态。
- 检查App A的
内容的提问来源于stack exchange,提问作者Đào Minh Đức
相关产品推荐
相关产品推荐

