Permissions API ใน Android

ก่อนที่จะใช้ Home API ใดๆ สำหรับ Android แอปต้องมีสิทธิ์เข้าถึงอุปกรณ์ในบ้านของผู้ใช้ ซึ่งใน API จะเรียกว่า โครงสร้าง โดยผู้ใช้สามารถใช้บัญชี Google ของตนเองเพื่อให้สิทธิ์แอป Home API เข้าถึงอุปกรณ์ในบ้านได้ด้วย Permissions API

โฟลว์การให้สิทธิ์ช่วยให้ผู้ใช้สร้างโครงสร้างได้หากยังไม่ได้ตั้งค่าไว้ โดยไม่ต้องใช้Google Home app (GHA)

ผสานรวม Permissions API

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

ขั้นแรก ให้ลงทะเบียน ActivityResultCaller กับ SDK ตัวอย่างเช่น แอปตัวอย่างจะจัดการดังนี้

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    homeManager.registerActivityResultCallerForPermissions(this)
  }

ตรวจสอบสิทธิ์

ก่อนที่จะขอสิทธิ์ เราขอแนะนำให้ตรวจสอบว่าผู้ใช้แอปได้ให้ความยินยอมในการเข้าถึงโครงสร้างแล้วหรือไม่ หากต้องการตรวจสอบ ให้เรียกใช้ เมธอด hasPermissions() ของอินสแตนซ์ Home เพื่อรับ Flow ของ PermissionsState ค่าดังนี้

val permissionsReadyState =
homeManager.hasPermissions().collect { state ->
    when (state) {
      PermissionsState.GRANTED -> println("Permissions granted, no need to request permissions")
      PermissionsState.PERMISSIONS_STATE_UNAVAILABLE ->
          println("Permissions state unavailable, request permissions")

      PermissionsState.NOT_GRANTED ->
          println("OAuth permission is enabled but not granted yet, request permissions")

      PermissionsState.PERMISSIONS_STATE_UNINITIALIZED -> println(
          "Permissions state is not initialized yet. Clients should wait for another status update"
      )
      else ->
          throw IllegalStateException("""
            HomeClient.hasPermissions state should be PermissionsState.GRANTED,
            PermissionState.PERMISSIONS_STATE_UNINITIALIZED, or
            PermissionsState.PERMISSIONS_STATE_UNAVAILABLE. Actual state: $state
          """.trimIndent())
    }
}

หากการตรวจสอบแสดง PermissionsState เป็น NOT_GRANTED หรือ PERMISSIONS_STATE_UNAVAILABLE หมายความว่าผู้ใช้หรือแอปพลิเคชันไม่มีสิทธิ์เข้าถึงโครงสร้าง หากการตรวจสอบแสดง PermissionsState เป็น GRANTED แต่การเรียกใช้ structures() ในภายหลังไม่แสดงโครงสร้างใดๆ หมายความว่าผู้ใช้ได้เพิกถอนสิทธิ์เข้าถึง แอปผ่านหน้าการตั้งค่า GHA หรือผู้ใช้ ไม่มีสิทธิ์เข้าถึงที่จำเป็น

ขอสิทธิ์

คุณต้องได้รับสิทธิ์เข้าถึงโครงสร้างและอุปกรณ์ภายในโครงสร้างที่กำหนด

หากผู้ใช้ยังไม่ได้ให้สิทธิ์ ให้ใช้ requestPermissions() เมธอดของอินสแตนซ์ Home เพื่อเปิด UI การให้สิทธิ์และประมวลผลผลลัพธ์

fun requestPermissions(scope: CoroutineScope, onShowSnackbar: (String) -> Unit) {
  scope.launch {
    val result =
      try {
        homeManager.requestPermissions()
      } catch (e: HomeException) {
        PermissionsResult(
          PermissionsResultStatus.ERROR,
          "Got HomeException with error: ${e.message}",
        )
      }
    when (result.status) {
      PermissionsResultStatus.SUCCESS -> {
        Log.i(TAG, "Permissions successfully granted.")
      }
      PermissionsResultStatus.CANCELLED -> {
        Log.i(TAG, "User cancelled Permissions flow.")
        onShowSnackbar("User cancelled Permissions flow")
      }
      else -> {
        Log.e(
          TAG,
          "Failed to grant permissions with error: ${result.status}, ${result.errorMessage}",
        )
        onShowSnackbar("Failed to grant permissions with error: ${result.errorMessage}")
      }
    }
  }
}
PermissionsManager

คุณต้อง ตั้งค่า OAuth สำหรับแอปเรียบร้อยแล้วเพื่อให้ UI การให้สิทธิ์เปิดขึ้นอย่างถูกต้อง

ให้สิทธิ์

ตอนนี้คุณควรจะเรียกใช้แอปและให้ผู้ใช้ให้สิทธิ์ได้แล้ว ประเภทของผู้ใช้ที่ให้สิทธิ์ได้และประเภทอุปกรณ์ที่ให้สิทธิ์ได้จะแตกต่างกันไปตามว่าคุณได้ลงทะเบียนแอปใน Google Home Developer Console หรือไม่

Developer Console ต้องลงทะเบียนเพื่อเผยแพร่แอปโดยใช้ Home API แต่ไม่จำเป็นต้องลงทะเบียนเพื่อทดสอบและใช้ Home API

หากแอปไม่ได้ลงทะเบียนใน Developer Console แอปจะอยู่ใน สถานะ ไม่ได้รับการยืนยัน เราขอแนะนำให้ใช้สถานะนี้เพื่อทดสอบการใช้ Home API

  • เฉพาะผู้ใช้ที่ลงทะเบียนเป็นผู้ใช้ทดสอบในคอนโซล OAuthเท่านั้นที่จะให้สิทธิ์ สำหรับแอปได้ แอปที่ไม่ได้รับการยืนยันจะมีผู้ใช้ทดสอบได้สูงสุด 100 ราย

  • แอปที่ไม่ได้รับการยืนยันจะมีสิทธิ์เข้าถึงอุปกรณ์ทุกประเภทที่ OAuth สำหรับ Home API รองรับ (รายการประเภทอุปกรณ์ใน Developer Console) ระบบจะให้สิทธิ์เข้าถึงอุปกรณ์ทั้งหมดในโครงสร้าง

หาก แอปได้ลงทะเบียนใน Developer Console และ ได้รับการอนุมัติให้เข้าถึงอุปกรณ์อย่างน้อย 1 ประเภท รวมถึงการยืนยัน แบรนด์สำหรับ OAuthเสร็จสมบูรณ์แล้ว แอปจะอยู่ในสถานะ ได้รับการยืนยัน คุณต้องมีสถานะนี้เพื่อเปิดตัวแอปในเวอร์ชันที่ใช้งานจริง

  • ไม่มีการจำกัดผู้ใช้ทดสอบอีกต่อไป ผู้ใช้ทุกคนสามารถให้สิทธิ์เข้าถึงแอปได้
  • ผู้ใช้จะให้สิทธิ์เข้าถึงได้เฉพาะอุปกรณ์ประเภทที่ได้รับการอนุมัติใน the Developer Console.

เมื่อตั้งค่า OAuth แล้ว การเรียกใช้ requestPermissions() ของแอปจะทริกเกอร์กล่องโต้ตอบต่อไปนี้

  1. ระบบจะแจ้งให้ผู้ใช้เลือกบัญชี Google ที่ต้องการใช้
  2. ระบบจะแจ้งให้ผู้ใช้เลือกโครงสร้างที่ต้องการให้สิทธิ์เข้าถึงแอป
    1. สำหรับแอปที่ไม่ได้รับการยืนยัน แอปจะเข้าถึงอุปกรณ์ทุกประเภทที่ Home API รองรับได้
    2. สำหรับแอปที่ได้รับการยืนยัน ผู้ใช้จะให้สิทธิ์เข้าถึงได้เฉพาะอุปกรณ์ประเภทที่ได้รับการอนุมัติใน Developer Console
    3. สำหรับอุปกรณ์ประเภทที่มีความละเอียดอ่อนซึ่งแอปมีสิทธิ์เข้าถึงเพื่อจัดการ ผู้ใช้สามารถจำกัดสิทธิ์เข้าถึงอุปกรณ์แต่ละเครื่องได้ เช่น หากผู้ใช้มีล็อก 3 รายการ ผู้ใช้จะให้สิทธิ์เข้าถึงล็อกได้เพียง 1 รายการเท่านั้น
  • ความยินยอม OAuth - เลือกบัญชี
  • ความยินยอม OAuth - ลิงก์อุปกรณ์ 01
  • ความยินยอม OAuth - ลิงก์อุปกรณ์ 02
รูปที่ 1: ตัวอย่างโฟลว์การขอความยินยอม OAuth

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

เปลี่ยนแปลงสิทธิ์

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

คุณสามารถทำได้โดยเรียกใช้ requestPermissions() อีกครั้งโดยตั้งค่าแฟล็ก forceLaunch เป็น true ดังนี้

homeManager.requestPermissions(forceLaunch=true)

เพิกถอนสิทธิ์

ผู้ใช้สามารถเพิกถอนสิทธิ์เข้าถึงที่ให้ไว้ก่อนหน้านี้ได้โดยทำดังนี้

  1. ผ่านหน้า บัญชีของฉันใน Google > ข้อมูลและความเป็นส่วนตัว > แอปและบริการของบุคคลที่สาม การดำเนินการนี้จะเพิกถอนโทเค็น OAuth ที่ออกให้เมื่อมีการให้ความยินยอมครั้งแรก และจะเพิกถอนสิทธิ์เข้าถึงอินสแตนซ์ของแอปที่ผู้ใช้กำลังใช้งานในทุกแพลตฟอร์ม (โทรศัพท์) และโครงสร้าง

    ระบบอาจเปลี่ยนเส้นทางผู้ใช้ด้วย Deep Link ไปยังหน้าย่อยแอปและบริการของบุคคลที่สาม โดยใช้ URL Scheme ต่อไปนี้

    https://myaccount.google.com/connections/link?project_number=Cloud project_number
    
  2. ผ่านหน้า GHA > การตั้งค่า > แอปที่ลิงก์ การคลิกที่ ใน GHA จะนำคุณไปยัง หน้า การตั้งค่า จากนั้นคลิกการ์ดแอปที่ลิงก์ ซึ่งจะนำคุณไปยังหน้าที่มีลักษณะคล้ายกับหน้าจอขอความยินยอม จากหน้านี้ ผู้ใช้สามารถนำสิทธิ์เข้าถึงแอปออกได้ นอกจากนี้ ผู้ใช้ยังใช้หน้าเดียวกันนี้เพื่อเปลี่ยนประเภทอุปกรณ์หรืออุปกรณ์ที่มีความละเอียดอ่อนที่แอปเข้าถึงได้

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

หากต้องการตรวจสอบว่าผู้ใช้ได้ให้สิทธิ์เข้าถึงอุปกรณ์ประเภทที่มีความละเอียดอ่อนหรือถูกจำกัดหรือไม่ ให้ใช้ฟังก์ชัน consentedDeviceTypes() ระดับโครงสร้าง

import com.google.home.Structure
import com.google.home.DeviceType
import com.google.home.DeviceTypeFactory
import com.google.home.consentedDeviceTypes // Extension function from the SDK
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * Example of how an app may monitor which device types have been granted access by a user.
 */
fun monitorDeviceConsent(structure: Structure, myScope: CoroutineScope) {
    // Obtain the flow of consented device type factories
    val consentedTypesFlow: Flow<Set<DeviceTypeFactory<out DeviceType>>> =
        structure.consentedDeviceTypes()

    myScope.launch {
        consentedTypesFlow.collect { consentedSet ->
            // Check if the user has consented to share a specific restricted
            // type, such as a Doorbell or Camera.
            val hasCameraAccess = consentedSet.any {
                it.toString() == "matter.google.type.GoogleDoorbellDevice"
            }

            if (hasCameraAccess) {
                // Enable features that require camera access
            } else {
                // Inform the user or disable camera-specific features
            }
        }
    }
}

สิทธิ์ OkGoogle

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

การทำงานอัตโนมัติ ลักษณะ การบังคับใช้สิทธิ์
เมื่อถึงเวลา 22:00 น. ให้ประกาศว่า "ได้เวลานอนแล้ว" ผ่านลำโพงห้องนอน AssistantBroadcastTrait ในอุปกรณ์ การสร้างการทำงานอัตโนมัติ:
  • อุปกรณ์ที่ใช้ประกาศต้องเป็นอุปกรณ์ Assistant
  • แอปและผู้ใช้ต้องมีสิทธิ์เข้าถึงอุปกรณ์ที่ใช้ประกาศ
การดำเนินการการทำงานอัตโนมัติ:
  • แอปและผู้ใช้ต้องมีสิทธิ์เข้าถึงอุปกรณ์ที่ใช้ประกาศ
เมื่อถึงเวลา 22:00 น. ให้ประกาศว่า "ได้เวลานอนแล้ว" ผ่านอุปกรณ์ทุกเครื่อง AssistantBroadcastTrait ในโครงสร้าง การสร้างการทำงานอัตโนมัติ:
  • ต้องมีอุปกรณ์ Assistant อย่างน้อย 1 เครื่องในโครงสร้าง ที่แอปและผู้ใช้มีสิทธิ์เข้าถึง
  • แอปและผู้ใช้ต้องมีสิทธิ์เข้าถึงโครงสร้าง
การดำเนินการการทำงานอัตโนมัติ:
  • แอปและผู้ใช้ต้องมีสิทธิ์เข้าถึงโครงสร้าง
เมื่อถึงเวลา 22:00 น. ให้ "เปิดเพลงหน่อย" AssistantFulfillmentTrait.OkGoogleCommand การสร้างการทำงานอัตโนมัติ:
  • แอปและผู้ใช้ต้องมีสิทธิ์เข้าถึงอุปกรณ์ที่ การทำงานอัตโนมัติส่งคำสั่ง
การดำเนินการการทำงานอัตโนมัติ:
  • แอปและผู้ใช้ต้องมีสิทธิ์เข้าถึงอุปกรณ์ที่ การทำงานอัตโนมัติส่งคำสั่ง
เมื่อมีคนพูดว่า "เปิดเพลงหน่อย" VoiceStarterTrait.OkGoogleEvent การสร้างการทำงานอัตโนมัติ:
  • แอปและผู้ใช้ต้องมีสิทธิ์เข้าถึงโครงสร้าง การทำงานอัตโนมัติไม่จำเป็นต้องมีอุปกรณ์ Assistant เพื่อผ่านการตรวจสอบหรือทำงาน เนื่องจากผู้ใช้ที่มีสิทธิ์เข้าถึงโครงสร้างจะใช้โทรศัพท์ (โดยใช้บัญชี Google เดียวกัน) เพื่อโต้ตอบกับ Assistant และทริกเกอร์ VoiceStarter ได้
การดำเนินการการทำงานอัตโนมัติ:
  • แอปไม่จำเป็นต้องมีสิทธิ์เข้าถึงอุปกรณ์ที่ เริ่มการทำงานอัตโนมัติ
  • แอปและผู้ใช้ต้องมีสิทธิ์เข้าถึงอุปกรณ์ที่ การดำเนินการเกิดขึ้น

คำแนะนำในกรณีที่ผู้ใช้เพิกถอนสิทธิ์ทั้งหมด

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

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