This topic describes how to initialize Link SDK for Java to connect a device to IoT Platform.
Prerequisites
A product and a device are created. For more information, see Create a product and device.
The verification information of the device and the endpoint to which you want to connect the device are obtained.
Background information
Link SDK for Java allows you to use only DeviceSecrets to verify the identities of devices. The following table describes the verification methods that are supported by the SDK.
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 certificat 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 the 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.
For information about the parameters of Link SDK for Java, see LinkKitInitParams.
Unique-certificate-per-device verification
Sample code for unique-certificate-per-device verification
String productKey = "${YourProductKey}";
String deviceName = "${YourDeviceName}";
String deviceSecret = "${YourDeviceSecret}";
LinkKitInitParams params = new LinkKitInitParams();
/**
* Step 1: Configure the required parameters for Message Queuing Telemetry Transport (MQTT) initialization.
*/
IoTMqttClientConfig config = new IoTMqttClientConfig();
MqttConfigure.mqttHost = "{YourInstanceId}.mqtt.iothub.aliyuncs.com:8883";
/*
* Specify whether to receive offline messages.
* This parameter corresponds to the cleanSession parameter of an MQTT connection.
*/
config.receiveOfflineMsg = false;
params.mqttClientConfig = config;
/**
* Step 2: Specify the verification information that is required to initialize a device.
*/
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.productKey = productKey;
deviceInfo.deviceName = deviceName;
deviceInfo.deviceSecret = deviceSecret;
params.deviceInfo = deviceInfo;
/**
* Step 3: Specify the username, token, and clientId of the device.
* This step is required only if you use the preregistration-free unique-certificate-per-product verification method to verify a device.
* By default, this step is skipped.
*/
// MqttConfigure.deviceToken="${YourDeviceToken}";
// MqttConfigure.clientId="${YourClientId}";
LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
public void onError(AError aError) {
ALog.e(TAG, "Init Error error= "+aError);
}
public void onInitDone(InitResult initResult) {
ALog.i(TAG, "onInitDone result=" + initResult);
}
});
If
onInitDone
is returned after you send an initialization request, the initialization is successful. IfonError
is returned, the initialization failed.If the initialization fails, you can configure the required parameter to re-initialize the device based on your business requirements. Link SDK for Java does not automatically reconnect the device to IoT Platform.
If the initialization is successful and the device is disconnected from IoT Platform, Link SDK for Java automatically reconnects the device to IoT Platform.
Dynamic registration
Unique-certificate-per-product verification is also known as dynamic registration. The feature is used to request DeviceSecrets from IoT Platform. Unique-certificate-per-product verification methods are 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 enabled 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 a value is specified for the productSecret parameter.Make sure that Step 1, Step 2, and Step 3 in the following sample code are performed.
After dynamic registration is completed, you must close the persistent connection for dynamic registration. For more information, see the sample code in Step 4.
The sample code shows how to perform pre-registration unique-certificate-per-product verification. You can refer to the usage notes in Step 1 of the sample code to perform preregistration-free unique-certificate-per-product verification.
To ensure device security, burn a DeviceSecret to a device after you obtain the DeviceSecret by using the unique-certificate-per-product verification method. If you want to connect your device to IoT Platform, refer to the "Unique-certificate-per-device verification" section of this topic.
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 | Message Queuing Telemetry Transport (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 3 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 |
| You can activate up to five physical devices by using the same ProductKey, ProductSecret, and DeviceName in the IoT Platform console at the same time. IoT Platform generates a unique ClientID and DeviceToken for each device. |
Sample code for dynamic registration:
String deviceName = "${YourDeviceName}";
String productKey = "${YourProductKey}";
String productSecret = "${YourProductSecret}";
// 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.
String registerType = "register";
// Step 2: Specify an endpoint for dynamic registration.
MqttConfigure.mqttHost = "ssl://${YourMqttHostUrl}:8883";
MqttInitParams initParams = new MqttInitParams(productKey, productSecret, deviceName, "",registerType);
// Step 3: If you use a public instance of the new version or an Enterprise Edition instance, specify the instance ID that you obtained from the Instance Details page in the IoT Platform console for dynamic registration.
initParams.instanceId = "${YourInstanceId}";
final Object lock = new Object();
LinkKit.getInstance().deviceDynamicRegister(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) {
try {
String responseData = new String((byte[]) response.data);
JSONObject jsonObject = JSONObject.parseObject(responseData);
// The output that is returned if the pre-registration unique-certificate-per-product verification method is used.
String deviceSecret = jsonObject.getString("deviceSecret");
// The output that is 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(ARequest aRequest, com.aliyun.alink.linksdk.channel.core.base.AError aError) {
System.out.println("mqtt dynamic registration failed");
// 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: Disable the dynamic registration instance.
// Do not run the following function in the LinkKit.getInstance().deviceDynamicRegister callback. Otherwise, an error may occur.
LinkKit.getInstance().stopDeviceDynamicRegister(2000, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken iMqttToken) {
System.out.println("mqtt dynamic registration success");
// Connect the device to IoT Platform and initialize the connection. For more information, see the "Unique-certificate-per-device verification" section of this topic.
}
@Override
public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
System.out.println("mqtt dynamic registration failed");
}
});
} catch (Exception e) {
}
Specify an endpoint
Sample code:
// Specify an endpoint for the LinkKitInitParams parameter in an MQTT request.
IoTMqttClientConfig clientConfig = new IoTMqttClientConfig();
clientConfig.channelHost = "a18wP******.iot-as-mqtt.cn-shanghai.aliyuncs.com:8883";
linkKitInitParams.mqttClientConfig = clientConfig;
Parameters:
Parameter | Example | Description |
channelHost | a18wP******.iot-as-mqtt.cn-shanghai.aliyuncs.com:8883 | Specify the endpoint to which you want to connect the device in the
For information about public instances of the new and previous versions, Enterprise Edition instances, and endpoints, see View the endpoint of an instance. |
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 the device. This parameter specifies the period of time during which a persistent connection can be retained between the device and IoT Platform.
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.
- The qos parameter. 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 preceding parameters based on your business requirements. The preceding information is provided only for reference. request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";
Offline messages
The cleanSession parameter specifies whether to receive offline messages.
/** * Configure the required parameters for MQTT initialization. */ IoTMqttClientConfig config = new IoTMqttClientConfig(); config.productKey = deviceInfoData.productKey; config.deviceName = deviceInfoData.deviceName; config.deviceSecret = deviceInfoData.deviceSecret; config.channelHost = pk + ".iot-as-mqtt." + deviceInfoData.region + ".aliyuncs.com:1883"; /** * Specify whether to receive offline messages. * The following definitions correspond to the following code: receiveOfflineMsg = !cleanSession. By default, offline messages cannot be received. */ config.receiveOfflineMsg = false; params.mqttClientConfig = config;
Support for logging and Log4j
You can run the following command to obtain debugging logs:
ALog.setLevel(ALog.LEVEL_DEBUG);
In Link SDK for Java V1.2.3.1 and later, you can configure the
log
function of a global interceptor to process logs based on your business requirements. For example, you can use Log4j to store logs in persistent storage such as a file.Sample code:
ALog.setLogDispatcher(new ILogDispatcher() { @Override public void log(int level, String prefix, String msg) { switch (level){ case LEVEL_DEBUG: System.out.println("debug:"+ prefix + msg); break; case LEVEL_INFO: System.out.println("info:" + prefix + msg); break; case LEVEL_ERROR: System.out.println("error:" + prefix + msg); break; case LEVEL_WARNING: System.out.println("warnings:" + prefix + msg); break; default: System.out.println("other:" + prefix + msg); } } });
Connection status and downstream message listeners
To listen to the connection and disconnection messages of a device and data that is sent from IoT Platform, configure the following listener:
IConnectNotifyListener notifyListener = new IConnectNotifyListener() { @Override public void onNotify(String connectId, String topic, AMessage aMessage) { // The callback for downstream data from IoT Platform, such as the connectId, connection type, downstream topic from IoT Platform, and the aMessage parameter that specifies the message body sent from IoT Platform. //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. 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 the required data processing logic for the listener 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 ConnectState in the SDK. // If the SDK detects that the device is disconnected from IoT Platform due to network fluctuations, the SDK automatically reconnects the device at intervals of 1 second, 2 seconds, 4 seconds, 8 seconds, and 128 seconds. After the retry interval reaches 128 seconds, the SDK retries at an interval of 128 seconds until the device is reconnected to IoT Platform. } } // Register a listener to listen to downstream data, including the status of a persistent connection and downstream data from IoT Platform. LinkKit.getInstance().registerOnNotifyListener(notifyListener);
Deinitialization
The following code shows how to perform deinitialization:
// Unregister the notifyListener listener. Make sure that you unregister the listener that you registered. LinkKit.getInstance().unRegisterOnNotifyListener(notifyListener); LinkKit.getInstance().deinit();