This article describes how to use Paho Android Service to connect to IoT Platform and exchange messages with IoT Platform.

Prerequisites

A product and a device are created in the IoT Platform console.

For more information, see Create a product and Create a device.

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 the development environment

In this example, Android Studio of version 3.5.1 and Gradle of version 3.5.1 are used.

Visit the Android Studio official website to download Android Studio. For more information about Android development, see the Android Studio official documentation.

Install Paho Android Client

  1. Create an Android project.
  2. In the Gradle file, add the Paho Android Client dependencies. In this example, Paho Android Client 1.1.1 is used. You need to 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'
      }
  3. 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" />

Connect to IoT Platform

  1. Click AiotMqttOption.java to obtain the source code provided by Alibaba Cloud to calculate the MQTT connection parameters.

    The AiotMqttOption.java file defines the AiotMqttOption class.

    • Prototype
      class AiotMqttOption
    • Description

      Calculates the MQTT connection parameters username, password, and clientid.

    • Members
      Type Method
      public AiotMqttOption getMqttOption(String productKey, String deviceName, String deviceSecret)

      You can call this method to calculate the username, password, and clientid parameters based on the productKey, deviceName, and deviceSecret of the device.

      public String getUsername()

      You can call this method to obtain the MQTT connection parameter username.

      public String getPassword()

      You can call this method to obtain the MQTT connection parameter password.

      public String getClientid()

      You can call this method to obtain the MQTT connection parameter clientid.

  2. Import the AiotMqttOption.java file into the Android project.
  3. 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 parameters that are used to establish an MQTT connection to IoT Platform.

    This section provides the development instructions and sample code.

    • Calculate 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. */
      MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
      mqttConnectOptions.setUserName(userName);
      mqttConnectOptions.setPassword(passWord.toCharArray());
    • Connect 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 by using 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. Write 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 communication topics, see What is a topic?

    • Write 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.

  4. Compile the project.

Demo

The demo code demonstrates how to connect a device to IoT Platform.

  1. Download the demo package and decompress it.
  2. Import aiot-android-demo into Android Studio.
  3. 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 the values of the productKey, deviceName, and deviceSecret parameters with your device certificate information.
    • Replace cn-shanghai in final String host = "tcp://" + PRODUCTKEY + ".iot-as-mqtt.cn-shanghai.aliyuncs.com:443"; with the ID of the region where your device resides. For more information about region IDs, see Regions and zones.
  4. 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

    Log on to the IoT Platform console.View device status and logs.

    • Choose Devices > Devices. You can find that the status of the device is Online.
    • Choose Maintenance > Device Log to view logs on the Cloud run log and Device local log tabs. For more information, see IoT Platform logs and Local device logs.

      If the Mqtt5App program is run, you can view the reported custom properties in the log details.

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 about the error codes that may be returned by IoT Platform, see Troubleshooting.