Before you connect a device to IoT Platform, the device must pass identity verification. This topic describes how to initialize Link SDK for Android to connect a device to IoT Platform.
Prerequisites
A product and a device are created. For more information, see Create a product and a device.
The Link SDK demo package for Android is downloaded.
The device certificate information and the endpoint to which you want to connect the device are obtained. For more information, see parameter configurations in the Link SDK for Android topic.
Background information
Link SDK for Android allows you to use a DeviceSecret or an IoT Device ID (ID²) to verify the identity of a device.
Use a DeviceSecret to verify a device:
Verification method
Registration method
Description
N/A
A device certificate that includes a ProductKey, a DeviceName, and a DeviceSecret is burned to each device.
Pre-registration
A product certificate that includes a ProductKey and a ProductSecret is burned to all devices of a product.
You must enable the dynamic registration feature for the product.
Dynamic registration allows a device to obtain a DeviceSecret.
Preregistration-free
A product certificate that includes a ProductKey and a ProductSecret is burned to all devices of a product.
You must enable the dynamic registration feature for the product.
Dynamic registration allows devices to obtain a combination of the ClientID and DeviceToken.
NoteFor information about the differences between pre-registration unique-certificate-per-product verification and preregistration-free unique-certificate-per-product verification, see Differences between the verification methods.
Use an ID² to verify a device: An ID² is a trusted identifier for an IoT Platform device. The ID² is tamper-resistant and non-falsifiable.
For information about how to use an ID² to verify a device, see the sample code in the InitManager.java
file.
Unique-certificate-per-device verification
Sample code for the unique-certificate-per-device verification method:
AppLog.setLevel(ALog.LEVEL_DEBUG);
final LinkKitInitParams params = new LinkKitInitParams();
String productKey = "${YourProductKey}";
String deviceName = "${YourDeviceName}";
String deviceSecret = "${YourDeviceSecret}";
String productSecret = "";
// Step 1: Specify the information about a device certificate.
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.productKey = productKey; // The ProductKey of the product.
deviceInfo.deviceName = deviceName; // The DeviceName of the device.
deviceInfo.deviceSecret = deviceSecret; // The DeviceSecret of the device.
deviceInfo.productSecret = productSecret; // The ProductSecret of the product.
params.deviceInfo = deviceInfo;
// Step 2: Specify the global default domain name.
IoTApiClientConfig userData = new IoTApiClientConfig();
params.connectConfig = userData;
// Step 3: Cache the Thing Specification Language (TSL) model.
Map<String, ValueWrapper> propertyValues = new HashMap<>();
/**
* The TSL data is cached in the preceding parameter. You cannot delete or leave this parameter empty. Otherwise, TSL-related features may fail.
* After you call an API operation to submit TSL data, the TSL data is cached.
*/
params.propertyValues = propertyValues;
// Step 4: Configure MQTT parameters.
/**
* The MQTT parameters, such as the endpoint. For more information, see the deviceinfo file.
* The domain name, ProductSecret, and security verification method.
*/
IoTMqttClientConfig clientConfig = new IoTMqttClientConfig();
clientConfig.receiveOfflineMsg = false;//cleanSession=1 Offline messages cannot be received.
// The information about the Message Queuing Telemetry Transport (MQTT) endpoint.
clientConfig.channelHost = "${YourMqttHostUrl}:8883";
params.mqttClientConfig = clientConfig;
MqttConfigure.pingSenderType = "android"; // Set the heartbeat detection type to android and set the timer type for heartbeat detection to AlarmTImer. This ensures that the heartbeat detection is performed as scheduled when the display is automatically shut down.
// Step 5: Configure advanced features. By default, all advanced features are disabled except for the TSL model feature.
IoTDMConfig ioTDMConfig = new IoTDMConfig();
// By default, the TSL model feature is enabled. After you initialize the TSL model that is requested from IoT Platform, onInitDone is returned.
ioTDMConfig.enableThingModel = true;
// By default, the gateway feature is disabled. After you enable the gateway feature, the gateway module is initialized to obtain the sub-device list of the gateway module from IoT Platform.
ioTDMConfig.enableGateway = false;
// By default, the log push feature is disabled. You can enable this feature.
ioTDMConfig.enableLogPush = false;
params.ioTDMConfig = ioTDMConfig;
// Step 6: Configure a callback function to process downstream messages.
LinkKit.getInstance().registerOnPushListener(new IConnectNotifyListener() {
@Override
public void onNotify(String s, String s1, AMessage aMessage) {
// You can configure the callback function for downstream message processing based on the documentation.
}
@Override
public boolean shouldHandle(String s, String s1) {
return true; // Configure the parameters based on your business requirements and the documentation.
}
@Override
public void onConnectStateChange(String s, ConnectState connectState) {
// The callback for the connection status change of the corresponding connection type. For information about the connection status, see ConnectState in the SDK.
// If the SDK disconnects the device from IoT Platform due to poor network conditions, the SDK automatically attempts to reconnect the device to IoT Platform at intervals of 2 to the power of n (unit: seconds). n is an integer ranging from 0 to 7. The maximum interval is 128s.
}
});
// If you want to verify a device by using the preregistration-free unique-certificate-per-product verification method, the DeviceToken and ClientID are required when you connect the device to IoT Platform.
// Step7: Configure the parameters for the preregistration-free unique-certificate-per-product verification. This feature is disabled by default.
// MqttConfigure.deviceToken = DemoApplication.deviceToken;
// MqttConfigure.clientId = DemoApplication.clientId;
// Step8: Configure parameters that are required to upload files over HTTP/2.
/**
* If you want to upload files to IoT Platform over HTTP/2, you must specify a domain name.
*/
// IoTH2Config ioTH2Config = new IoTH2Config();
// ioTH2Config.clientId = "client-id";
// ioTH2Config.endPoint = "https://" + productKey + ioTH2Config.endPoint;// The endpoint that is used to upload files over HTTP/2 to IoT Platform.
// params.iotH2InitParams = ioTH2Config;
/**
* Initialize the SDK to connect a device to IoT Platform.
* onError The initialization failed. If the initialization fails due to network issues, you must re-initialize the SDK.
* onInitDone The initialization is successful.
*/
LinkKit.getInstance().init(getAppContext(), params, new ILinkKitConnectListener() {
@Override
public void onError(AError error) {
ALog.d(TAG, "onError() called with: error = [" + (error) + "]");
}
@Override
public void onInitDone(Object data) {
ALog.d(TAG, "onInitDone() called with: data = [" + data + "]");
// Device verification is complete and the device is connected. You can run your business as required.
}
});
Unique-certificate-per-product verification
Unique-certificate-per-product verification is also known as dynamic registration. The feature is used to request DeviceSecrects from IoT Platform. Unique-certificate-per-product verification methods can be classified into the following types: preregistration-free and pre-registration. Before you use the feature, make sure that the following prerequisites are met:
Dynamic Registration is turned on for a product that you created in the IoT Platform console.
In the
deviceinfo
file of the demo package, the deviceSecret parameter is left empty and the productSecret is not empty.Step 1 to Step 3 in the sample code are performed.
After a dynamic registration succeeds or fails, close the persistent connection for the dynamic registration. For information about how to close the connection, see Step 4.
To ensure device security, burn a DeviceSecret to a device after you obtain the DeviceSecret by using the unique-certificate-per-product verification method.
The following table describes the differences between the preregistration-free unique-certificate-per-product and pre-registration unique-certificate-per-product verification methods.
Item | Pre-registration | Preregistration-free |
Protocols | MQTT and HTTPS | MQTT |
Regions |
| China (Shanghai) and China (Beijing) |
Returned DeviceSecrets | For more information about how to use a DeviceSecret, see Step 1 in the sample code for unique-certificate-per-device verification. | Burn the ClientID and DeviceToken of a device to the device. This way, the information can be used when you use specific features, such as connecting the device to IoT Platform. For more information, see Step 7 in the sample code for unique-certificate-per-device verification. |
Device registration | You must pre-register the DeviceName of a device in the IoT Platform console. | You do not need to pre-register the DeviceName of a device in the IoT Platform console. |
Usage times |
| Each ProductKey, ProductSecret, and DeviceName can be used to activate up to five physical devices. You can activate the devices in the IoT Platform console at the same time. IoT Platform generates a unique ClientID and DeviceToken for each device. |
For more information about the code, see the DemoApplication.java
file in the demo package.
Sample code for dynamic registration:
String productKey = "${YourProductKey}";
String deviceName = "${YourDeviceName}";
String deviceSecret = "${YourDeviceSecret}";
String productSecret = "";
MqttInitParams initParams = new MqttInitParams(productKey, productSecret, deviceName, deviceSecret, MqttConfigure.MQTT_SECURE_MODE_TLS);
// Step 1: Check whether the unique-certificate-per-product verification method is preregistration-free or pre-registration.
// Case 1: If you set the registerType parameter to regnwl, the preregistration-free unique-certificate-per-product verification method is used and you do not need to create a device.
// Case 2: If you leave the registerType parameter empty or set the registerType parameter to register, the pre-registration unique-certificate-per-product verification method is used and you must create a device.
initParams.registerType = "";
// Step 2: Specify an endpoint for dynamic registration.
MqttConfigure.mqttHost = "${YourMqttHostUrl}:8883";;
// (Optional) Step 3: You must specify this parameter for Enterprise Edition instances, or public instances of the IoT Platform service that is activated on July 30, 2021 and later.
// For public instances of the IoT Platform service that was activated before July 30, 2021, the value of this parameter is an empty string "".
MqttConfigure.registerInstanceId = "${YourInstanceId}";
final Object lock = new Object();
LinkKit.getInstance().deviceDynamicRegister(this, initParams, new IOnCallListener() {
@Override
public void onSuccess(com.aliyun.alink.linksdk.channel.core.base.ARequest request, com.aliyun.alink.linksdk.channel.core.base.AResponse response) {
ALog.i(TAG, "onSuccess() called with: request = [" + request + "], response = [" + response + "]");
// response.data is byte array
try {
String responseData = new String((byte[]) response.data);
JSONObject jsonObject = JSONObject.parseObject(responseData);
String pk = jsonObject.getString("productKey");
String dn = jsonObject.getString("deviceName");
// The result returned if the pre-registration unique-certificate-per-product verification method is used.
String deviceSecret = jsonObject.getString("deviceSecret");
// The result returned if the preregistration-free unique-certificate-per-product verification method is used.
String clientId = jsonObject.getString("clientId");
String deviceToken = jsonObject.getString("deviceToken");
// Save the returned credentials and proceed to Step 4. After you complete Step 4, you can use the onSuccess method to connect the device to IoT Platform.
// Call the API operation that waits for the thread.
synchronized (lock){
lock.notify();
}
} catch (Exception e) {
}
}
@Override
public void onFailed(com.aliyun.alink.linksdk.channel.core.base.ARequest request, com.aliyun.alink.linksdk.channel.core.base.AError error) {
ALog.e(TAG, "onFailed() called with: request = [" + request + "], error = [" + error + "]");
// Call the API operation that waits for the thread.
synchronized (lock){
lock.notify();
}
}
@Override
public boolean needUISafety() {
return false;
}
});
try{
// Wait for a downstream message. In most cases, the downstream message is returned within 1 second.
synchronized (lock){
lock.wait(3000);
}
// Step 4: Exit dynamic registration
// Do not run the following function in the LinkKit.getInstance().deviceDynamicRegister callback function. Otherwise, an error may occur.
LinkKit.getInstance().stopDeviceDynamicRegister(10 * 1000, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken iMqttToken) {
ALog.d(TAG, "onSuccess() called with: iMqttToken = [" + iMqttToken + "]");
// Connect the device to IoT Platform and initialize the connection based on the unique-certificate-per-device verification method.
}
@Override
public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
ALog.w(TAG, "onFailure() called with: iMqttToken = [" + iMqttToken + "], throwable = [" + throwable + "]");
}
});
}catch (Exception e){
};
ID²-based device verification
. /**
* Create a device that uses the iTLS-based verification in the IoT Platform console and perform the iTLS-based verification to initialize the device.
* Grant the ID² permissions to the product to which the device belongs.
*/
IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey, deviceName, deviceSecret);
clientConfig.channelHost = productKey + ".itls.cn-shanghai.aliyuncs.com:1883";
clientConfig.productSecret = productSecret;
clientConfig.secureMode = 8;
linkKitInitParams.mqttClientConfig = clientConfig;
// If you use an Enterprise Edition instance or a public instance of the IoT Platform service that was activated on July 30, 2021 or later, you can specify the instance ID by replacing the ${Instance ID} variable in the following command with the actual instance ID in the iot-******* format.
MqttConfigure.extraMqttClientIdItems=",instanceId=" + "${Instance ID}";
The clientConfig.channelHost
parameter in the sample code specifies the endpoint that the device can use to connect to IoT Platform.
More settings
You can configure the following parameters to configure additional settings that are related to device connection.
MQTT connection
Item
Description
Sample code
Keepalive interval
Specify a keepalive interval for a device. This parameter specifies the period of time during which a persistent connection can be retained between the device and IoT Platform.
NoteThe default keepalive period that is defined in the SDK is 65 seconds.
You can specify a keepalive interval that ranges from 30 to 1,200 seconds.
// The keepalive interval. Unit: seconds. MqttConfigure.setKeepAliveInterval(int interval);
QoS level
Specify a Quality of Service (QoS) level. A QoS level is an agreement that defines the quality level of message delivery between a device and IoT Platform. Valid values:
0
: Each message is delivered at most once.1
: Each message is delivered at least once.
MqttPublishRequest request = new MqttPublishRequest(); // Valid values: 0 and 1. Default value: 0. request.qos = 0; request.isRPC = false; request.topic = topic.replace("request", "response"); String resId = topic.substring(topic.indexOf("rrpc/request/")+13); request.msgId = resId; // Configure the parameters based on your business requirements. request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";
Offline messages
The cleanSession parameter specifies whether to receive offline messages.
IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(); // Correspond to the following code: receiveOfflineMsg = !cleanSession. By default, offline messages cannot be received. clientConfig.receiveOfflineMsg = true;
The ClientID.
The clientId parameter specifies a ClientID. For more information, see the description of the clientId parameter.
MqttConfigure.clientId = "abcdef******";
Reconnection mechanism
The automaticReconnect parameter specifies whether to re-connect a device to IoT Platform. Valid values:
true
: The system re-connects the device to IoT Platform.false
: The system does not reconnect the device to IoT Platform.
Sample code:
MqttConfigure.automaticReconnect = true;
SDK deinitialization
To perform deinitialization, you can call the following function. The function works in synchronous manner.
NoteIf you want to initialize the SDK, make sure that the previous deinitialization on the SDK is completed. Otherwise, the initialization on the SDK may fail.
// Unregister the notifyListener object. The object must be the same as the notifyListener object that is registered. LinkKit.getInstance().unRegisterOnPushListener(notifyListener); LinkKit.getInstance().deinit();
Connection status and downstream message listeners
You can configure the following listener to listen to the connection and disconnection messages of a device and listen to data sent from IoT Platform:
IConnectNotifyListener notifyListener = new IConnectNotifyListener() { @Override public void onNotify(String connectId, String topic, AMessage aMessage) { // The callback for downstream data from IoT Platform. // The connectId parameter specifies a connection type, the topic parameter specifies a downstream topic from IoT Platform, and the aMessage parameter specifies downstream data from IoT Platform. // Define a function named pushData to parse data. //String pushData = new String((byte[]) aMessage.data); // pushData example: {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"} // The method parameter specifies a service type, and the params parameter specifies the content of data that you want to push. } @Override public boolean shouldHandle(String connectId, String topic) { // Specify whether to process the downstream data of a topic from IoT Platform. // If a topic is not processed, the onNotify listener cannot receive the downstream data of the topic from IoT Platform. return true; // Specify a value based on your business scenario. } @Override public void onConnectStateChange(String connectId, ConnectState connectState) { // The callback for the connection status change of the corresponding connection type. For information about the connection status, see the description of ConnectState in the SDK. // If the SDK disconnects the device from IoT Platform due to poor network conditions, the SDK automatically attempts to reconnect the device to IoT Platform at intervals of 2 to the power of n (unit: seconds). n is an integer ranging from 0 to 7. The maximum interval is 128s. After the interval reaches 128s, the SDK attempts to reconnect the device to IoT Platform at the interval of 128s until the device is connected. } } // Register a listener to listen to downstream data, including the status of a persistent connection and downstream data from IoT Platform. LinkKit.getInstance().registerOnPushListener(notifyListener); // Unregister the listener that listens to downstream data. Make sure that the listener to be unregistered is the same as the listener that you registered. // LinkKit.getInstance().unRegisterOnPushListener(notifyListener);
NoteBy default, the
onNotify
callback function is called to transmit downstream data in the UI thread. Inlp-iot-linkkit
V1.7.3 and later, you can set thePersistentConnect.mNotifyReceivedMsgOnMainThread
parameter to false to transmit downstream data in threads other than the UI thread. We recommend that you set the PersistentConnect.mNotifyReceivedMsgOnMainThread parameter tofalse
when downstream messages are frequently transmitted or the UI thread is overloaded.Log switch
Turn on the internal log output switch of the SDK for Android:
PersistentNet.getInstance().openLog(true); ALog.setLevel(ALog.LEVEL_DEBUG);
Obtain the version number of the SDK for Android:
ALog.i(TAG, "sdk version = " + LinkKit.getInstance().getSDKVersion());
Quickly reconnect an Android device
If the SDK for Android disconnects a device from IoT Platform, the device is automatically reconnected to IoT Platform after 65 seconds. If you want to reconnect the device after a custom interval after the disconnection, you can perform the following steps to reconnect the device:
Specify
import com.aliyun.alink.linksdk.channel.core.persistent.PersistentNet;
and call thePersistentNet.getInstance().reconnect();
function.If you want to specify a custom reconnection interval, you can start a timer. When the timer ends, call the
PersistentNet.getInstance().reconnect();
function to re-establish a closed MQTT connection in real time.
Usage notes on the demo package
If a device fails to be initialized, you must re-initialize the SDK. If a device is disconnected from IoT Platform due to specific causes such as network failures, the SDK automatically reconnects the device to IoT Platform.
Modify the required parameters of the
./app/src/main/res/raw/deviceinfo
file in the demo package of Link SDK for Android to connect a device to IoT Platform. Configure the parameters that are marked as Required and use the default values for the parameters that are marked as Optional. The following table describes the parameters.If you connect a device to a public instance of the new version or an Enterprise Edition instance, go to the Instance Details page in the IoT Platform console and copy the port number on the page. Format:
{instanceid}.mqtt.iothub.aliyuncs.com:8883
If you connect a device to a public instance of the previous version, no port number is displayed on the Instance Details page in the IoT Platform console. You must specify a port number for the endpoint that you copied from the page. Format:
{YourProductKey}.iot-as-mqtt.{region}.aliyuncs.com:8883
. For more information, see View the endpoint of an instance.
Parameter | Description | Unique-certificate-per-device verification | Pre-registration unique-certificate-per-product verification | Preregistration-free unique-certificate-per-product verification |
productKey | The unique identifier issued by IoT Platform for the product. | Required | Required | Required |
deviceName | The unique identifier of the device within the product. | Required | Required | Required |
productSecret | The ProductSecret of the product. | Optional | Required | Required |
deviceSecret | The DeviceSecret of the device. | Required | Optional | Optional |
registerType | The preregistration-free or pre-registration unique-certificate-per-product verification. | Optional | Optional | Required. Set the value to regnwl. |
instanceId | The ID of the instance. Enterprise Edition instances and public instances of the new version have instance IDs. For more information, see Overview of IoT Platform instances. | Optional | Required | Required |
mqttHost | The endpoint that is used by a device to connect to the IoT Platform instance over MQTT. | Required, except for instances in the China (Shanghai) region. You must specify the domain name and port number in the endpoint based on your actual region. |