Permissions API ใน Android

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

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

ผสานรวม Permissions API

ก่อนดำเนินการต่อ โปรดตรวจสอบว่าคุณได้ทำตามขั้นตอนในหัวข้อ เริ่มต้นใช้งานบ้านใน 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())
    }
}

หากการตรวจสอบแสดงผลเป็น PermissionsStateNOT_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}")
      }
    }
  }
}

คุณต้องตั้งค่า 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 และ ได้รับอนุมัติให้เข้าถึงอุปกรณ์ประเภทใดประเภทหนึ่งหรือมากกว่า และการยืนยัน แบรนด์สำหรับ OAuth เสร็จสมบูรณ์แล้ว แอปจะอยู่ในสถานะยืนยันแล้ว สถานะนี้จำเป็นสำหรับการเปิดตัวแอปไปยังสภาพแวดล้อมการใช้งานจริง

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

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

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

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

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

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

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

homeManager.requestPermissions(forceLaunch=true)

เปลี่ยนสิทธิ์ด้วยการบอกโครงสร้าง

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

การบอกโครงสร้างได้รับการจัดการโดยใช้คลาสข้อมูล ConsentScreenOptions คลาส ConsentScreenOptions รับพารามิเตอร์การกำหนดค่าต่อไปนี้

  • structureId — รหัสโครงสร้างที่เฉพาะเจาะจงเพื่อเลือกไว้ล่วงหน้าในกล่องโต้ตอบสิทธิ์ รับค่านี้โดยตรวจสอบพร็อพเพอร์ตี้ โครงสร้างสำหรับโครงสร้างที่ อัปเดต
  • allowedStructureIds — รายการรหัสโครงสร้าง หากระบุไว้ กล่องโต้ตอบสิทธิ์ จะกรองโครงสร้างที่ใช้ได้เพื่อแสดงเฉพาะโครงสร้างในรายการนี้ ในกรณีส่วนใหญ่ คุณอาจไม่ต้องระบุค่านี้ เว้นแต่ต้องการให้ผู้ใช้ อยู่ในรายการโครงสร้างที่ได้รับอนุญาตอยู่แล้ว
  • allowStructureChange — กำหนดว่าผู้ใช้ได้รับอนุญาตให้เปลี่ยนโครงสร้างที่เลือกไว้ล่วงหน้าหรือไม่ ตั้งค่านี้เป็น true หากมีการระบุ allowedStructureIds และ structureId อย่างน้อย 1 รายการในกรณีส่วนใหญ่เพื่อรองรับลักษณะการทำงานที่เป็นธรรมชาติสำหรับผู้ใช้

ส่งออบเจ็กต์นี้เป็นพารามิเตอร์ที่ไม่บังคับในrequestPermissions() call โดยตั้งค่าแฟล็ก forceLaunch เป็น true

import com.google.home.ConsentScreenOptions

// Create the ConsentScreenOptions class, allowing structure changes while
// ensuring the permissions dialog pre-selects the target structure on launch
val consentOptions = ConsentScreenOptions(
    structureId = target-structure-id,
    allowStructureChange = true
)

homeManager.requestPermissions(forceLaunch=true, consentOptions)

ผู้ใช้จะเห็นหน้าจอขอความยินยอมที่กรองแล้วตามโครงสร้างที่ระบุไว้ในออบเจ็กต์ ConsentScreenOptions

อนุญาตให้ผู้ใช้เปลี่ยนโครงสร้างด้วยคำแนะนำโครงสร้าง

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

val consentOptions = ConsentScreenOptions(
    structureId = target-structure-id,
    allowedStructureIds = listOf(target-structure-id, another-structure-id),
    allowStructureChange = 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
            }
        }
    }
}

สิทธิ์ Ok Google

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

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

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

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

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