本文介绍如何使用Paho Android Service接入阿里云物联网平台,并进行数据收发。
前提条件
已在物联网平台控制台,对应实例下,创建产品和设备,并获取MQTT接入域名和设备证书信息(ProductKey、DeviceName和DeviceSecret)。具体操作,请参见:
背景信息
Paho Android Service是一个基于Java语言的Paho MQTT库开发的MQTT客户端服务包。
准备开发环境
本示例使用的Android Studio版本为3.5.1,gradle版本为3.5.1。
请访问Android Studio官网下载Android Studio。Android开发相关教程,请查看Android Studio官方文档。
安装Paho Android Client
- 创建一个新的Android工程。
重要 在应用 build.gradle文件中的 targetSdkVersion需要小于或等于30。若不符合要求,请进行修正。
- 在gradle文件中,添加Paho Android Client依赖。本示例使用1.1.1版本的PahoAndroidClient,需添加以下依赖:
- 在工程build.gradle中,添加Paho仓库地址。本示例使用release仓库。
repositories { maven { url "https://repo.eclipse.org/content/repositories/paho-releases/" } }
- 在应用build.gradle中,添加Paho Android Service。本示例中,使用1.1.1 release版本的Paho服务,底层基于paho.client.mqttv3-1.1.0版本。
dependencies { implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0' implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' }
- 在工程build.gradle中,添加Paho仓库地址。本示例使用release仓库。
- 为了使App能够绑定到Paho Android Service,需要在AndroidManifest.xml中添加以下信息:
- 声明以下服务:
<!-- Mqtt Service --> <service android:name="org.eclipse.paho.android.service.MqttService"> </service>
- 添加Paho MQTT Service所需的权限。
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- 声明以下服务:
接入物联网平台
- 下载android_sameple_code.zip,然后解压获取阿里云提供的计算MQTT连接参数所需的源码文件AiotMqttOption.java。
AiotMqttOption.java文件中定义了AiotMqttOption()类,类说明如下:
- 原型:
class AiotMqttOption
- 功能:
用于计算设备接入物联网平台的MQTT连接参数username、password和clientid。
- 成员:
类型定义 方法描述 public AiotMqttOption getMqttOption(String productKey, String deviceName, String deviceSecret)
根据设备的productKey、deviceName和deviceSecret计算出MQTT连接参数username、password和clientid。
public String getUsername()
用于获取MQTT建连参数username。
public String getPassword()
用于获取MQTT建连参数password。
public String getClientid()
用于获取MQTT建连参数clientid。
- 原型:
- 将AiotMqttOption.java导入Android项目。
- 在Android项目中,添加实现设备接入物联网平台的程序文件。
您需编写程序调用AiotMqttOption.java中的AiotMqttOption()类计算MQTT连接参数,实现接入物联网平台和通信。
开发说明和示例代码如下:
- 计算MQTT连接参数clientId、username和password,并将username和password设置到MqttConnectOptions对象中。
final private String PRODUCTKEY = "a11xsrW****"; final private String DEVICENAME = "paho_android"; final private String DEVICESECRET = "tLMT9QWD36U2SArglGqcHCDK9rK9****"; /* 获取MQTT连接信息clientId、username、password。 */ AiotMqttOption aiotMqttOption = new AiotMqttOption().getMqttOption(PRODUCTKEY, DEVICENAME, DEVICESECRET); if (aiotMqttOption == null) { Log.e(TAG, "device info error"); } else { clientId = aiotMqttOption.getClientId(); userName = aiotMqttOption.getUsername(); passWord = aiotMqttOption.getPassword(); } /* 创建MqttConnectOptions对象,并配置username和password。 */ MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); mqttConnectOptions.setUserName(userName); mqttConnectOptions.setPassword(passWord.toCharArray());
- 接入物联网平台。
创建一个MqttAndroidClient对象,设置回调接口,然后使用mqttConnectOptions调用connect方法,即可建立连接。
/* 创建MqttAndroidClient对象,并设置回调接口。 */ mqttAndroidClient = new MqttAndroidClient(getApplicationContext(), host, clientId); mqttAndroidClient.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { Log.i(TAG, "connection lost"); } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { Log.i(TAG, "topic: " + topic + ", msg: " + new String(message.getPayload())); } @Override public void deliveryComplete(IMqttDeliveryToken token) { Log.i(TAG, "msg delivered"); } }); /* 建立MQTT连接。 */ try { mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Log.i(TAG, "connect succeed"); subscribeTopic(SUB_TOPIC); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Log.i(TAG, "connect failed"); } }); } catch (MqttException e) { e.printStackTrace(); }
- 发布消息。封装publish方法,用于向Topic
/${prodcutKey}/${deviceName}/user/update
发布指定payload的消息。public void publishMessage(String payload) { try { if (mqttAndroidClient.isConnected() == false) { mqttAndroidClient.connect(); } MqttMessage message = new MqttMessage(); message.setPayload(payload.getBytes()); message.setQos(0); mqttAndroidClient.publish(PUB_TOPIC, message,null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Log.i(TAG, "publish succeed!"); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Log.i(TAG, "publish failed!"); } }); } catch (MqttException e) { Log.e(TAG, e.toString()); e.printStackTrace(); } }
通信Topic介绍,请参见什么是Topic。
- 封装subscribe方法,用于实现订阅指定Topic,获取云端下发的消息。
public void subscribeTopic(String topic) { try { mqttAndroidClient.subscribe(topic, 0, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Log.i(TAG, "subscribed succeed"); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Log.i(TAG, "subscribed failed"); } }); } catch (MqttException e) { e.printStackTrace(); } }
关于设备、服务器和物联网平台的通信方式介绍,请参见通信方式概述。
- 计算MQTT连接参数clientId、username和password,并将username和password设置到MqttConnectOptions对象中。
- 编译项目。
示例Demo
使用Demo代码程序接入物联网平台。
- 下载代码Demo包,并解压缩。
- 将aiot-android-demo导入Android Studio。
- 在app/src/main/java/com.linkkit.aiot_android_demo下的MainActivity文件中,替换设备信息为您的设备信息。
- 替换PRODUCTKEY、DEVICENAME和DEVICESECRET的值为您的设备证书信息。
- 修改代码
final String host = "tcp://" + PRODUCTKEY + ".iot-as-mqtt.cn-shanghai.aliyuncs.com:443";
中的值为对应的接入域名。
- 构建应用,并运行。
运行成功后,可在Logcat中查看本地日志。
2019-12-04 19:44:01.824 5952-5987/com.linkkit.aiot_android_demo W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without... 2019-12-04 19:44:01.829 5952-5987/com.linkkit.aiot_android_demo D/EGL_emulation: eglCreateContext: 0xec073240: maj 3 min 0 rcv 3 2019-12-04 19:44:01.830 5952-5987/com.linkkit.aiot_android_demo D/EGL_emulation: eglMakeCurrent: 0xec073240: ver 3 0 (tinfo 0xec09b470) 2019-12-04 19:44:01.852 5952-5987/com.linkkit.aiot_android_demo W/Gralloc3: mapper 3.x is not supported 2019-12-04 19:44:01.854 5952-5987/com.linkkit.aiot_android_demo D/HostConnection: createUnique: call ... ... 2019-12-04 19:44:01.860 5952-5987/com.linkkit.aiot_android_demo D/eglCodecCommon: allocate: Ask for block of size 0x1000 2019-12-04 19:44:01.861 5952-5987/com.linkkit.aiot_android_demo D/eglCodecCommon: allocate: ioctl allocate returned offset 0x3ff706000 size 0x2000 2019-12-04 19:44:01.897 5952-5987/com.linkkit.aiot_android_demo D/EGL_emulation: eglMakeCurrent: 0xec073240: ver 3 0 (tinfo 0xec09b470) 2019-12-04 19:44:02.245 5952-6023/com.linkkit.aiot_android_demo D/AlarmPingSender: Register alarmreceiver to MqttServiceMqttService.pingSender.a11xsrW****.paho_android|timestamp=1575459841629,_v=sdk-android-1.0.0,securemode=2,signmethod=hmacsha256| 2019-12-04 19:44:02.256 5952-6023/com.linkkit.aiot_android_demo D/AlarmPingSender: Schedule next alarm at 1575459902256 2019-12-04 19:44:02.256 5952-6023/com.linkkit.aiot_android_demo D/AlarmPingSender: Alarm scheule using setExactAndAllowWhileIdle, next: 60000 2019-12-04 19:44:02.272 5952-5952/com.linkkit.aiot_android_demo I/AiotMqtt: connect succeed 2019-12-04 19:44:02.301 5952-5952/com.linkkit.aiot_android_demo I/AiotMqtt: subscribed succeed
登录物联网平台控制台,在对应实例下,可查看设备状态和日志。
错误码
如果设备通过MQTT协议接入物联网平台失败,请根据错误码排查问题。服务端错误码说明,请参见错误排查。