一、前言

上一篇博文中提到了Android+java+mqtt的使用,但是谷歌上架发现有精确闹钟-USE_EXACT_ALARM和前台服务权限-FOREGROUND_SERVICE_DATA_SYNC共两个错误

后续找到了一个新的库https://github.com/hannesa2/paho.mqtt.android,和上一篇博文中提到的库(https://github.com/mayzs/paho.mqtt.android)用法大致相同,而且新库从Version 4.xx开始不再需要前台服务通知。

二、使用

1、build.gradle

allprojects {
  repositories {
    ...
    maven { url 'https://jitpack.io' }
  }
}
dependencies {
  implementation "com.github.hannesa2:paho.mqtt.android:$latestVersion"//目前最新版是4.4.2
  //去掉上个mqtt库
  //implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
  //implementation 'io.github.mayzs:paho.mqtt.android:1.1.7'
}

2、AndroidManifest.xml

<uses-permission android:name="android.permission.WAKE_LOCK" />
 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
    
    <!--  去掉这些权限:上一篇博文中的参考链接1-Android14+MQTT,Android 14添加权限  -->
<!--    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />-->
<!--    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />-->
<!--    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />-->
<!--    <uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
 
<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
   
    <!--  去掉这些权限:上一篇博文中的参考链接1-Android14+MQTT,Android 14添加权限  -->
    <!--        <service-->
        <!--        android:name=".MqttService"-->
        <!--        android:enabled="true"-->
        <!--        android:exported="true"-->
        <!--        android:foregroundServiceType="dataSync"/>-->
</application>

3、MqttManager类

大致相同,只是不用设置前台服务通知,也就是可以去掉

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationHelper notificationHelper = new NotificationHelper(this);
            Notification notification = notificationHelper.createNotification();
            mqttAndroidClient.setForegroundService(notification, 1);
}

位置:

img

另外,使用新的Mqtt库编译时捕获MqttException均会报错,需要都改成Exception

try {
    client.subscribe(topic, qos, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.d(TAG, "订阅成功: " + topic);
                }
​
                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.e(TAG, "订阅失败: " + topic + ", 原因: " + exception.getMessage());
                }
            });
} catch (Exception e) {
    Log.e(TAG, "订阅主题时发生异常: " + e.getMessage());
    e.printStackTrace();
}

三、其他

遇到的问题:

在子线程创建了对话框(包括设置标题、消息、按钮和监听器),只有显示show()时才在主线程runOnUiThread中调用,导致点击取消和确定按钮均无法进入对应的监听器,对话框一直存在。后续也一直无法更新UI。

原因和解决办法:

如果用到对话框,需要确保整个对话框的创建和显示都是在主线程runOnUiThread 中进行的。其中所有的对话框构建逻辑,包括设置标题、消息、按钮和监听器。

activity.runOnUiThread(() -> {
    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    builder.setTitle("标题")
        .setMessage("文本")
        .setPositiveButton("同意", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //同意时执行的操作
            }
        })
        .setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //拒绝时执行的操作
            }
        })
        .show();
});
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐