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

Android 14(SDK34)动态注册广播接收器报SecurityException解决

解决Android 14(SDK 34)动态注册BroadcastReceiver的SecurityException错误

问题背景

原有动态注册BroadcastReceiver的代码在SDK版本低于34时运行正常,但升级到Android 14(SDK 34)后抛出如下SecurityException:

java.lang.SecurityException: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts

原注册逻辑:通过包名拼接的自定义action注册接收器,收到广播后自动注销并启动主页面。

错误原因

Android 14(API 34)新增强制安全规则:非系统专属的广播接收器,必须明确声明是否允许其他应用触发,需通过RECEIVER_EXPORTED或RECEIVER_NOT_EXPORTED标记指定接收器的暴露状态。

解决方案

根据广播的使用场景选择对应标记,再修改注册代码兼容高低版本:

1. 确定广播使用范围

  • 如果仅当前应用内部收发(比如你的SYNC_NOTIFY是应用内部同步通知):用RECEIVER_NOT_EXPORTED,这是更安全的选择,避免其他应用恶意触发。
  • 如果需要允许其他应用触发:用RECEIVER_EXPORTED,你的action已用包名拼接,唯一性有保障,无需额外调整。

2. 修改注册代码

针对Android 14及以上版本添加标记参数,低版本沿用原有逻辑:

private void registerReceiver() {
    try {
        IntentFilter intentFilter = new IntentFilter(Config.getUCHAction(getApplicationContext(), SYNC_NOTIFY));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // 对应Android 14,API 34
            // 根据场景选择RECEIVER_NOT_EXPORTED或RECEIVER_EXPORTED
            registerReceiver(syncStatusReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
        } else {
            // 低版本无需指定标记
            registerReceiver(syncStatusReceiver, intentFilter);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

也可以兼容到Android 13(API 33),该版本已支持这两个标记,只是Android 14强制要求:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // Android 13,API 33
    registerReceiver(syncStatusReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:07:41