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
相关产品推荐
相关产品推荐

