SDK mạng Thread dành cho Android

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

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 ưu tiên cho mạng Thread từ Dịch vụ Google Play.
  2. Thiết lập bộ định tuyến biên mới và thêm thông tin đăng nhập mạng Thread của bạn vào Google Dịch vụ Google Play.
  3. Nếu đã có bộ định tuyến biên tại chỗ, bạn có thể kiểm tra xem đường viền của mình bộ định tuyến nằm trong mạng ưu tiên và di chuyển chú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 chúng trong hướng dẫn này, cùng với các tính năng chính khác và cách sử dụng được đề xuất.

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

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

  • Thông tin đăng nhập mạng luồng: Blob nhị phân của TLV luồng mã hoá Tên mạng luồng, Khoá mạng và các thuộc tính khác bắt buộc bởi một thiết bị Thread để kết nối với một mạng Thread cụ thể.

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

  • Mã tác nhân đường viền: Mã nhận dạng duy nhất trên toàn cầu 16 byte cho Bộ định tuyến đường viền luồng thiết bị. Mã này do các nhà cung cấp bộ định tuyến biên tạo và quản lý.

  • Ứng dụng thiết lập bộ định tuyến đường viền luồng: Đây là ứng dụng Android giúp thiết lập các thiết bị Bộ định tuyến biên Thread mới và thêm thông tin đăng nhập mạng Thread vào Dịch vụ Google Play. Ứng dụng của bạn là chủ sở hữu có thẩm quyền của nội dung được thêm vào và có quyền truy cập vào các thông tin đó.

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

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 mạng Thread sẽ trở thành chủ sở hữu của thông tin xác thực và có toàn quyền truy cập vào thông tin xác thực đó. Nếu bạn thử để truy cập vào thông tin xác thực do các ứng dụng khác thêm vào, bạn sẽ nhận được một PERMISSION_DENIED .

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

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

Thông tin xác thực phải được lưu bằng Mã nhân viên hỗ trợ biên giới. Bạn cần đảm bảo rằng ứng dụng Thiết lập Thread Border Router có thể xác định mã nhận dạng Border Agent của bộ định tuyến biên Thread.

Bộ định tuyến đường viền luồng phải sử dụng mDNS để quảng cáo thông tin mạng Thread, bao gồm cả Tên mạng, Mã liên kết mở rộng và Mã nhận dạng tác nhân đường viền. Chiến lược phát hành đĩa đơn giá trị txt tương ứng cho các thuộc tính này 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 lấy thông tin đăng nhập mạng Google Thread để sử dụng.

Tích hợp SDK vào ứng dụng Android

Để 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:

    implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0'
    
  3. Không bắt buộc: Xác định lớp dữ liệu BorderAgent để lưu trữ bộ định tuyến biên của bạn. Chúng tôi sẽ sử dụng dữ liệu đó trong suốt 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 ta sẽ xem xét các bước đề xuất để thêm và quản lý lựa chọn ưu tiên thông tin xác thực.

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

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

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

Yêu cầu thông tin xác thực

Cách nhắc người dùng cung cấp thông tin đăng nhập ưu tiên:

  1. Khai báo ActivityLauncher:

    private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  2. Xử lý kết quả Hoạt động, được 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ó thông tin đăng nhập mạng Thread ưu tiên trong tài khoản của người dùng Mạng Thread, sau đó bạn có thể sử dụng API addCredentials để thêm thông tin đăng nhập vào Dịch vụ Google Play. Để thực hiện việc này, bạn cần phải tạo một ThreadBorderAgent đồng thời cung cấp một đối tượng ThreadNetworkCredentials.

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

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

Cách chỉ định Tên mạng Thread:

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

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

Để cung cấp 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 chúng vào Dịch vụ Google Play. Trước khi chúng tôi có thể thêm thông tin xác thực, chúng ta cũng cần biết Thread này được gửi đến thiết bị bộ định tuyến biên nào thuộc về mạng nào.

Trong ví dụ này, chúng ta sẽ tạo một ThreadBorderAgent từ một Border Agent ID (Mã nhân viên hỗ trợ biên giới) và truyề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 tại trường

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

isPreferredCredentails trả về 0 cho trường hợp không khớp và 1 cho trường hợp không khớp khớp, dưới dạng loại dữ liệu Int. Bạn có thể dùng IsPreferredCredentialsResult để kiểm tra kết quả.

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

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

Tạo chuỗi thông tin xác thực mạng theo Tập dữ liệu hoạt động

Có những trường hợp mà Bộ định tuyến đường viền luồng của bạn đã được thiết lập bằng 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 ThreadNetworkCredential thực thể từ danh sách TLV tập dữ liệu hoạt động đang 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. Sử dụng fromActiveOperationalDataset để tạo ThreadNetworkCredentials. Khi thành công, bạn sẽ có thể lấy được Tên mạng Thread, Kênh và thông tin khác về mạng. Để xem danh sách đầy đủ các cơ sở lưu trú, hãy tham khảo ThreadNetworkCredentials.

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

Tạo chuỗi thông tin xác thực mạng do Border Agent thực hiện

Mã nhận dạng của Border Agent xác định duy nhất một thiết bị bộ định tuyến biên. Để sử dụng getCredentialsByBorderAgent API. Trước tiên, bạn cần tạo một ThreadBorderAgent rồi truyền mã nhận dạng tác nhân đường viền (Border Agent ID).

Sau khi bạn tạo đối tượng ThreadBorderAgent, hãy gọi getCredentialsByBorderAgent Nếu thông tin xác thực đã được lưu, hãy kiểm tra để xem nếu họ được ưu tiên sử dụ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}]") }
}

Thông tin xác thực mạng chuỗi theo ID kéo mở rộng

Tương tự như getPreferredCredentials, bạn cũng có thể nhắc người dùng thông tin xác thực từ Extended Pan ID của bộ định tuyến biên. Chiến lược phát hành đĩa đơn getCredentialsByExtendedPanId trả về IntentSender và Activity (Hoạt động) kết quả 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}]") }
}

Xoá thông tin đăng nhập

Khi thiết bị Border Router bị xoá khỏi nhà hoặc bị đặt lại về trạng thái ban đầu, bạn cần xoá mạng Thread 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ề Thread Network SDK, hãy tham khảo Tài liệu tham khảo API.