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

Android 14下MQTT接收时RECEIVER相关SecurityException问题求助

Android 14下MQTT接收数据触发SecurityException的解决办法

问题描述

从MQTT接收数据时出现致命异常,已将自身广播注册代码改为传入RECEIVER_NOT_EXPORTED的新写法,但问题仍存在。代码在Android 14以下版本运行正常,相关代码及报错日志如下:

自行注册的广播代码

ContextCompat.registerReceiver(this,mMessageReceiver,
                new IntentFilter(AppConstants.INTENT_FILTERS.DASHBOARD_MESSAGE),
                ContextCompat.RECEIVER_NOT_EXPORTED);

报错日志

java.lang.SecurityException: com.example.dummy: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts
                                        at android.os.Parcel.createExceptionOrNull(Parcel.java:3057)
                                        at android.os.Parcel.createException(Parcel.java:3041)
                                        at android.os.Parcel.readException(Parcel.java:3024)
                                        at android.os.Parcel.readException(Parcel.java:2966)
                                        at android.app.IActivityManager$Stub$Proxy.registerReceiverWithFeature(IActivityManager.java:5684)
                                        at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1852)
                                        at android.app.ContextImpl.registerReceiver(ContextImpl.java:1792)
                                        at android.app.ContextImpl.registerReceiver(ContextImpl.java:1780)
                                        at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:755)
                                        at info.mqtt.android.service.ping.AlarmPingSender.start(AlarmPingSender.kt:55)
                                        at org.eclipse.paho.client.mqttv3.internal.ClientState.connected(ClientState.java:1214)
                                        at org.eclipse.paho.client.mqttv3.internal.ClientState.notifyReceivedAck(ClientState.java:1050)
                                        at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:151)
                                        at java.lang.Thread.run(Thread.java:1012)
                                    Caused by: android.os.RemoteException: Remote stack trace:
                                        at com.android.server.am.ActivityManagerService.registerReceiverWithFeature(ActivityManagerService.java:13927)
                                        at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2570)
                                        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2720)
                                        at android.os.Binder.execTransactInternal(Binder.java:1339)
                                        at android.os.Binder.execTransact(Binder.java:1275)

问题根源

从报错堆栈可以明确看到:异常并非来自你自己注册的广播接收器,而是MQTT Android客户端内部的AlarmPingSender类——它在注册ping检测广播时,没有按照Android 14的要求指定RECEIVER_EXPORTED或RECEIVER_NOT_EXPORTED标记,这才是触发SecurityException的核心原因。

解决方法

方法一:升级MQTT Android客户端库

官方已经在后续版本中修复了这个适配问题,直接将info.mqtt.android:mqtt-android-client依赖升级到4.3.0及以上版本即可,新版本会自动处理广播注册的标记参数。

方法二:自定义AlarmPingSender(无法升级库时使用)

如果暂时无法升级依赖,可以自定义PingSender类,重写广播注册逻辑,手动添加RECEIVER_NOT_EXPORTED标记:

自定义PingSender代码

public class CustomAlarmPingSender extends AlarmPingSender {
    private final Context context;

    public CustomAlarmPingSender(Context context) {
        super(context);
        this.context = context;
    }

    @Override
    public void start(ClientState clientState) {
        super.clientState = clientState;
        Intent intent = new Intent(ACTION_PING_SENDER);
        intent.setPackage(context.getPackageName());
        pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
        
        // 替换原注册逻辑,添加RECEIVER_NOT_EXPORTED参数
        context.registerReceiver(pingReceiver, new IntentFilter(ACTION_PING_SENDER), ContextCompat.RECEIVER_NOT_EXPORTED);
        
        schedule(clientState.getKeepAlive());
    }
}

初始化MQTT客户端时指定自定义PingSender

MqttAndroidClient client = new MqttAndroidClient(context, serverUri, clientId);
// 设置自定义的PingSender
client.setPingSender(new CustomAlarmPingSender(context));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:13:15