SDK mạng Thread cho Android

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

SDK mạng Thread cung cấp chức năng tương tự như chìa khóa kỹ thuật số cho phép các ứng dụng Android của bạn chia sẻ thông tin đăng nhập mạng Thread với Dịch vụ Google Play. Điều này cho phép các ứng dụng của bạn thiết lập bất kỳ thiết bị Thread nào từ hệ sinh thái nhà thông minh bất kỳ mà không cần tiết lộ thông tin xác thực và dữ liệu người dùng trực tiếp.

Chỉ với một vài lệnh gọi API, bạn có thể:

  1. Yêu cầu thông tin đăng nhập vào mạng Thread ưa thích từ Dịch vụ Google Play.
  2. Thiết lập bộ định tuyến biên mới, đồng thời thêm thông tin xác thực mạng Thread của bạn vào Dịch vụ Google Play.
  3. Nếu đã có bộ định tuyến biên trong trường, bạn có thể kiểm tra xem bộ định tuyến biên giới có trong mạng ưu tiên và di chuyển chúng không, nếu cần.

Có một số hành trình của người dùng và nhà phát triển cần xem xét. Chúng tôi sẽ đề cập đến hầu hết phần này trong hướng dẫn này, cùng với các tính năng chính khác và gợi ý sử dụng.

Các thuật ngữ chính và khái niệm về API

Trước khi bắt đầu, bạn nên hiểu các thuật ngữ sau:

  • Thông tin đăng nhập mạng theo chuỗi: blob nhị phân của các LV TLV mã hóa Tên mạng chuỗi, Khóa mạng và các thuộc tính khác mà thiết bị Thread yêu cầu để tham gia một mạng Thread đã cho.

  • Thông tin đăng nhập mạng Thread ưu tiên: Thông tin xác thực mạng Thread được chọn tự động có thể được chia sẻ với các ứng dụng của nhiều nhà cung cấp bằng cách sử dụng getPreferredCredentials API.

  • Mã tác nhân biên giới: Mã nhận dạng duy nhất trên toàn cầu có kích thước 16 byte cho một thiết bị Bộ định tuyến biên. Mã này do các nhà cung cấp bộ định tuyến biên giới tạo và quản lý.

  • Ứng dụng Thiết lập bộ định tuyến đường viền: Đây là ứng dụng Android của bạn để thiết lập các thiết bị Bộ định tuyến đường viền mới và thêm thông tin xác thực mạng Thread vào các dịch vụ của Google Play. Ứng dụng của bạn là chủ sở hữu có thẩm quyền của các thông tin xác thực đã thêm và có quyền truy cập miễn phí vào thông tin xác thực.

Nhiều API mạng Thread trả về một Task hoàn thành không đồng bộ. Bạn có thể sử dụng addOnSuccessListeneraddOnFailureListener để đăng ký các lệnh gọi lại để nhận kết quả. Để tìm hiểu thêm, hãy tham khảo tài liệu Việc cần làm.

Quyền sở hữu và duy trì thông tin đăng nhập

Ứng dụng thêm thông tin đăng nhập vào mạng Thread sẽ trở thành chủ sở hữu thông tin đăng nhập và có toàn quyền truy cập vào thông tin đăng nhập. Nếu cố gắng truy cập vào thông tin đăng nhập do các ứng dụng khác thêm vào, bạn sẽ gặp lỗi PERMISSION_DENIED.

Là chủ sở hữu ứng dụng, bạn nên cập nhật thông tin xác thực trong Dịch vụ Google Play khi mạng Bộ định tuyến đường viền Thread được cập nhật. Điều này có nghĩa là việc thêm thông tin xác thực khi cần, cập nhật thông tin xác thực khi thông tin đăng nhập mạng của bộ định tuyến trình tuyến thay đổi và xóa thông tin xác thực khi Bộ định tuyến đường viền bị xóa hoặc bị đặt lại về trạng thái ban đầu.

Khám phá tác nhân biên giới

Bạn phải lưu thông tin đăng nhập bằng mã tác nhân biên giới. Bạn sẽ cần đảm bảo rằng ứng dụng Thiết lập bộ định tuyến đường viền có thể xác định Mã tác nhân biên giới của bộ định tuyến đường viền Thread.

Bộ định tuyến biên Thread phải sử dụng mDNS để quảng cáo thông tin mạng Thread, bao gồm Tên mạng, Mã Pan mở rộng và Mã tác nhân biên giới. Giá trị txt tương ứng cho các thuộc tính này lần lượt là nn, xpid.

Đối với các mạng có bộ định tuyến biên của Google, Dịch vụ Google Play sẽ tự động có được thông tin đăng nhập mạng Google Thread để sử dụng.

Tích hợp SDK vào ứng dụng Android của bạn

Để bắt đầu, hãy hoàn thành các bước sau:

  1. Làm theo hướng dẫn tại Thiết lập Dịch vụ Google Play.

  2. Thêm phần phụ thuộc Dịch vụ Google Play vào tệp build.gradle của bạn:

    implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0-beta01'
    
  3. Không bắt buộc: Xác định Đại lý biên giới data class để lưu trữ thông tin bộ định tuyến biên giới. Chúng tôi sẽ sử dụng dữ liệu này trong hướng dẫn này:

    data class BorderAgentInfo(
      // Network Name max 16 len
      val networkName: String = "",
      val extPanId: ByteArray = ByteArray(16),
      val borderAgentId: ByteArray = ByteArray(16),
      ...
    )
    

Tiếp theo, chúng tôi sẽ xem xét các bước được đề xuất để thêm và quản lý thông tin xác thực ưa thích.

Thiết lập bộ định tuyến biên mới

Trước khi tạo mạng mới cho bộ định tuyến biên mới, trước tiên, bạn cần sử dụng thông tin xác thực mạng ưu tiên. Điều này đảm bảo rằng các thiết bị Chuỗi được kết nối với một mạng Thread khi có thể.

Lệnh gọi đến getPreferredCredentials sẽ khởi chạy một Hoạt động, nhắc người dùng cho phép yêu cầu mạng. Nếu thông tin xác thực mạng đã được lưu trữ trong chuỗi khóa kỹ thuật số SDK Thread, thì thông tin đăng nhập sẽ được trả về ứng dụng của bạn.

Yêu cầu thông tin đăng nhập

Để nhắc người dùng về thông tin đăng nhập ưu tiên:

  1. Khai báo một ActivityLauncher:

    private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  2. Xử lý kết quả Hoạt động, trả về dưới dạng 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.")
       }
     }
    
  3. Gọi preferredCredentials và chạy Hoạt động:

    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}]") }
    }
    

Tạo một mạng Thread mới

Nếu không có bằng chứng xác thực mạng Thread ưu tiên nào trong Mạng chuỗi của người dùng, thì bạn có thể sử dụng API addCredentials để thêm thông tin đăng nhập vào Dịch vụ Google Play. Để làm điều này, bạn cần phải tạo ThreadBorderAgent, đồng thời cung cấp đối tượng ThreadNetworkCredentials.

Để tạo mạng ngẫu nhiên, hãy gọi newRandomizeBuilder:

val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()

Để chỉ định Tên mạng chuỗi:

val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
  .setNetworkName("ThreadNetworkSDK")
  .build()

Thêm thông tin đăng nhập

Để có thể sử dụng thông tin đăng nhập mạng Thread của bạn cho các nhà cung cấp Thread khác, chúng tôi cần thêm thông tin đăng nhập đó vào Dịch vụ Google Play. Trước khi có thể thêm thông tin xác thực mới, chúng ta cũng cần biết thiết bị định tuyến này thuộc về thiết bị định tuyến biên nào.

Trong ví dụ này, chúng ta sẽ tạo một ThreadBorderAgent từ mã tác nhân biên giới và chuyển thông tin đăng nhập mạng Thread mới mà bạn vừa tạo:

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}]") }
}

Phát hiện và di chuyển bộ định tuyến biên trong trường

Nếu đang có bộ định tuyến biên nội bộ, bạn có thể sử dụng isPreferredCredentials để xác định xem bộ định tuyến biên có thuộc mạng ưu tiên hay không. API này không nhắc người dùng cấp quyền và kiểm tra thông tin xác thực của bộ định tuyến biên giới đối với nội dung được lưu trữ trong Dịch vụ Google Play.

isPreferredCredentails trả về 0 cho dữ liệu không khớp và 1 trả về đối với dữ liệu so khớp dưới dạng loại dữ liệu Int. Bạn có thể sử dụng IsPreferredCredentialsResult để kiểm tra kết quả của mình.

public @interface IsPreferredCredentialsResult {
    int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
    int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
    int PREFERRED_CREDENTIALS_MATCHED = 1;
}

Để sử dụng isPreferredCredentials, trước tiên, bạn sẽ cần tạo một đối tượng ThreadNetworkCredentials. Có một số cách để tạo ThreadNetworkCredentials. Trong các bước tiếp theo, chúng ta sẽ xem xét những tuỳ chọn này.

Chuỗi thông tin đăng nhập mạng theo Tập dữ liệu hoạt động

Có một số trường hợp mà Bộ định tuyến chuỗi của bạn đã được thiết lập với mạng Thread và bạn muốn thêm mạng Thread này vào Dịch vụ Google Play để chia sẻ với các nhà cung cấp khác. Bạn có thể tạo một thực thể của ThreadNetworkCredential từ danh sách TLV tập dữ liệu hoạt động của luồng thô:

  1. Chuyển đổi Tập dữ liệu hoạt động thành ByteArray. Ví dụ:

    val activeDataset =
          "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
    
    fun String.dsToByteArray(): ByteArray {
      return chunked(2).map { it.toInt(16).toByte() }.toByteArray()
    }
    
  2. Hãy dùng fromActiveOperationalDataset để tạo ThreadNetworkCredentials. Khi thành công, bạn sẽ có thể lấy Tên mạng chuỗi, Kênh và thông tin khác về mạng. Để biết danh sách đầy đủ các thuộc tính, hãy tham khảo ThreadNetworkIdentifiers.

    val threadNetworkCredentials =
        ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset)
    Log.d(
        "threadNetworkCredentials",
        threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
    
  3. Gọi API isPreferredCredentials và chuyển 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}]") }
    

Thông tin đăng nhập mạng của chủ sở hữu biên giới đã được tạo

Mã tác nhân biên giới xác định duy nhất một thiết bị bộ định tuyến biên. Để sử dụng API getCredentialsByBorderAgent, trước tiên, bạn sẽ cần tạo một đối tượng ThreadBorderAgent và chuyển Mã nhân viên hỗ trợ biên giới.

Sau khi bạn đã tạo đối tượng ThreadBorderAgent, hãy gọi getCredentialsByBorderAgent. Nếu thông tin đăng nhập đã được lưu, hãy kiểm tra xem thông tin này có được ưu tiên hay không.

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}]") }
}

Bằng chứng xác thực mạng chuỗi theo ID toàn bộ

Tương tự như getPreferredCredentials, bạn cũng có thể nhắc người dùng xác thực thông tin từ Mã mở rộng của bộ định tuyến biên giới. getCredentialsByExtendedPanId trả về IntentSender và kết quả Hoạt động chứa đối tượng ThreadNetworkCredentials khi người dùng phê duyệt.

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}]") }
}

Xóa thông tin đăng nhập

Khi thiết bị Bộ định tuyến biên bị xóa khỏi nhà hoặc trạng thái đặt lại về trạng thái ban đầu, bạn cần xóa mạng Thread của thiết bị đó khỏi Dịch vụ Google Play.

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}]") }
}

Tài nguyên

Để tìm hiểu thêm về SDK mạng Thread, hãy tham khảo Tài liệu tham khảo API.