Android API26+下,未知接收方时如何跨应用发送广播?
Android 8.0+ 通过PendingIntent向未知接收器发送广播的可行方案
从Android 8.0(API 26)开始,系统对PendingIntent.getBroadcast做了限制,要求通过PendingIntent发送广播时必须在Intent里指定接收器的组件名称。但如果不确定有没有应用托管目标接收器,还是有几种可行的办法:
靠包名筛选构建显式广播
要是你知道目标接收器所在应用的包名,哪怕不清楚具体类名,可以通过PackageManager遍历该包下的所有广播接收器,再逐个构建显式Intent来创建PendingIntent。示例代码:val packageName = "com.target.app" val pm = context.packageManager val intent = Intent("com.target.action") val resolveInfoList = pm.queryBroadcastReceivers(intent, PackageManager.GET_RESOLVED_FILTER) for (resolveInfo in resolveInfoList) { if (resolveInfo.activityInfo.packageName == packageName) { val componentName = ComponentName(packageName, resolveInfo.activityInfo.name) val explicitIntent = Intent(intent).setComponent(componentName) val pendingIntent = PendingIntent.getBroadcast(context, 0, explicitIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) // 后续使用这个pendingIntent即可 break } }这种方式能精准定位目标应用内的接收器,但前提是你得知道准确的包名。
场景允许的话用系统广播替代
如果你的广播属于系统级通用行为,可以考虑用系统预定义的广播Action(比如ACTION_BOOT_COMPLETED),这类广播在API 26+仍然允许隐式发送,但要记得声明相关权限。不过这种方法只适用于符合系统广播场景的需求。通过自身动态接收器转发广播
你可以在自己的应用里注册一个动态广播接收器,先创建指向这个接收器的PendingIntent,当接收器收到广播后,再用隐式广播转发给其他应用的接收器。步骤如下:- 动态注册接收器:
val receiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { intent?.let { // 转发隐式广播给其他应用 context?.sendBroadcast(it) } } } context.registerReceiver(receiver, IntentFilter("com.your.custom.action"))- 创建指向自身接收器的
PendingIntent:
val pendingIntent = PendingIntent.getBroadcast(context, 0, Intent("com.your.custom.action"), PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)这种方法绕开了
PendingIntent的限制,但要注意自身应用在广播触发时得处于活跃状态,不然动态接收器可能会被系统回收。
内容的提问来源于stack exchange,提问作者mohammad fakhraee
相关产品推荐
相关产品推荐

