デバイスを IoT Platform に接続する前に、デバイスは ID 検証に合格する必要があります。このトピックでは、Android 向け Link SDK を初期化してデバイスを IoT Platform に接続する方法について説明します。
前提条件
プロダクトとデバイスが作成されていること。詳細については、「プロダクトとデバイスを作成する」をご参照ください。
Android 向け Link SDK デモパッケージ がダウンロードされていること。
デバイス証明書の情報と、デバイスを接続するエンドポイントが取得されていること。詳細については、「Android 向け Link SDK」トピックのパラメーター構成をご参照ください。
背景情報
Android 向け Link SDK を使用すると、DeviceSecret または IoT デバイス ID(ID²) を使用してデバイスの ID を検証できます。
DeviceSecret を使用してデバイスを検証する:
検証方法
登録方法
説明
該当なし
ProductKey、DeviceName、および DeviceSecret を含むデバイス証明書が各デバイスに書き込まれます。
事前登録
ProductKey と ProductSecret を含むプロダクト証明書が、プロダクトのすべてのデバイスに書き込まれます。
プロダクトに対して [動的登録] 機能を有効にする必要があります。
動的登録により、デバイスは DeviceSecret を取得できます。
事前登録不要
ProductKey と ProductSecret を含むプロダクト証明書が、プロダクトのすべてのデバイスに書き込まれます。
プロダクトに対して [動的登録] 機能を有効にする必要があります。
動的登録により、デバイスは ClientID と DeviceToken の組み合わせを取得できます。
説明事前登録によるプロダクトごとの一意の証明書検証と、事前登録不要のプロダクトごとの一意の証明書検証の違いについては、「検証方法の違い」をご参照ください。
ID² を使用してデバイスを検証する: ID² は、IoT Platform デバイスの信頼できる ID です。ID² は改ざん防止と偽造防止がされています。
ID² を使用してデバイスを検証する方法については、InitManager.java ファイルのサンプルコードをご参照ください。
デバイスごとの一意の証明書検証
デバイスごとの一意の証明書検証方法のサンプルコード:
AppLog.setLevel(ALog.LEVEL_DEBUG);
final LinkKitInitParams params = new LinkKitInitParams();
String productKey = "${YourProductKey}";
String deviceName = "${YourDeviceName}";
String deviceSecret = "${YourDeviceSecret}";
String productSecret = "";
// ステップ 1: デバイス証明書に関する情報を指定します。
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.productKey = productKey; // プロダクトの ProductKey。
deviceInfo.deviceName = deviceName; // デバイスの DeviceName。
deviceInfo.deviceSecret = deviceSecret; // デバイスの DeviceSecret。
deviceInfo.productSecret = productSecret; // プロダクトの ProductSecret。
params.deviceInfo = deviceInfo;
// ステップ 2: グローバルデフォルトドメイン名を指定します。
IoTApiClientConfig userData = new IoTApiClientConfig();
params.connectConfig = userData;
// ステップ 3: Thing Specification Language (TSL) モデルをキャッシュします。
Map<String, ValueWrapper> propertyValues = new HashMap<>();
/**
* TSL データは上記のパラメーターにキャッシュされます。このパラメーターを削除したり、空のままにしたりすることはできません。そうしないと、TSL 関連の機能が失敗する可能性があります。
* API 操作を呼び出して TSL データを送信すると、TSL データがキャッシュされます。
*/
params.propertyValues = propertyValues;
// ステップ 4: MQTT パラメーターを構成します。
/**
* エンドポイントなどの MQTT パラメーター。詳細については、deviceinfo ファイルをご参照ください。
* ドメイン名、ProductSecret、およびセキュリティ検証方法。
*/
IoTMqttClientConfig clientConfig = new IoTMqttClientConfig();
clientConfig.receiveOfflineMsg = false;//cleanSession=1 オフラインメッセージは受信できません。
// Message Queuing Telemetry Transport (MQTT) エンドポイントに関する情報。
clientConfig.channelHost = "${YourMqttHostUrl}:8883";
params.mqttClientConfig = clientConfig;
MqttConfigure.pingSenderType = "android"; // ハートビート検出タイプを android に設定し、ハートビート検出のタイマータイプを AlarmTImer に設定します。これにより、ディスプレイが自動的にシャットダウンされた場合でも、ハートビート検出がスケジュールどおりに実行されます。
// ステップ 5: 拡張機能を構成します。デフォルトでは、TSL モデル機能を除くすべての拡張機能が無効になっています。
IoTDMConfig ioTDMConfig = new IoTDMConfig();
// デフォルトでは、TSL モデル機能は有効になっています。IoT Platform からリクエストされた TSL モデルを初期化すると、onInitDone が返されます。
ioTDMConfig.enableThingModel = true;
// デフォルトでは、ゲートウェイ機能は無効になっています。ゲートウェイ機能を有効にすると、ゲートウェイモジュールが初期化され、IoT Platform からゲートウェイモジュールのサブデバイスリストが取得されます。
ioTDMConfig.enableGateway = false;
// デフォルトでは、ログプッシュ機能は無効になっています。この機能を有効にすることができます。
ioTDMConfig.enableLogPush = false;
params.ioTDMConfig = ioTDMConfig;
// ステップ 6: ダウンストリームメッセージを処理するコールバック関数を構成します。
LinkKit.getInstance().registerOnPushListener(new IConnectNotifyListener() {
@Override
public void onNotify(String s, String s1, AMessage aMessage) {
// ドキュメントに基づいて、ダウンストリームメッセージ処理のコールバック関数を構成できます。
}
@Override
public boolean shouldHandle(String s, String s1) {
return true; // ビジネス要件とドキュメントに基づいてパラメーターを構成します。
}
@Override
public void onConnectStateChange(String s, ConnectState connectState) {
// 対応する接続タイプの接続状態変更のコールバック。接続状態については、SDK の ConnectState をご参照ください。
// ネットワークの状態が悪いなどの理由で SDK がデバイスを IoT Platform から切断した場合、SDK は 2 の n 乗秒(n は 0 から 7 までの整数)の間隔でデバイスを IoT Platform に自動的に再接続しようとします。最大間隔は 128 秒です。
}
});
// 事前登録不要のプロダクトごとの一意の証明書検証方法を使用してデバイスを検証する場合、デバイスを IoT Platform に接続するときに DeviceToken と ClientID が必要です。
// ステップ 7: 事前登録不要のプロダクトごとの一意の証明書検証のパラメーターを構成します。この機能はデフォルトでは無効になっています。
// MqttConfigure.deviceToken = DemoApplication.deviceToken;
// MqttConfigure.clientId = DemoApplication.clientId;
// ステップ 8: HTTP/2 経由でファイルをアップロードするために必要なパラメーターを構成します。
/**
* HTTP/2 経由でファイルを IoT Platform にアップロードする場合、ドメイン名を指定する必要があります。
*/
// IoTH2Config ioTH2Config = new IoTH2Config();
// ioTH2Config.clientId = "client-id";
// ioTH2Config.endPoint = "https://" + productKey + ioTH2Config.endPoint;// HTTP/2 経由でファイルを IoT Platform にアップロードするために使用されるエンドポイント。
// params.iotH2InitParams = ioTH2Config;
/**
* SDK を初期化してデバイスを IoT Platform に接続します。
* onError 初期化に失敗しました。ネットワークの問題で初期化に失敗した場合は、SDK を再初期化する必要があります。
* onInitDone 初期化に成功しました。
*/
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 + "]");
// デバイスの検証が完了し、デバイスが接続されました。必要に応じてビジネスを実行できます。
}
});
プロダクトごとの一意の証明書検証
プロダクトごとの一意の証明書検証は、動的登録とも呼ばれます。この機能は、IoT Platform から DeviceSecret をリクエストするために使用されます。プロダクトごとの一意の証明書検証方法は、事前登録不要と事前登録の 2 つのタイプに分類できます。この機能を使用する前に、次の前提条件が満たされていることを確認してください。
IoT Platform コンソールで作成したプロダクトに対して、[動的登録] が有効になっていること。
デモパッケージの
deviceinfoファイルで、deviceSecret パラメーターが空で、productSecret が空でないこと。サンプルコードのステップ 1 からステップ 3 が実行されていること。
動的登録が成功または失敗した後、動的登録の持続的接続を閉じます。接続を閉じる方法については、ステップ 4 をご参照ください。
デバイスのセキュリティを確保するために、プロダクトごとの一意の証明書検証方法を使用して DeviceSecret を取得した後、DeviceSecret をデバイスに書き込みます。
次の表に、事前登録不要のプロダクトごとの一意の証明書検証と、事前登録のプロダクトごとの一意の証明書検証の違いを示します。
項目 | 事前登録 | 事前登録不要 |
プロトコル | MQTT および HTTPS | MQTT |
リージョン |
| 中国 (上海) および中国 (北京) |
返される DeviceSecret | DeviceSecret の使用方法については、デバイスごとの一意の証明書検証のサンプルコードのステップ 1 をご参照ください。 | デバイスの ClientID と DeviceToken をデバイスに書き込みます。このようにして、デバイスを IoT Platform に接続するなどの特定の機能を使用するときに、この情報を使用できます。詳細については、デバイスごとの一意の証明書検証のサンプルコードのステップ 7 をご参照ください。 |
デバイスの登録 | IoT Platform コンソールでデバイスの DeviceName を事前登録する必要があります。 | IoT Platform コンソールでデバイスの DeviceName を事前登録する必要はありません。 |
使用回数 |
| 各 ProductKey、ProductSecret、および DeviceName を使用して、最大 5 つの物理デバイスをアクティブ化できます。IoT Platform コンソールでデバイスを同時にアクティブ化できます。IoT Platform は、デバイスごとに一意の ClientID と DeviceToken を生成します。 |
コードの詳細については、デモパッケージの DemoApplication.java ファイルをご参照ください。
動的登録のサンプルコード:
String productKey = "${YourProductKey}";
String deviceName = "${YourDeviceName}";
String deviceSecret = "${YourDeviceSecret}";
String productSecret = "";
MqttInitParams initParams = new MqttInitParams(productKey, productSecret, deviceName, deviceSecret, MqttConfigure.MQTT_SECURE_MODE_TLS);
// ステップ 1: プロダクトごとの一意の証明書検証方法が事前登録不要か事前登録かを確認します。
// ケース 1: registerType パラメーターを regnwl に設定すると、事前登録不要のプロダクトごとの一意の証明書検証方法が使用され、デバイスを作成する必要はありません。
// ケース 2: registerType パラメーターを空のままにするか、registerType パラメーターを register に設定すると、事前登録のプロダクトごとの一意の証明書検証方法が使用され、デバイスを作成する必要があります。
initParams.registerType = "";
// ステップ 2: 動的登録のエンドポイントを指定します。
MqttConfigure.mqttHost = "${YourMqttHostUrl}:8883";;
// (オプション) ステップ 3: このパラメーターは、Enterprise Edition インスタンス、または 2021 年 7 月 30 日以降にアクティブ化された IoT Platform サービスのパブリックインスタンスに指定する必要があります。
// 2021 年 7 月 30 日より前にアクティブ化された IoT Platform サービスのパブリックインスタンスの場合、このパラメーターの値は空の文字列 "" です。
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 はバイト配列です
try {
String responseData = new String((byte[]) response.data);
JSONObject jsonObject = JSONObject.parseObject(responseData);
String pk = jsonObject.getString("productKey");
String dn = jsonObject.getString("deviceName");
// 事前登録のプロダクトごとの一意の証明書検証方法が使用された場合に返される結果。
String deviceSecret = jsonObject.getString("deviceSecret");
// 事前登録不要のプロダクトごとの一意の証明書検証方法が使用された場合に返される結果。
String clientId = jsonObject.getString("clientId");
String deviceToken = jsonObject.getString("deviceToken");
// 返された資格情報を保存し、ステップ 4 に進みます。ステップ 4 が完了すると、onSuccess メソッドを使用してデバイスを IoT Platform に接続できます。
// スレッドを待機する API 操作を呼び出します。
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 + "]");
// スレッドを待機する API 操作を呼び出します。
synchronized (lock){
lock.notify();
}
}
@Override
public boolean needUISafety() {
return false;
}
});
try{
// ダウンストリームメッセージを待機します。ほとんどの場合、ダウンストリームメッセージは 1 秒以内に返されます。
synchronized (lock){
lock.wait(3000);
}
// ステップ 4: 動的登録を終了します
// LinkKit.getInstance().deviceDynamicRegister コールバック関数で次の関数を実行しないでください。そうしないと、エラーが発生する可能性があります。
LinkKit.getInstance().stopDeviceDynamicRegister(10 * 1000, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken iMqttToken) {
ALog.d(TAG, "onSuccess() called with: iMqttToken = [" + iMqttToken + "]");
// デバイスを IoT Platform に接続し、デバイスごとの一意の証明書検証方法に基づいて接続を初期化します。
}
@Override
public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
ALog.w(TAG, "onFailure() called with: iMqttToken = [" + iMqttToken + "], throwable = [" + throwable + "]");
}
});
}catch (Exception e){
};
ID² ベースのデバイス検証
. /**
* IoT Platform コンソールで iTLS ベースの検証を使用するデバイスを作成し、iTLS ベースの検証を実行してデバイスを初期化します。
* デバイスが属するプロダクトに ID² 権限を付与します。
*/
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;
// Enterprise Edition インスタンス、または 2021 年 7 月 30 日以降にアクティブ化された IoT Platform サービスのパブリックインスタンスを使用する場合は、次のコマンドの ${Instance ID} 変数を iot-******* 形式の実際のインスタンス ID に置き換えることで、インスタンス ID を指定できます。
MqttConfigure.extraMqttClientIdItems=",instanceId=" + "${Instance ID}";
サンプルコードの clientConfig.channelHost パラメーターは、デバイスが IoT Platform に接続するために使用できるエンドポイントを指定します。
その他の設定
次のパラメーターを構成して、デバイス接続に関連する追加設定を構成できます。
MQTT 接続
項目
説明
サンプルコード
キープアライブ間隔
デバイスのキープアライブ間隔を指定します。このパラメーターは、デバイスと IoT Platform 間で持続的接続を維持できる期間を指定します。
説明SDK で定義されているデフォルトのキープアライブ期間は 65 秒です。
30 ~ 1,200 秒のキープアライブ間隔を指定できます。
// キープアライブ間隔。単位: 秒。 MqttConfigure.setKeepAliveInterval(int interval);QoS レベル
サービス品質 (QoS) レベルを指定します。QoS レベルは、デバイスと IoT Platform 間のメッセージ配信の品質レベルを定義する契約です。有効な値:
0: 各メッセージは最大 1 回配信されます。1: 各メッセージは少なくとも 1 回配信されます。
MqttPublishRequest request = new MqttPublishRequest(); // 有効な値: 0 および 1。デフォルト値: 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; // ビジネス要件に基づいてパラメーターを構成します。 request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";オフラインメッセージ
cleanSession パラメーターは、オフラインメッセージを受信するかどうかを指定します。
IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(); // 次のコードに対応します: receiveOfflineMsg = !cleanSession。デフォルトでは、オフラインメッセージは受信できません。 clientConfig.receiveOfflineMsg = true;ClientID
clientId パラメーターは、ClientID を指定します。詳細については、clientId パラメーターの説明をご参照ください。
MqttConfigure.clientId = "abcdef******";再接続メカニズム
automaticReconnect パラメーターは、デバイスを IoT Platform に再接続するかどうかを指定します。有効な値:
true: システムはデバイスを IoT Platform に再接続します。false: システムはデバイスを IoT Platform に再接続しません。
サンプルコード:
MqttConfigure.automaticReconnect = true;SDK の初期化解除
初期化解除を実行するには、次の関数を呼び出すことができます。この関数は同期的に動作します。
説明SDK を初期化する場合は、SDK の以前の初期化解除が完了していることを確認してください。そうしないと、SDK の初期化に失敗する可能性があります。
// notifyListener オブジェクトの登録を解除します。オブジェクトは、登録されている notifyListener オブジェクトと同じである必要があります。 LinkKit.getInstance().unRegisterOnPushListener(notifyListener); LinkKit.getInstance().deinit();接続状態とダウンストリームメッセージリスナー
次のリスナーを構成して、デバイスの接続および切断メッセージをリッスンし、IoT Platform から送信されたデータをリッスンできます。
IConnectNotifyListener notifyListener = new IConnectNotifyListener() { @Override public void onNotify(String connectId, String topic, AMessage aMessage) { // IoT Platform からのダウンストリームデータのコールバック。 // connectId パラメーターは接続タイプを指定し、topic パラメーターは IoT Platform からのダウンストリームトピックを指定し、aMessage パラメーターは IoT Platform からのダウンストリームデータを指定します。 // pushData という名前の関数を定義してデータを解析します。 //String pushData = new String((byte[]) aMessage.data); // pushData の例: {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"} // method パラメーターはサービスタイプを指定し、params パラメーターはプッシュするデータの内容を指定します。 } @Override public boolean shouldHandle(String connectId, String topic) { // IoT Platform からのトピックのダウンストリームデータを処理するかどうかを指定します。 // トピックが処理されない場合、onNotify リスナーは IoT Platform からのトピックのダウンストリームデータを受信できません。 return true; // ビジネスシナリオに基づいて値を指定します。 } @Override public void onConnectStateChange(String connectId, ConnectState connectState) { // 対応する接続タイプの接続状態変更のコールバック。接続状態については、SDK の ConnectState の説明をご参照ください。 // ネットワークの状態が悪いなどの理由で SDK がデバイスを IoT Platform から切断した場合、SDK は 2 の n 乗秒(n は 0 から 7 までの整数)の間隔でデバイスを IoT Platform に自動的に再接続しようとします。最大間隔は 128 秒です。間隔が 128 秒に達すると、SDK はデバイスが接続されるまで 128 秒の間隔でデバイスを IoT Platform に再接続しようとします。 } } // ダウンストリームデータをリッスンするリスナーを登録します。これには、持続的接続のステータスと IoT Platform からのダウンストリームデータが含まれます。 LinkKit.getInstance().registerOnPushListener(notifyListener); // ダウンストリームデータをリッスンするリスナーの登録を解除します。登録解除するリスナーは、登録したリスナーと同じであることを確認してください。 // LinkKit.getInstance().unRegisterOnPushListener(notifyListener);説明デフォルトでは、
onNotifyコールバック関数は UI スレッドでダウンストリームデータを送信するために呼び出されます。lp-iot-linkkitV1.7.3 以降では、PersistentConnect.mNotifyReceivedMsgOnMainThreadパラメーターを false に設定して、UI スレッド以外のスレッドでダウンストリームデータを送信できます。ダウンストリームメッセージが頻繁に送信される場合、または UI スレッドが過負荷になっている場合は、PersistentConnect.mNotifyReceivedMsgOnMainThread パラメーターをfalseに設定することをお勧めします。ログスイッチ
Android 向け SDK の内部ログ出力スイッチをオンにします。
PersistentNet.getInstance().openLog(true); ALog.setLevel(ALog.LEVEL_DEBUG);Android 向け SDK のバージョン番号を取得する:
ALog.i(TAG, "sdk version = " + LinkKit.getInstance().getSDKVersion());
Android デバイスの迅速な再接続
Android 向け SDK がデバイスを IoT Platform から切断した場合、デバイスは 65 秒後に IoT Platform に自動的に再接続されます。切断後、カスタム間隔でデバイスを再接続する場合は、次の手順を実行してデバイスを再接続できます。
import com.aliyun.alink.linksdk.channel.core.persistent.PersistentNet;を指定し、PersistentNet.getInstance().reconnect();関数を呼び出します。カスタムの再接続間隔を指定する場合は、タイマーを起動できます。タイマーが終了したら、
PersistentNet.getInstance().reconnect();関数を呼び出して、閉じた MQTT 接続をリアルタイムで再確立します。
デモパッケージの使用上の注意
デバイスの初期化に失敗した場合は、SDK を再初期化する必要があります。ネットワーク障害などの特定の原因によりデバイスが IoT Platform から切断された場合、SDK はデバイスを IoT Platform に自動的に再接続します。
Android 向け Link SDK のデモパッケージ の
./app/src/main/res/raw/deviceinfoファイルで必要なパラメーターを変更して、デバイスを IoT Platform に接続します。[必須] とマークされているパラメーターを構成し、[オプション] とマークされているパラメーターにはデフォルト値を使用します。次の表にパラメーターを示します。デバイスを新しいバージョンのパブリックインスタンスまたは Enterprise Edition インスタンスに接続する場合は、IoT Platform コンソールの [インスタンスの詳細] ページに移動し、ページのポート番号をコピーします。形式:
{instanceid}.mqtt.iothub.aliyuncs.com:8883以前のバージョンのパブリック インスタンスにデバイスを接続する場合、IoT Platform コンソールの [インスタンスの詳細] ページにポート番号は表示されません。 ページからコピーしたエンドポイントにポート番号を指定する必要があります。形式:
デバイスを以前のバージョンのパブリックインスタンスに接続する場合、IoT Platform コンソールの [インスタンスの詳細] ページにはポート番号は表示されません。ページからコピーしたエンドポイントにポート番号を指定する必要があります。形式:
{YourProductKey}.iot-as-mqtt.{region}.aliyuncs.com:8883。詳細については、「インスタンスのエンドポイントを表示する」をご参照ください。
パラメーター | 説明 | デバイスごとの一意の証明書検証 | 事前登録によるプロダクトごとの一意の証明書検証 | 事前登録不要のプロダクトごとの一意の証明書検証 |
productKey | プロダクトに対して IoT Platform によって発行された一意の ID。 | 必須 | 必須 | 必須 |
deviceName | プロダクト内でのデバイスの一意の ID。 | 必須 | 必須 | 必須 |
productSecret | プロダクトの ProductSecret。 | オプション | 必須 | 必須 |
deviceSecret | デバイスの DeviceSecret。 | 必須 | オプション | オプション |
registerType | 事前登録不要または事前登録のプロダクトごとの一意の証明書検証。 | オプション | オプション | 必須。値を regnwl に設定します。 |
instanceId | インスタンスの ID。Enterprise Edition インスタンスと新しいバージョンのパブリックインスタンスには、インスタンス ID があります。詳細については、「IoT Platform インスタンスの概要」をご参照ください。 | オプション | 必須 | 必須 |
mqttHost | デバイスが MQTT 経由で IoT Platform インスタンスに接続するために使用するエンドポイント。 | 中国 (上海) リージョンのインスタンスを除き、必須です。実際のリージョンに基づいて、エンドポイントにドメイン名とポート番号を指定する必要があります。 | ||