Use the Paho Android Service to connect an Android app to IoT Platform and send and receive messages.
Prerequisites
In the IoT Platform console , for the corresponding instance, create a product and a device, and obtain the MQTT access domain name and the device certificate information (ProductKey, DeviceName, and DeviceSecret). For more information, see:
Overview
Paho Android Service is an MQTT client service built on the Eclipse Paho MQTT library for Java.
Development environment
This example uses Android Studio 3.5.1 with Gradle 3.5.1.
Download Android Studio from the official Android Studio website.
Install the Paho Android client
- Create a new Android project.
Important The targetSdkVersion in the application's build.gradle file must be 30 or lower. If it is higher, you must modify it.
- Add the Paho Android Client 1.1.1 dependency to your Gradle files:
- In the project's build.gradle file, add the Paho release repository URL.
repositories { maven { url "https://repo.eclipse.org/content/repositories/paho-releases/" } } - In the application's build.gradle file, add the Paho Android Service (1.1.1) and MQTT client (1.1.0) dependencies.
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 project's build.gradle file, add the Paho release repository URL.
- Add the following entries to AndroidManifest.xml:
- Declare the MQTT service:
<!-- Mqtt Service --> <service android:name="org.eclipse.paho.android.service.MqttService"> </service> - Add the required permissions.
<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 MQTT service:
Connect to IoT Platform
- Download android_sample_code.zip and extract the AiotMqttOption.java file, which calculates MQTT connection parameters.
The AiotMqttOption.java file defines the AiotMqttOption class:
- Prototype:
class AiotMqttOption Features
Calculates the username, password, and clientid parameters for an MQTT connection to IoT Platform.
- Members:
Type definition Method description public AiotMqttOption getMqttOption(String productKey, String deviceName, String deviceSecret)Calculates the MQTT username, password, and clientid from the device's productKey, deviceName, and deviceSecret.
public String getUsername()Gets the MQTT username.
public String getPassword()Gets the MQTT password.
public String getClientid()Gets the MQTT clientid.
- Prototype:
- Import AiotMqttOption.java into your Android project.
- Add code to connect the device to IoT Platform.
Call the AiotMqttOption class in AiotMqttOption.java to calculate MQTT connection parameters and connect to IoT Platform.
Development instructions and sample code:
- Calculate the MQTT connection parameters clientId, username, and password, and set username and password in the MqttConnectOptions object.
final private String PRODUCTKEY = "a11xsrW****"; final private String DEVICENAME = "paho_android"; final private String DEVICESECRET = "tLMT9QWD36U2SArglGqcHCDK9rK9****"; /* Obtain the MQTT connection information: 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. */ MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); mqttConnectOptions.setUserName(userName); mqttConnectOptions.setPassword(passWord.toCharArray()); - Connect to IoT Platform.
Create an MqttAndroidClient object, set the callback, and call connect with MqttConnectOptions.
/* Create an MqttAndroidClient object and set 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 an MQTT connection. */ 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 a message. Call publish to send a payload to the
/${productKey}/${deviceName}/user/updatetopic.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(); } } - Call subscribe to subscribe to a topic and receive 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 information about the communication methods of devices, servers, and IoT Platform, see Overview of communications among devices, IoT platform, and servers.
- Calculate the MQTT connection parameters clientId, username, and password, and set username and password in the MqttConnectOptions object.
- Compile the project.
Run the demo
Run the demo app to verify the connection to IoT Platform.
- Download the demo code package and extract it.
- Import aiot-android-demo into Android Studio.
- In the MainActivity file in app/src/main/java/com.linkkit.aiot_android_demo, replace the placeholder device information with your device credentials.
- Set PRODUCTKEY, DEVICENAME, and DEVICESECRET to your device certificate values.
- Set the host to your endpoint:
final String host = "tcp://" + PRODUCTKEY + ".iot-as-mqtt.cn-shanghai.aliyuncs.com:443";- For new public instances and Enterprise instances, set the host to your instance endpoint:
final String host = "tcp://" + "{your-instance-endpoint}".Log on to the IoT Platform console. On the Instance Overview page, click your instance. On the Instance Details page, click View Development Configuration to obtain the endpoint. View and configure instance endpoints.
- For legacy public instances:
Replace the region code (cn-shanghai) with the region where your device is located. Supported regions.
- For new public instances and Enterprise instances, set the host to your instance endpoint:
- Build and run the application.
After successful execution, check the 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 succeedLog on to the IoT Platform console. In the appropriate instance, you can view the device status and logs.
Choose . The status of the device is Online.
Choose . You can view IoT Platform logs and on-premises device logs. For more information, see IoT Platform logs and On-premises device logs.
Error codes
If the device fails to connect to IoT Platform over MQTT, use the error codes to troubleshoot the issue. For more information about server-side error codes, see Troubleshooting.