สร้างแอป Android สําหรับกรณี

1. ยินดีต้อนรับ

Matter สร้างเป้าหมายในการรวมมาตรฐาน IoT เข้าด้วยกัน โดยจะเชื่อมต่ออุปกรณ์สมาร์ทโฮมในระบบนิเวศต่างๆ เช่น Google Home, Zigbee, Bluetooth Mesh, Z-Wave และอื่นๆ

อุปกรณ์เคลื่อนที่เป็นจุดศูนย์กลางในการโต้ตอบกับอุปกรณ์สมาร์ทโฮม หากต้องการสร้างแอป Android ของคุณเองเพื่อรองรับอุปกรณ์ Matter เราช่วยให้คุณเริ่มต้นใช้งานได้อย่างรวดเร็ว

แอป Google Home ตัวอย่างสำหรับ Matter (GHSA สำหรับ Matter) จะแสดง Home Mobile SDK API ที่ช่วยให้ผู้ใช้สั่งงานและแชร์อุปกรณ์ได้ นอกจากนี้ คุณยังสามารถใช้แอปตัวอย่างเป็นเครื่องมือการเรียนรู้เพื่อทำความเข้าใจแนวคิดหลักของ Matter ให้ดียิ่งขึ้น รวมถึงใช้เครื่องมือเพื่อแก้ไขข้อบกพร่องและแก้ปัญหาการโต้ตอบกับอุปกรณ์ Matter

สิ่งที่คุณจะต้องทำ

ใน Codelab นี้ คุณจะได้ดาวน์โหลดซอร์สโค้ดของแอปตัวอย่างและดูวิธีใช้ Home Mobile SDK เพื่อมอบหมายและแชร์อุปกรณ์ และคุณยังจะได้ทราบวิธีใช้ไลบรารีการว่าจ้างและไลบรารีคลัสเตอร์จากที่เก็บ Matter (connectedhomeip) อีกด้วย

หลังจากดาวน์โหลดแอปตัวอย่างแล้ว เราจะตรวจสอบซอร์สโค้ดใน Android Studio และติดตั้ง Home Mobile SDK API ต่อไปนี้

นอกจากนี้ คุณยังดูข้อมูลเพิ่มเติมเกี่ยวกับแนวคิดการมอบหมายงาน ผ้า Matter และวิธีควบคุมอุปกรณ์ Matter ได้อีกด้วย

สิ่งที่คุณต้องมี

ก่อนที่จะเริ่ม โปรดทำตามขั้นตอนต่อไปนี้

คุณไม่จำเป็นต้องใช้ฮับ เช่น Google Nest Hub (รุ่นที่ 2) เพื่อจัดการและควบคุมอุปกรณ์ด้วยแอปตัวอย่าง

2. ตั้งค่า

แอปเริ่มต้นสำหรับ Codelab อยู่ใน Branch ของ codelab คุณสามารถดาวน์โหลดไฟล์ ZIP เพื่อเริ่มต้นทำงานกับซอร์สโค้ดของ Codelab

คุณจะใช้ไฟล์ ZIP ขนาด codelab นี้เพื่อสร้างตัวอย่างที่ใช้ได้

เวอร์ชัน Codelab

สาขา codelab ติดแท็กด้วยรุ่น 2.0.0 ของแอปตัวอย่าง หากต้องการเปรียบเทียบการอัปเดตระหว่างที่ทําแต่ละขั้นตอน ให้ดาวน์โหลดซอร์สโค้ดที่สมบูรณ์สําหรับรุ่นนี้

หากต้องการโคลนที่เก็บ GitHub ให้ทำตามวิธีการในแอปตัวอย่าง README

การอ้างอิง

เราจะแนะนำซอร์สโค้ดที่ต้องใช้ในการแชร์และจัดเตรียมอุปกรณ์ แต่เราขอแนะนำให้คุณทราบถึงทรัพยากร Dependency ต่อไปนี้ก่อนที่จะเริ่มต้นใช้งาน โปรดทราบว่ามีการประกาศทรัพยากร Dependency เหล่านี้ในไฟล์ libs.versions.toml และการใช้งานที่ระบุไว้ในไฟล์ build.gradle.kts

ซอร์สโค้ด

เราได้สร้างอินเทอร์เฟซผู้ใช้และฟังก์ชันส่วนใหญ่ไว้ให้คุณแล้ว

สำหรับ Codelab นี้ เราจะเพิ่มฟังก์ชัน Matter ลงในไฟล์ต่อไปนี้

  • java/com/google/homesampleapp/commissioning/AppCommissioningService: ให้คุณมอบหมายอุปกรณ์ให้กับฝ่ายพัฒนา
  • java/com/google/homesampleapp/screens/home/HomeScreen และ java/com/google/homesampleapp/screens/home/HomeViewModel.kt: มีฟังก์ชันการว่าจ้าง SDK สำหรับอุปกรณ์เคลื่อนที่
  • java/com/google/homesampleapp/screens/device/DeviceScreen และ java/com/google/homesampleapp/screens/device/DeviceViewModel: รวมการเรียก Share Device API

แต่ละไฟล์จะมีการแสดงความคิดเห็นเกี่ยวกับโค้ดบล็อกที่คุณจะแก้ไข ตัวอย่างเช่น

// CODELAB: add commissioningFunction()

ซึ่งจะช่วยให้คุณค้นหาส่วนที่เกี่ยวข้องใน Codelab ได้อย่างรวดเร็ว

3. ค่าคอมมิชชันสำหรับ Google

ก่อนที่คุณจะควบคุมอุปกรณ์และอนุญาตให้อุปกรณ์สื่อสารกันภายในผ้าเดียวกันได้ อุปกรณ์เหล่านี้ต้องได้รับมอบหมายจากคณะกรรมาธิการ ซึ่งในกรณีนี้คือแอปพลิเคชันตัวอย่างนี้ ซึ่งก็คือแอปตัวอย่าง Google Home สำหรับ Matter

โปรดทำความเข้าใจแนวคิดเกี่ยวกับการมอบหมายงานให้ Matter ดังนี้

  • ผ้าช่วยให้อุปกรณ์สื่อสารกันได้
  • Fabric จะเก็บข้อมูลเข้าสู่ระบบที่ไม่ซ้ำกันซึ่งใช้ร่วมกัน
  • ระบบนิเวศมีหน้าที่รับผิดชอบในการออกใบรับรองรูทที่เชื่อถือได้ กำหนดรหัส Fabric และกำหนดรหัสโหนดที่ไม่ซ้ำกัน ระบบนิเวศเป็นบริการแบ็กเอนด์ของเจ้าหน้าที่ เช่น Home Graph สําหรับระบบนิเวศของ Google Home
  • คุณจะมอบหมายอุปกรณ์ให้รองรับ Fabric ได้มากกว่า 1 เครื่อง (ฟีเจอร์สำหรับผู้ดูแลระบบหลายคน)

หากต้องการจัดเตรียมอุปกรณ์ คุณจะต้องใช้ CommissioningClient API การเรียก .commissionDevice() จะแสดงผล IntentSender ซึ่งจะเปิดกิจกรรมที่เหมาะสมในบริการ Google Play:

interface CommissioningClient {
  Task<IntentSender> commissionDevice(CommissioningRequest request);
}

ในส่วนถัดไป เราจะพูดถึงโค้ดขั้นต่ำที่จำเป็นต้องใช้สำหรับการจัดเตรียมอุปกรณ์ให้กับ Google Fabric

ขั้นตอนที่ 1: Launcher กิจกรรม

ในการจัดการ IntentSender จาก CommissioningClient คุณสามารถใช้ ActivityResultLauncher ได้ดังนี้

val commissioningLauncher = registerForActivityResult(
    StartIntentSenderForResult()
) { result: ActivityResult ->
    if (result.resultCode == RESULT_OK) {
        Timber.d(TAG, "Commissioning succeeded.")
    } else {
        Timber.d(TAG, "Commissioning failed. " + result.resultCode)
    }
}

ขั้นตอนที่ 2: ฟังก์ชันการใช้งาน

ต่อไปนี้เป็นตัวอย่างพื้นฐานที่ใช้ CommissioningClient API เพื่อจัดเตรียมอุปกรณ์ให้กับ Fabric ของ Google

  1. กระบวนการจัดเตรียมเริ่มต้นด้วยฟังก์ชัน commissionDevice() ขั้นแรก ระบบจะกำหนด CommissioningRequest การกำหนดค่าเริ่มต้นนี้ทำให้อุปกรณ์ได้รับการว่าจ้างให้ใช้กับ Android Fabric เท่านั้น
  2. Matter คือจุดแรกเข้าของ Home Mobile SDK ในการโทรครั้งถัดไป .getCommissioningClient จะได้รับค่าคอมมิชชันจาก this (กิจกรรม)
  3. .commissionDevice() ยอมรับCommissioningRequest
  4. สุดท้าย เราได้เรียก .addOnSuccessListener ให้ประมวลผล CommissioningResult และเปิดกิจกรรมในอุปกรณ์ค่าคอมมิชชันของบริการ Google Play (GPS)
private fun commissionDevice() {
    val request: CommissioningRequest = CommissioningRequest.builder().build()
    Matter.getCommissioningClient(this)
        .commissionDevice(request)
        .addOnSuccessListener { result ->
            commissioningLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
}

คุณสามารถใช้ Local Android Fabric ๆ ได้ผ่านการตั้งค่า Android เพื่อลดความซับซ้อนของการนำอุปกรณ์ไปปรับใช้กับ Fabric อื่นๆ

ต่อไป คุณจะได้เรียนรู้วิธีที่จะนำอุปกรณ์ไปพัฒนาโครงสร้าง

ดูภาพรวมของอินเทอร์เฟซผู้ใช้ระหว่างกระบวนการจัดเตรียมการใช้งานได้ที่แอปตัวอย่างของ Google Home สำหรับคู่มือ Matter

4. ค่าคอมมิชชันสำหรับการพัฒนาแอป

คุณใช้อุปกรณ์สร้างผ้าได้มากกว่า 1 ชนิด หากต้องการจัดการการจับคู่ที่เชื่อถือได้ อุปกรณ์จะจัดเก็บ FabricTable ที่มีสมาชิก FabricInfo หลายคน ตัวอย่างเช่น

  • การระบุผ้า
  • รหัสโหนดที่กำหนดโดย Fabric ให้แก่อุปกรณ์
  • รหัสผู้ให้บริการ
  • รหัส Fabric
  • ข้อมูลเข้าสู่ระบบการใช้งานอุปกรณ์

เครื่องมือจัดการโดเมนการดูแลระบบ (ADM) จะกำหนดข้อมูลเข้าสู่ระบบ Fabric ในสถานการณ์ก่อนหน้านี้ บริการ Google Play คือระบบนิเวศที่ทําหน้าที่เป็นผู้ออกใบรับรอง (CA) รูทที่เชื่อถือได้ เมื่อคุณมอบหมายอุปกรณ์ให้กับ Android Fabric ที่มีอยู่ อุปกรณ์ทุกเครื่องจะมีข้อมูลเข้าสู่ระบบ Fabric เดียวกันและ CA ชุดเดียวกัน

บริการติดตั้งใช้งานตามความต้องการของลูกค้า

ในการทำให้แพลตฟอร์ม Android Fabric ใช้งานได้ เราใช้พารามิเตอร์เริ่มต้นเพื่อสร้าง CommissioningRequest ใน CommissioningClient API ดังนี้

val request: CommissioningRequest = CommissioningRequest.builder().build()

หากต้องการควบคุมและจัดการอุปกรณ์ใหม่จากแอปของคุณ คุณต้องสร้างกระบวนการสำหรับการพัฒนาในท้องถิ่นและรับข้อมูลเข้าสู่ระบบด้านการปฏิบัติงานสำหรับอุปกรณ์ที่จะมอบหมาย ในสถานการณ์นี้ แอปของคุณจะกลายเป็นระบบนิเวศอิสระที่ไม่ซ้ำกันซึ่งกำหนดข้อมูลเข้าสู่ระบบโหนดที่เหมาะสมให้กับอุปกรณ์

คุณแจ้ง SDK บนอุปกรณ์เคลื่อนที่ว่าต้องการมอบหมายอุปกรณ์ให้กับ Fabric ของคุณเองได้โดยส่งผ่านบริการที่กำหนดเองไปยัง CommissioningRequest ดังนี้

class CommissioningRequest {
  static CommissioningRequest.Builder builder();

  class Builder {
    Builder setCommissioningService(@Nullable ComponentName commissioningService);

    CommissioningRequest build();
  }
}

ในขั้นตอนถัดไป เราจะแก้ไขฟังก์ชัน commissionDevice() เพื่อใช้บริการที่กำหนดเอง นอกจากนี้ เราจะเพิ่ม Launcher กิจกรรมลงในส่วนย่อยของหน้าแรกและใช้ออบเจ็กต์ LiveData เพื่อจัดการโฟลว์ API ด้วย

ขั้นตอนที่ 1: สร้าง Launcher กิจกรรม GPS

ก่อนอื่น ให้สร้าง Launcher กิจกรรมเพื่อจัดการ IntentSender จาก CommissioningClient API

  1. เปิด HomeScreen ในโฟลเดอร์ java/com/google/homesampleapp/screens/home/
  2. แทนที่ความคิดเห็น // CODELAB: commissionDeviceLauncher definition ด้วยรหัสต่อไปนี้เพื่อลงทะเบียนและจัดการผลลัพธ์ของกิจกรรมที่มอบหมายงาน
    val commissionDeviceLauncher =
      rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartIntentSenderForResult()
      ) { result ->
        // Commission Device Step 5.
        // The Commission Device activity in GPS (step 4) has completed.
        val resultCode = result.resultCode
        if (resultCode == Activity.RESULT_OK) {
          Timber.d("CommissionDevice: Success")
          // We let the ViewModel know that GPS commissioning has completed successfully.
          // The ViewModel knows that we still need to capture the device name and will\
          // update UI state to trigger the NewDeviceAlertDialog.
          homeViewModel.gpsCommissioningDeviceSucceeded(result)
        } else {
          homeViewModel.commissionDeviceFailed(resultCode)
        }
      }
    

ขั้นตอนที่ 2: ทริกเกอร์การดำเนินการกับอุปกรณ์ค่าคอมมิชชัน

ในขั้นตอนนี้ ผู้ใช้จะทริกเกอร์ "อุปกรณ์ค่าคอมมิชชัน" โดยคลิกที่เครื่องหมาย "+" ที่ด้านล่างขวาของหน้าจอหลัก จากนั้นจะโทรหา commissionDevice()

val onCommissionDevice = {
  ...
  commissionDevice(activity!!.applicationContext, commissionDeviceLauncher)
}

ขั้นตอนที่ 3: เรียกใช้ API

  1. ยังคงอยู่ที่ HomeScreen.kt ในโฟลเดอร์ java/com/google/homesampleapp/screens/home
  2. แทนที่ความคิดเห็น // CODELAB: commissionDevice ด้วย commissionDeviceRequest ต่อไปนี้ setCommissioningService จะเชื่อมโยง AppCommissioningService กับอินสแตนซ์ CommissioningService ซึ่งแสดงผลในฟังก์ชัน Callback เมื่อคุณผ่านบริการที่กำหนดเอง Home Mobile SDK จะมอบหมายอุปกรณ์ให้กับ Fabric ในพื้นที่ของ Android ก่อน แล้วจึงส่งเพย์โหลดการเริ่มต้นใช้งานกลับไปยัง AppCommissioningService
    val commissionDeviceRequest =
        CommissioningRequest.builder()
            .setCommissioningService(ComponentName(
                context, AppCommissioningService::class.java))
            .build()
    
  3. โทร .getCommissioningClient() ต่อด้วย .commissionDevice()
Matter.getCommissioningClient(context)
    .commissionDevice(commissionDeviceRequest)

เพื่อให้ฟังก์ชัน commissionDevice เสร็จสมบูรณ์ ให้เพิ่ม addOnSuccessListener และ addOnFailureListener:

    .addOnSuccessListener { result ->
      commissionDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
    }
    .addOnFailureListener { error ->
      Timber.e(error)
    }

5. สร้างบริการการจัดเตรียม

ในฟังก์ชัน commissionDevice() เราขอ CommissioningService จาก CommissioningClient API ในขั้นตอนนี้ CommissioningClient API จะมอบหมายอุปกรณ์ไปยัง Fabric Android ในพื้นที่ก่อน จากนั้นจะส่งกลับ Callback ที่มีออบเจ็กต์ CommissioningRequestMetadata ดังนี้

public interface CommissioningService {
interface Callback {
    void onCommissioningRequested(CommissioningRequestMetadata metadata);
  }
}

ตอนนี้ เราจะต้องรับค่า CommissioningService.Callback และระบุฟังก์ชันที่จำเป็นในการมอบฟังก์ชันให้กับอุปกรณ์ไปยังแอปตัวอย่างของเรา ต่อไปนี้คือตัวอย่างการใช้งาน CommissioningService เบื้องต้น

class MatterCommissioningService : Service(), CommissioningService.Callback {
   private val commissioningServiceDelegate =
     CommissioningService.Builder(this)
       .setCallback(this)
       .build()

   override fun onBind(intent: Intent) = commissioningServiceDelegate.asBinder()

   override fun onCommissioningRequested(metadata: CommissioningRequestMetadata) {
     // perform commissioning

     commissioningServiceDelegate
       .sendCommissioningComplete(CommissioningCompleteMetadata.builder().build())
   }
 }

ขั้นตอนที่ 1: สำรวจ AppCommissioningService ที่กำหนดเอง

เพื่อช่วยคุณเริ่มต้นใช้งาน เราได้กำหนดโครงสร้างพื้นฐานของชั้นเรียนสำหรับ CommissioningService ที่กำหนดเองไว้แล้ว ต่อไปนี้เป็นภาพรวมคร่าวๆ ของฟังก์ชันการทำงานของบริการ หากต้องการติดตามข้อมูลนี้ ให้เปิด AppCommissioningService ใน java/commissioning

เราได้เพิ่มการนำเข้าต่อไปนี้สำหรับ Home Mobile SDK API

import com.google.android.gms.home.matter.commissioning.CommissioningCompleteMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningRequestMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningService

AppCommissioningService ยังรวมถึงไลบรารีจากที่เก็บ Matter (connectedhomeip) ด้วย

import com.google.homesampleapp.chip.ChipClient

บริการสุดท้ายรวมถึงการนำเข้าเพื่อรองรับ Hilt และ Kotlin coroutines

ต่อไป เราจะสร้างเครื่องมือสร้างและตั้งค่าบางอย่าง รวมถึง commissioningServiceDelegate ซึ่งเราจะใช้เพื่อแจ้งให้บริการ Google Play ทราบเมื่อการทำให้ใช้งานได้เสร็จสมบูรณ์

private lateinit var commissioningServiceDelegate: CommissioningService
...
commissioningServiceDelegate = CommissioningService.Builder(this).setCallback(this).build()

ตอนนี้ได้เวลาเพิ่มฟังก์ชันการว่าจ้างแล้ว

ขั้นตอนที่ 2: ลบล้าง onCommissioningRequested

หากต้องการมอบหมายอุปกรณ์ให้กับผ้าสำหรับการพัฒนาแอป ให้ทำตามขั้นตอนต่อไปนี้

  1. เปิด AppCommissioningService ใน java/commissioning
  2. ค้นหาฟังก์ชัน onCommissioningRequested() เราได้ส่งข้อความบันทึกที่พิมพ์ CommissioningRequestMetadata แล้ว แทนที่ความคิดเห็น // CODELAB: onCommissioningRequested() เพื่อเริ่มโครูทีน serviceScope และรับ deviceId
    // Perform commissioning on custom fabric for the sample app.
    serviceScope.launch {
      val deviceId = devicesRepository.incrementAndReturnLastDeviceId()
    
  3. จัดเตรียมระบบ ในขั้นตอนนี้ เราจะส่งข้อมูลอุปกรณ์ที่แสดงผลในออบเจ็กต์ CommissioningRequestMetadata ChipClient จะใช้ข้อมูลเมตานี้เพื่อสร้างช่องทางที่ปลอดภัยระหว่าง GHSA สำหรับแอป Matter กับอุปกรณ์ของคุณ
    try {
      Timber.d(
          "Commissioning: App fabric -> ChipClient.establishPaseConnection(): deviceId [${deviceId}]")
      chipClient.awaitEstablishPaseConnection(
          deviceId,
          metadata.networkLocation.ipAddress.hostAddress!!,
          metadata.networkLocation.port,
          metadata.passcode)
      Timber.d(
          "Commissioning: App fabric -> ChipClient.commissionDevice(): deviceId [${deviceId}]")
      chipClient.awaitCommissionDevice(deviceId, null)
    } catch (e: Exception) {
      Timber.e(e, "onCommissioningRequested() failed")
      // No way to determine whether this was ATTESTATION_FAILED or DEVICE_UNREACHABLE.
      commissioningServiceDelegate
          .sendCommissioningError(CommissioningError.OTHER)
          .addOnSuccessListener {
            Timber.d(
                "Commissioning: commissioningServiceDelegate.sendCommissioningError() succeeded")
          }
          .addOnFailureListener { e2 ->
            Timber.e(e2, "Commissioning: commissioningServiceDelegate.sendCommissioningError() failed")
          }
      return@launch
    }
    
  4. ใช้ commissioningServiceDelegate เพื่อแจ้งให้บริการ Google Play ทราบว่าการว่าจ้างเสร็จสมบูรณ์แล้ว ใน.sendCommissioningComplete() ให้ผ่านการตรวจสอบ CommissioningCompleteMetadata
    commissioningServiceDelegate
        .sendCommissioningComplete(
            CommissioningCompleteMetadata.builder().setToken(deviceId.toString()).build())
        .addOnSuccessListener {
          Timber.d("Commissioning: commissioningServiceDelegate.sendCommissioningComplete() succeeded")
        }
        .addOnFailureListener { e ->
          Timber.e(e, "Commissioning: commissioningServiceDelegate.sendCommissioningComplete() failed")
        }
    }
    

เรียกใช้แอป

เมื่อได้โค้ดทั้งหมดที่จำเป็นแล้ว ไปยังแพลตฟอร์มของเราได้แล้ว ก็ได้เวลาทดสอบ เลือกอุปกรณ์ Android แล้วเรียกใช้แอป จากหน้าจอหลัก ให้แตะเพิ่มอุปกรณ์ แล้วทำตามขั้นตอนเพื่อจัดเตรียมอุปกรณ์ให้เสร็จเรียบร้อย

เมื่อมอบหมายเสร็จสมบูรณ์แล้ว อุปกรณ์ของคุณจะมี 2 ประเภท ได้แก่ แพลตฟอร์ม Android Fabric สำหรับการพัฒนาในท้องถิ่น และ Fabric การพัฒนาพื้นที่ของคุณ ผ้าแต่ละแบบจะมีชุดข้อมูลเข้าสู่ระบบของตัวเองและรหัส Fabric 64 บิตที่ไม่ซ้ำกัน

6. ควบคุมอุปกรณ์

การใช้ระบบสำหรับการพัฒนาจะช่วยให้คุณใช้ไลบรารีจากที่เก็บ Matter (connectedhomeip) เพื่อควบคุมอุปกรณ์จากแอปตัวอย่างได้

เราได้สร้างคลาสตัวช่วยเพื่อให้เข้าถึงคลัสเตอร์ของอุปกรณ์และส่งคำสั่งได้ง่ายขึ้น เปิด ClustersHelper ใน java/clusters เพื่อดูข้อมูลเพิ่มเติม ตัวช่วยของ Singleton นี้จะนำเข้าไลบรารีต่อไปนี้เพื่อเข้าถึงข้อมูลอุปกรณ์

import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipStructs

เราสามารถใช้คลาสนี้เพื่อรับคลัสเตอร์เปิด/ปิดของอุปกรณ์ จากนั้นโทรไปที่ .toggle

suspend fun toggleDeviceStateOnOffCluster(deviceId: Long, endpoint: Int) {
  Timber.d("toggleDeviceStateOnOffCluster())")
  val connectedDevicePtr =
      try {
        chipClient.getConnectedDevicePointer(deviceId)
      } catch (e: IllegalStateException) {
        Timber.e("Can't get connectedDevicePointer.")
        return
      }
  return suspendCoroutine { continuation ->
    getOnOffClusterForDevice(connectedDevicePtr, endpoint)
        .toggle(
            object : ChipClusters.DefaultClusterCallback {
              override fun onSuccess() {
                continuation.resume(Unit)
              }
              override fun onError(ex: Exception) {
                Timber.e("readOnOffAttribute command failure: $ex")
                continuation.resumeWithException(ex)
              }
            })
  }
}

เปิด/ปิดอุปกรณ์

หลังจากที่กำหนดอุปกรณ์แล้ว ระบบจะเพิ่มเพย์โหลดที่แสดงผลใน CommissioningResult ไปยัง DataStore วิธีนี้ช่วยให้แอปเข้าถึงข้อมูลอุปกรณ์ที่เราใช้ส่งคำสั่งได้

แอป Matter จะขับเคลื่อนด้วยเหตุการณ์ เมื่อเริ่มต้นสแต็ก Matter บริการคลัสเตอร์จะคอยฟังข้อความขาเข้า เมื่อมีการมอบหมายอุปกรณ์แล้ว ไคลเอ็นต์ Matter จะส่งคำสั่งผ่านช่องทางการดำเนินการที่ปลอดภัยซึ่งสร้างขึ้นระหว่างการแจกจ่ายอุปกรณ์

ในอุปกรณ์ แพ็กเก็ตจะได้รับการตรวจสอบ ถอดรหัส แล้วส่งด้วย Callback ฟังก์ชัน Callback ได้แก่ EndpointId, ClusterId และ AttributeId ซึ่งเข้าถึงได้จาก attributePath เช่น โค้ดนี้ติดตั้งใช้งานในอุปกรณ์ Matter ได้

void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type,
                                       uint16_t size, uint8_t * value)
{
    // handle callback
    ClusterId clusterId     = attributePath.mClusterId;
    AttributeId attributeId = attributePath.mAttributeId;
}

ในขั้นตอนถัดไป คุณจะใช้ Matter SDK และ ClustersHelper เพื่อเปิด/ปิดอุปกรณ์

  1. ไปที่ DeviceViewModel ใน java/screens/device
  2. ค้นหาฟังก์ชัน updateDeviceStateOn
  3. แทนที่ความคิดเห็น // CODELAB: toggle ด้วยรหัสที่จะเรียก clustersHelper จากนั้นอัปเดตที่เก็บของอุปกรณ์:
    Timber.d("Handling real device")
        try {
          clustersHelper.setOnOffDeviceStateOnOffCluster(deviceUiModel.device.deviceId, isOn, 1)
          devicesStateRepository.updateDeviceState(deviceUiModel.device.deviceId, true, isOn)
        } catch (e: Throwable) {
          Timber.e("Failed setting on/off state")
        }
    

ฟังก์ชันนี้เรียกจาก DeviceScreen:

// On/Off Switch click.
val onOnOffClick: (value: Boolean) -> Unit = { value ->
  deviceViewModel.updateDeviceStateOn(deviceUiModel!!, value)
}

เรียกใช้แอป

เรียกใช้แอปเพื่อโหลดการอัปเดตซ้ำ สลับอุปกรณ์เป็นเปิดและปิดจากหน้าจอหลัก

7. แชร์อุปกรณ์กับระบบนิเวศอื่นๆ

การแชร์อุปกรณ์เรียกว่าขั้นตอนสำหรับผู้ดูแลระบบหลายคนในข้อกำหนดของ Matter

ในขั้นตอนก่อนหน้านี้ เราได้เรียนรู้ว่า Home Mobile SDK ทำให้สามารถส่งอุปกรณ์ไปยัง Android Fabric ได้และยังพัฒนา Fabric สำหรับการพัฒนาซอฟต์แวร์สำหรับแอปตัวอย่างอีกด้วย นี่คือตัวอย่างของขั้นตอนสำหรับผู้ดูแลระบบหลายคน ซึ่งกำหนดให้อุปกรณ์ใช้ผ้าได้มากกว่า 1 เครื่อง

ตอนนี้คุณอาจต้องการแชร์อุปกรณ์กับผ้าจำนวนมากขึ้น โดยเฉพาะอย่างยิ่งหากเป็นครอบครัวที่ผู้คนมีความต้องการเป็นของตนเองเมื่อใช้แอปพลิเคชันและแพลตฟอร์ม

Home Mobile SDK มีฟังก์ชันการทำงานนี้ใน ShareDeviceRequest API ซึ่งช่วยให้คุณทำสิ่งต่อไปนี้ได้

  1. เปิดหน้าต่างการว่าจ้างชั่วคราวสำหรับอุปกรณ์
  2. เปลี่ยนสถานะของอุปกรณ์เพื่อสั่งทำเป็นผ้าสำรอง
  3. ควบคุมอุปกรณ์ของคุณจากแอปและระบบนิเวศอื่นๆ

ในขั้นตอนถัดไป คุณจะใช้ Home Mobile SDK เพื่อแชร์อุปกรณ์

ขั้นตอนที่ 1: สร้าง Launcher กิจกรรม GPS

เราได้สร้าง Launcher กิจกรรมการแชร์อุปกรณ์เพื่อจัดการ IntentSender จาก CommissioningClient API ซึ่งคล้ายกับ Launcher กิจกรรม Commissioning ที่เราสร้างขึ้นเมื่อเปลี่ยนไปใช้โครงสร้างการพัฒนา

  1. เปิด DeviceScreen ในโฟลเดอร์ java/com/google/homesampleapp/screens/device/
  2. แทนที่ความคิดเห็น // CODELAB: shareDeviceLauncher definition ด้วยรหัสต่อไปนี้เพื่อลงทะเบียนและจัดการผลลัพธ์ของ .shareDevice()
    val shareDeviceLauncher = rememberLauncherForActivityResult(
      contract = ActivityResultContracts.StartIntentSenderForResult()
    ) { result ->
      // Commission Device Step 5.
      // The Share Device activity in GPS (step 4) has completed.
      val resultCode = result.resultCode
      if (resultCode == Activity.RESULT_OK) {
        deviceViewModel.shareDeviceSucceeded()
      } else {
        deviceViewModel.shareDeviceFailed(resultCode)
      }
    }
    

ขั้นตอนที่ 2: ทริกเกอร์การดำเนินการแชร์อุปกรณ์

ในขั้นตอนนี้ ผู้ใช้จะทริกเกอร์ "แชร์อุปกรณ์" โดยคลิกที่ "แชร์" บนหน้าจออุปกรณ์ ระบบจะโทรหา deviceViewModel เพื่อเปิดหน้าต่างการจับคู่สำหรับการแชร์อุปกรณ์

// Share Device button click.
val onShareDevice: () -> Unit = remember {
 {
   deviceViewModel.openPairingWindow(deviceUiModel!!.device.deviceId)
 }
}

หลังจากเปิดหน้าต่างแยกวิเคราะห์สำเร็จแล้ว deviceViewModel จะแจ้งข้อเท็จจริงดังกล่าวกับ UI การสื่อสารระหว่าง ViewModel กับ UI จะดำเนินการผ่านออบเจ็กต์ StateFlow

// Communicate to the UI that the pairing window is open.
// UI can then launch the GPS activity for device sharing.
_pairingWindowOpenForDeviceSharing.value = true

หลังจากเห็นการเปลี่ยนแปลงในออบเจ็กต์ StateFlow แล้ว DeviceScreen จะทำการเรียกต่อไปนี้

shareDevice(activity!!.applicationContext, shareDeviceLauncher, deviceViewModel)

ขั้นตอนที่ 3: เรียกใช้ API

ได้เวลาเริ่มงานแชร์อุปกรณ์แล้ว

  1. เปิด DeviceScreen.kt ในโฟลเดอร์ java/com/google/homesampleapp/screens/device/
  2. ค้นหาฟังก์ชัน shareDevice() แทนที่ความคิดเห็น // CODELAB: shareDevice ด้วย ShareDeviceRequest DeviceDescriptor ให้ข้อมูลเฉพาะเกี่ยวกับอุปกรณ์ เช่น รหัสผู้ให้บริการ รหัสผลิตภัณฑ์ และประเภทอุปกรณ์ ในตัวอย่างนี้ เราจะฮาร์ดโค้ดค่า
    val shareDeviceRequest =
      ShareDeviceRequest.builder()
        .setDeviceDescriptor(DeviceDescriptor.builder().build())
        .setDeviceName("GHSAFM temp device name")
    
  3. ตั้งค่า CommissioningWindow และ parameters
        .setCommissioningWindow(
            CommissioningWindow.builder()
                .setDiscriminator(Discriminator.forLongValue(DISCRIMINATOR))
                .setPasscode(SETUP_PIN_CODE)
                .setWindowOpenMillis(SystemClock.elapsedRealtime())
                .setDurationSeconds(OPEN_COMMISSIONING_WINDOW_DURATION_SECONDS.toLong())
                .build())
        .build()
    
  4. เรียกใช้ .getCommissioningClient() เฉพาะครั้งนี้โดยใช้ .shareDevice() API
    Matter.getCommissioningClient(context)
        .shareDevice(shareDeviceRequest)
    

การเรียกกลับที่สำเร็จของ commissioningClient.shareDevice() API จะระบุ IntentSender สำหรับการเรียกใช้ "แชร์กิจกรรมของอุปกรณ์" ในบริการ Google Play

  1. เพิ่ม addOnSuccessListener และ addOnFailureListener เพื่อให้ฟังก์ชัน shareDevice เสร็จสมบูรณ์ เมื่อดำเนินการสำเร็จ ระบบจะเรียกใช้ launch ใน shareDeviceLauncher เพื่อเปิดกิจกรรม GPS สำหรับการแชร์อุปกรณ์
        .addOnSuccessListener { result ->
          Timber.d("ShareDevice: Success getting the IntentSender: result [${result}]")
          shareDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
        .addOnFailureListener { error ->
          Timber.e(error)
          deviceViewModel.showMsgDialog("Share device failed", error.toString())
        }
    

เรียกใช้แอป

หากต้องการแชร์อุปกรณ์ Matter กับระบบนิเวศอื่นๆ คุณจะต้องติดตั้งแพลตฟอร์มอื่นในอุปกรณ์ Android เราได้สร้างอินสแตนซ์อีกรายการหนึ่งสำหรับแอปตัวอย่างที่คุณสามารถใช้เป็นเจ้าหน้าที่เป้าหมายได้

เมื่อติดตั้งค่าคอมมิชชันเป้าหมายในอุปกรณ์ Android แล้ว ให้ยืนยันว่าคุณแชร์อุปกรณ์ Matter ได้ แอปค่าคอมมิชชันเป้าหมายจะติดป้ายกำกับเป็น GHSAFM-TC

อุปกรณ์ของคุณเข้าร่วมได้ 3 ประเภท ดังนี้

  1. Android Fabric ของท้องถิ่น
  2. ผ้าสำหรับการพัฒนา (แอปนี้)
  3. ผ้าตัวที่ 3 นี้ที่คุณเพิ่งแชร์อุปกรณ์ด้วย

8. ขั้นตอนถัดไป

ขอแสดงความยินดี

ยินดีด้วย คุณทำภารกิจ Codelab นี้เสร็จแล้ว และได้เรียนรู้วิธีมอบหมายและแชร์อุปกรณ์โดยใช้ Home Mobile SDK

หากคุณมีปัญหากับแอปตัวอย่าง ให้ลองทำตามขั้นตอนต่างๆ เพื่อยืนยันสภาพแวดล้อมของคุณ

หากคุณมีคำถามเกี่ยวกับการใช้แอปตัวอย่างหรือค้นพบข้อบกพร่องของโค้ด คุณส่งปัญหาไปยังตัวติดตามปัญหาในที่เก็บ GitHub ได้โดยทำดังนี้

หากต้องการคำแนะนำอย่างเป็นทางการจาก Google สำหรับคำถามทางเทคนิค โปรดไปที่ฟอรัมนักพัฒนาซอฟต์แวร์สมาร์ทโฮม

หากต้องการรับการสนับสนุนด้านเทคนิคจากชุมชน ให้ใช้แท็ก google-smart-home ใน Stack Overflow