This topic describes how to use Paho Android Service to connect a device to IoT Platform and enable messaging.
Prerequisites
A product and a device are created in an instance in the IoT Platform console. The device certificate and an MQTT endpoint are obtained. The device certificate information includes the ProductKey, DeviceName, and DeviceSecret. For more information, see the following topics:
Background information
Paho Android Service is a Message Queuing Telemetry Transport (MQTT) client that is developed based on the Paho MQTT library for Java.
Prepare a development environment
In this example, Android Studio of version 3.5.1 and Gradle of version 3.5.1 are used.
Visit the official Android Studio website to download Android Studio. For more information about Android development, see the official Android Studio documentation.
Install Paho Android Client
- Create an Android project. Important If the value of the targetSdkVersion parameter is greater than 30 in the build.gradle file, change the value to a value that is less than or equal to 30.
- In the Gradle file, add the Paho Android Client dependencies. In this example, Paho Android Client 1.1.1 is used. You must add the following dependencies.
- In the build.gradle file, add the address of the Paho repository. In this example, the release repository is used.
repositories { maven { url "https://repo.eclipse.org/content/repositories/paho-releases/" } }
- In the build.gradle file, add the Paho Android Service dependencies. In this example, Paho Android Service 1.1.1 is used. It is based on 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' }
- In the build.gradle file, add the address of the Paho repository. In this example, the release repository is used.
- To bind an app to Paho Android Service, add the following information to the AndroidManifest.xml file.
- Declare the following service:
<!-- Mqtt Service --> <service android:name="org.eclipse.paho.android.service.MqttService"> </service>
- Add the permissions required by 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" />
- Declare the following service:
Connect a device to IoT Platform
- Download the android_sameple_code.zip package and decompress the package to obtain the AiotMqttOption.java file provided by Alibaba Cloud. This way, you can obtain the MQTT connection parameters.
The AiotMqttOption.java file defines the AiotMqttOption class.
- Prototype
class AiotMqttOption
- Description
You can use this class to obtain the following MQTT connection parameters: username, password and clientid.
- Members
Type Method public AiotMqttOption getMqttOption(String productKey, String deviceName, String deviceSecret)
Calculates the values of the username, password, and clientid parameters based on the values of the productKey, deviceName, and deviceSecret parameters.
public String getUsername()
Obtains the username parameter.
public String getPassword()
Obtains the password parameter.
public String getClientid()
Obtains the clientid parameter.
- Prototype
- Import the AiotMqttOption.java file into the Android project.
- In the Android project, add a program file that can connect a device to IoT Platform.
You must write a program to use the AiotMqttOption class in the AiotMqttOption.java file to calculate the values of the parameters that are required to establish an MQTT connection to IoT Platform.
This section provides the development instructions and sample code.
- Calculate the values of the MQTT connection parameters clientId, username, and password. Configure the username and password parameters in the MqttConnectOptions object.
final private String PRODUCTKEY = "a11xsrW****"; final private String DEVICENAME = "paho_android"; final private String DEVICESECRET = "tLMT9QWD36U2SArglGqcHCDK9rK9****"; /* Obtain the MQTT connection parameters clientId, username, and 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(); } /* Create an MqttConnectOptions object and configure the username and password parameters. */ MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); mqttConnectOptions.setUserName(userName); mqttConnectOptions.setPassword(passWord.toCharArray());
- Connect the client to IoT Platform.
Create an MqttAndroidClient object and configure the callback. Use the mqttConnectOptions object to call the connect() method to establish the connection.
/* Create an MqttAndroidClient object and configure the callback. */ 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"); } }); /* Establish a connection to IoT Platform over 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 messages. Define the publishMessage() method to publish messages with the specified payload to the
/${prodcutKey}/${deviceName}/user/update
topic.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(); } }
For more information about topics, see Topics.
- Define the subscribeTopic() method to subscribe to a specified topic and obtain messages from IoT Platform.
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(); } }
For more information about the communication methods of devices, servers, and IoT Platform, see Overview.
- Calculate the values of the MQTT connection parameters clientId, username, and password. Configure the username and password parameters in the MqttConnectOptions object.
- Compile the project.
Sample code
The following sample code shows how to connect to IoT Platform.
- Download the demo package and decompress it.
- Import aiot-android-demo to Android Studio.
- In the app/src/main/java/com.linkkit.aiot_android_demo directory, replace the device information with your device information in the MainActivity file.
- Replace PRODUCTKEY, DEVICENAME, and DEVICESECRET with your device certificate information.
- Replace .iot-as-mqtt.cn-shanghai.aliyuncs.com:443 in the
final String host = "tcp://" + PRODUCTKEY + ".iot-as-mqtt.cn-shanghai.aliyuncs.com:443";
code with the endpoint of your instance.- If you use an Enterprise Edition instance or a public instance of the new version, specify
final String host = "tcp://" + "${MQTT endpoint of your instance}"
.To obtain the MQTT endpoint, perform the following steps: Log on to the IoT Platform console. On the Overview page, click the card of the instance that you want to manage. In the upper-right corner of the Instance Details page, click View Development Configurations. For more information, see View the endpoint of an instance.
- If you use a public instance of the old version, perform the following step:
Replace cn-shanghai in the code with the ID of the region where your device resides. For more information about region IDs, see Supported regions.
- If you use an Enterprise Edition instance or a public instance of the new version, specify
- Build and run the demo. After the demo is run, you can view the local logs in 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
In the IoT Platform console, you can view the device status and logs.
- Choose . The Devices page shows that the device is in Online state.
- Choose IoT Platform logs and Local device logs. . Then, click the Cloud run log or Device local log tab to view logs. For more information, see
Error codes
If a device fails to establish an MQTT connection to IoT Platform, you can troubleshoot the issue based on the error code. For more information, see Troubleshooting.