You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android如何检测其他应用中指定BroadcastReceiver是否存在?

问题:Android 11+ 下检测第三方BroadcastReceiver存在性失败

我尝试向其他应用的CmdReceiver发送广播,同时需要检测该接收器是否存在(不存在则调用showDialogNotFound())。Android 10及以下通过PackageManager.getReceiverInfo()可以正常检测,但Android 11+因安全限制改用有序广播的方式,即使接收器存在,仍会触发showDialogNotFound(),相关代码如下:

原检测代码(Android 11+分支)

val filter = IntentFilter()
filter.addAction("android.intent.action.MAIN")
val cmdIntent = Intent()
cmdIntent.setComponent(
    ComponentName(
        pkgName,
        pkgName + ".CmdReceiver"
    )
)
cmdIntent.flags = Intent.FLAG_RECEIVER_FOREGROUND
cmdIntent.flags = Intent.FLAG_INCLUDE_STOPPED_PACKAGES
cmdIntent.putExtra("isOrderedBroadcast", true)
sendOrderedBroadcast(cmdIntent, null, object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val result = getResultCode()
        val resultData = getResultData()
        if (result == -1 && resultData == "ReceiverFound") {
            Log.d("MainActivity", "BroadcastReceiver exists!")
            showDialogFound()
        } else {
            showDialogNotFound()
        }
    }
}, null, Activity.RESULT_CANCELED, null, null)

目标应用CmdReceiver的处理代码(Java)

Boolean isOrderedBroadcast = intent.getBooleanExtra("isOrderedBroadcast", false);
if (isOrderedBroadcast) {
    setResultCode(-1);
    setResultData("ReceiverFound");
}

问题原因&修正方案

1. Intent Flags赋值错误

连续两次给cmdIntent.flags赋值会导致前一个flag被覆盖,正确的多flag设置需要用按位或合并:

cmdIntent.flags = Intent.FLAG_RECEIVER_FOREGROUND or Intent.FLAG_INCLUDE_STOPPED_PACKAGES

2. 目标接收器的导出属性缺失

Android 12+对跨应用组件调用的权限限制更严格,CmdReceiver必须在Manifest中显式设置android:exported="true",否则其他应用无法访问:

<receiver
    android:name=".CmdReceiver"
    android:exported="true">
    <!-- 显式调用时intent-filter非必须,若需匹配特定action可添加 -->
</receiver>

3. 有序广播的结果判断逻辑优化

  • 自定义初始结果码(避免与系统默认码冲突),简化判断逻辑
  • 移除冗余的isOrderedBroadcast额外参数,接收器可直接通过isOrderedBroadcast()方法判断

修正后的检测代码:

val cmdIntent = Intent()
cmdIntent.setComponent(ComponentName(pkgName, pkgName + ".CmdReceiver"))
cmdIntent.flags = Intent.FLAG_RECEIVER_FOREGROUND or Intent.FLAG_INCLUDE_STOPPED_PACKAGES

sendOrderedBroadcast(cmdIntent, null, object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (getResultCode() == -1) {
            Log.d("MainActivity", "BroadcastReceiver exists!")
            showDialogFound()
        } else {
            showDialogNotFound()
        }
    }
}, null, -2, null, null)

修正后的目标接收器代码:

if (isOrderedBroadcast()) {
    setResultCode(-1);
}

内容的提问来源于stack exchange,提问作者IsHacker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 06:12:45