Thread Network SDK 提供類似數位鑰匙圈的功能,讓 Android 應用程式能與 Google Play 服務共用 Thread 網路憑證。這樣一來,應用程式就能直接透過任何智慧住宅生態系統設定任何 Thread 裝置,而不必洩露憑證和使用者資料。
只需幾個 API 呼叫,您就可以:
- 向 Google Play 服務要求偏好的 Thread 網路憑證。
- 設定新的邊界路由器,並將 Thread 網路憑證新增至 Google Play 服務。
- 如果您已有現場邊界路由器,則可查看邊界路由器是否在偏好的網路中,並在需要時進行遷移。
需要考量多個開發人員和開發人員的流程。本指南將介紹大部分內容,以及其他重要功能和建議使用方式。
重要術語及 API 概念
在開始之前,建議您先瞭解下列字詞:
Thread 網路憑證:執行緒 TLV 的二進位 blob,將執行緒網路名稱、網路金鑰和其他屬性所需的編碼,以納入執行緒系統所需的特定執行緒。
偏好的 Thread 網路憑證:自動選取的 Thread 網路憑證,可透過
getPreferredCredentials
API 與不同供應商的應用程式共用。邊界代理程式 ID:為 Thread Border 路由器裝置的全域唯一 ID。由邊界路由器廠商建立及管理。
Thread Border 路由器設定應用程式:這是您的 Android 應用程式,會設定新的 Thread Border 路由器裝置,並將 Thread 網路憑證新增至 Google Play 服務。您的應用程式是新憑證的權威擁有者,可以存取這些憑證。
許多 Thread Network API 都會傳回以非同步方式完成的工作。您可以使用 addOnSuccessListener 和 addOnFailureListener 註冊接收結果的回呼。詳情請參閱工作說明文件。
憑證擁有權和維護
新增 Thread 網路憑證的應用程式會成為憑證的擁有者,且具有憑證的完整權限。如果您嘗試存取其他應用程式新增的憑證,您會收到 PERMISSION_DENIED
錯誤。
身為應用程式擁有者,我們建議您在更新 Thread 邊界路由器網路時,將 Google Play 服務中儲存的憑證保持在最新狀態。這表示在需要時新增憑證,在邊界路由器的 Thread 網路憑證變更時更新憑證,並在移除執行緒邊界或恢復原廠設定時移除憑證。
探索代理程式代理程式
憑證必須連同邊界代理程式 ID 儲存。您必須確認 Thread Border 路由器設定應用程式能夠判斷執行緒邊框路由器的邊界代理程式 ID。
執行緒邊界路由器必須使用 mDNS 來公告 Thread 網路資訊,包括網路名稱、擴充窗格 ID 和邊界代理程式 ID。這些屬性對應的 txt
值分別為 nn
、xp
和 id
。
針對具有 Google 邊界路由器的網路,Google Play 服務會自動取得要使用的 Google Thread 網路憑證。
將 SDK 整合至您的 Android 應用程式
如要開始使用,請完成下列步驟:
按照設定 Google Play 服務提供的說明操作。
將 Google Play 服務依附元件新增至
build.gradle
檔案:implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0'
選用:定義
BorderAgent
資料類別以儲存邊界路由器的資訊。在本指南中,我們會使用這些資料:data class BorderAgentInfo( // Network Name max 16 len val networkName: String = "", val extPanId: ByteArray = ByteArray(16), val borderAgentId: ByteArray = ByteArray(16), ... )
接下來,我們會介紹建議新增及管理偏好憑證的建議步驟。
新增邊界路由器設定
為新的邊界路由器建立新網路之前,請務必先嘗試使用偏好的網路憑證。這可確保 Thread 裝置盡可能連線至單一執行緒網路。
呼叫 getPreferredCredentials
會啟動活動,提示使用者允許網路要求。如果您將網路憑證儲存在 Thread SDK 數位鑰匙圈中,系統會將憑證傳回您的應用程式。
要求憑證
如何提示使用者授予所需憑證:
宣告
ActivityLauncher
:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
處理活動結果,以
ThreadNetworkCredentials
傳回:preferredCredentialsLauncher = registerForActivityResult( StartIntentSenderForResult() ) { result: ActivityResult -> if (result.resultCode == RESULT_OK) { val threadNetworkCredentials = ThreadNetworkCredentials.fromIntentSenderResultData(result.data!!) Log.d("debug", threadNetworkCredentials.networkName) } else { Log.d("debug", "User denied request.") } }
呼叫
preferredCredentials
並啟用 Activity:private fun getPreferredThreadNetworkCredentials() { ThreadNetwork.getClient(this) .preferredCredentials .addOnSuccessListener { intentSenderResult -> intentSenderResult.intentSender?.let { preferredCredentialsLauncher.launch(IntentSenderRequest.Builder(it).build()) } ?: Log.d("debug", "No preferred credentials found.") } .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") } }
建立新的 Thread 網路
如果沒有使用者 Thread 網路中偏好的 Thread 網路憑證,您可以使用 addCredentials
API 將憑證新增至 Google Play 服務。如要這麼做,您必須建立 ThreadBorderAgent
,並提供 ThreadNetworkCredentials
物件。
如要建立隨機網路,請呼叫 newRandomizeBuilder
:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
如何指定執行緒網路名稱:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
新增憑證
為了讓您的 Thread 網路憑證可供其他 Thread 廠商使用,我們必須將這些憑證新增至 Google Play 服務。在新增憑證之前,我們還需要瞭解這個 Thread 網路所屬的邊界路由器裝置。
在這個範例中,我們會從邊界代理程式 ID 建立 ThreadBorderAgent
,並傳遞您剛建立的新 Thread 網路憑證:
private fun addCredentials(borderAgentInfo: BorderAgentInfo, credentialsToBeAdded: ThreadNetworkCredentials) {
val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
Log.d("debug", "border router id:" + threadBorderAgent.id)
ThreadNetwork.getClient(this)
.addCredentials(threadBorderAgent, credentialsToBeAdded)
.addOnSuccessListener {
Log.d("debug", "Credentials added.")
}
.addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}
偵測並遷移現場邊界路由器
如果您目前已有現場邊界路由器,可使用 isPreferredCredentials
來判斷您的邊界路由器是否屬於偏好的網路。這個 API 不會提示使用者授予權限,並根據與 Google Play 服務中儲存的資料檢查邊界路由器憑證。
isPreferredCredentails
會傳回未比對的 0
,1
則表示比對為 Int
資料類型。您可以使用 IsPreferredCredentialsResult
查看結果。
public @interface IsPreferredCredentialsResult {
int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
int PREFERRED_CREDENTIALS_MATCHED = 1;
}
如要使用 isPreferredCredentials
,您必須先建立 ThreadNetworkCredentials
物件。目前有幾種方式可將 ThreadNetworkCredentials
執行個體化。在接下來的步驟中,我們將探討這些選項。
透過作業資料集提供的執行緒網路憑證
某些情況下,您的 Thread 邊界路由器已透過 Thread 網路進行設定,而您想將這個執行緒網路新增到 Google Play 服務,然後與其他供應商共用。您可以從原始的 Thread 運作運作資料集 TLV 清單建立 ThreadNetworkCredential
執行個體:
將作業資料集轉換為
ByteArray
。例如:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }
使用
fromActiveOperationalDataset
建立ThreadNetworkCredentials
。成功後,您就能取得執行緒網路名稱、頻道和其他網路資訊。如需完整的屬性清單,請參閱 ThreadNetworkCredentials。val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
呼叫
isPreferredCredentials
API 並傳遞ThreadNetworkCredentials
。ThreadNetwork.getClient(this) .isPreferredCredentials(threadNetworkCredentials) .addOnSuccessListener { result -> when (result) { IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_NOT_MATCHED -> Log.d("isPreferredCredentials", "Credentials not matched.") IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_MATCHED -> Log.d("isPreferredCredentials", "Credentials matched.") } } .addOnFailureListener { e: Exception -> Log.d("isPreferredCredentials", "ERROR: [${e}]") }
Border 代理程式的執行緒網路憑證
邊界代理程式 ID 可明確識別邊界路由器裝置。如要使用 getCredentialsByBorderAgent
API,您必須先建立 ThreadBorderAgent
物件,並傳遞邊界代理程式 ID。
建立 ThreadBorderAgent
物件後,請呼叫 getCredentialsByBorderAgent
。如果該憑證已經儲存完畢,請檢查該憑證是否為偏好的程序。
private fun isPreferredThreadNetworkByBorderAgent(borderAgentInfo: BorderAgentInfo) {
val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
Log.d("debug", "border router id:" + threadBorderAgent.id)
var isPreferred = IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_NOT_FOUND
var borderAgentCredentials: ThreadNetworkCredentials?
val taskByBorderAgent = ThreadNetwork.getClient(this)
taskByBorderAgent
.getCredentialsByBorderAgent(threadBorderAgent)
.addOnSuccessListener { result: ThreadNetworkCredentialsResult ->
borderAgentCredentials = result.credentials
result.credentials?.let {
taskByBorderAgent.isPreferredCredentials(it).addOnSuccessListener { result ->
isPreferred = result
}
}
}
.addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}
按 Extended Pan ID 劃分的執行緒網路憑證
與 getPreferredCredentials
類似,您也可以提示使用者從邊框路由器的擴充擴充功能 ID 要求憑證。getCredentialsByExtendedPanId
會傳回 IntentSender
,而使用者核准後,活動結果會包含 ThreadNetworkCredentials
物件。
private fun getCredentialsByExtPanId(borderAgentInfo: BorderAgentInfo) {
ThreadNetwork.getClient(this)
.getCredentialsByExtendedPanId(borderAgentInfo.extPanId)
.addOnSuccessListener { intentSenderResult ->
intentSenderResult.intentSender?.let {
preferredCredentialsLauncher.launch(IntentSenderRequest.Builder(it).build())
}
?: Log.d("debug", "No credentials found.")
}
.addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}
移除憑證
如果您的 Border 路由器裝置從住家或恢復原廠設定後遭到移除,就必須從 Google Play 服務中移除 BThread 網路。
private fun removeCredentials(borderAgentInfo: BorderAgentInfo) {
val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
Log.d("debug", "border router id:" + threadBorderAgent.id)
ThreadNetwork.getClient(this)
.removeCredentials(threadBorderAgent)
.addOnSuccessListener { Log.d("debug", "Credentials removed.") }
.addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}
資源
如要進一步瞭解 Thread Network SDK,請參閱 API 參考資料。