Android 上的 Permissions API

如要使用任何 Android 適用的 Home API,應用程式必須有權存取使用者住家中的裝置 (在 API 中稱為「結構」)。使用者可以透過 Permissions API,使用 Google 帳戶授權 Home API 應用程式存取住家中的裝置。

整合 Permissions API

繼續操作之前,請務必按照「在 Android 上初始化住家」一文的步驟操作。該步驟中的 homeManager 例項會用於這裡的所有 Permissions 範例。

首先,請向 SDK 註冊 ActivityResultCaller。舉例來說,範例應用程式會以這種方式處理:

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

檢查權限

要求權限前,建議先檢查應用程式使用者是否已授予同意聲明。如要這麼做,請呼叫 Home 執行個體的 hasPermissions() 方法,取得 PermissionsState 值的 Flow

val permissionsReadyState =
  homeManager.hasPermissions().collect { state ->
    state == PermissionsState.GRANTED ||
      state == PermissionsState.PERMISSIONS_STATE_UNAVAILABLE ||
      state == PermissionsState.NOT_GRANTED
    when (permissionsReadyState) {
      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")
      else ->
        throw IllegalStateException(
          "HomeClient.hasPermissions state should be PermissionsState.GRANTED or " +
            "PermissionsState.PERMISSIONS_STATE_UNAVAILABLE")
  }
}

如果檢查結果傳回 PermissionsStateNOT_GRANTEDPERMISSIONS_STATE_UNAVAILABLE,您需要要求權限。如果檢查傳回 PermissionsStateGRANTED,但後續對 structures() 的呼叫未傳回任何結構,表示使用者已透過 Google Home app (GHA) 設定頁面撤銷應用程式的存取權,因此您應要求權限。否則,使用者應該已經有存取權。

要求權限

您必須授予應用程式權限,才能存取特定住家結構體內的裝置。

如果使用者尚未授予權限,請使用 Home 執行個體的 requestPermissions() 方法啟動權限使用者介面,並處理結果:

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

授予權限

現在您應該可以執行應用程式,並讓使用者授予權限。可授予權限的使用者類型,以及可授予權限的裝置類型,會因您是否已在 Google Home Developer Console 中註冊應用程式而異。

如要使用 Home API 發布應用程式,必須先Developer Console註冊。測試及使用 Home API 並非必要。

如果應用程式未在 Developer Console中註冊,就會處於「未驗證」狀態。建議您使用這項功能測試 Home API:

  • 只有在 OAuth 控制台中註冊為測試使用者的使用者,才能授予應用程式權限。未經驗證的應用程式最多只能有 100 位測試使用者。

  • 未經驗證的應用程式可以存取 OAuth 支援的任何裝置類型 (裝置類型清單請參閱Developer Console)。系統會授予應用程式存取結構中所有裝置的權限。

如果應用程式已在Developer Console 中註冊,並獲准存取一或多種裝置類型,且已完成 OAuth 的品牌驗證,就會處於「已驗證」狀態。如要發布應用程式,必須先達到這個狀態:

  • 測試使用者限制不再適用。任何使用者都可以授予應用程式權限。
  • 使用者只能將權限授予 Developer Console 中核准的裝置類型。

OAuth 設定完成後,應用程式對 requestPermissions() 的呼叫會觸發下列對話方塊:

  1. 系統會提示使用者選取要使用的 Google 帳戶。
  2. 系統會提示使用者選取要授予應用程式存取權的結構。
    1. 如果應用程式未經驗證,則可使用 Home API 支援的所有裝置類型。
    2. 如果是已驗證的應用程式,使用者只能將權限授予 Developer Console 中核准的裝置類型。
    3. 如果應用程式有權管理敏感裝置類型,使用者可以限制個別裝置的存取權。舉例來說,如果使用者有三把鎖,只能授予其中一把鎖的存取權。
  • OAuth 同意 - 選取帳戶
  • OAuth consent - link devices 01
  • OAuth 同意 - 連結裝置 02
圖 1:OAuth 同意流程範例

取得授權後,應用程式就能使用 Home API 讀取及控制結構中的裝置狀態。如果使用者未授予應用程式特定裝置類型或私密裝置的權限,應用程式就無法使用 Home API 存取、控制或自動化這類裝置。

變更權限

如要授予存取不同結構中裝置的權限,可以啟動帳戶挑選器,讓使用者挑選要切換的 Google 帳戶和結構。在此期間,系統會再次向使用者顯示同意畫面,即使使用者先前已同意也一樣。

如要達成這個效果,請再次呼叫 requestPermissions(),並將 forceLaunch 旗標設為 true

homeManager.requestPermissions(forceLaunch=true)

撤銷權限

使用者可以撤銷先前授予的存取權:

  1. 前往 Google 我的帳戶頁面,然後依序點選「資料與隱私權」>「第三方應用程式和服務」。這會撤銷授予初始同意聲明時核發的 OAuth 權杖,並撤銷使用者在所有介面 (手機) 和結構體上使用的任何應用程式例項存取權。

    使用者可能會透過深層連結導向「第三方應用程式和服務」子頁面,網址架構如下:

    https://myaccount.google.com/connections/link?project_number=Cloud project_number
    
  2. 透過「GHA」>「設定」>「已連結的應用程式」頁面。 按一下 GHA,即可前往「設定」頁面。然後按一下「已連結的應用程式」圖塊,系統會將您帶往類似同意畫面。使用者可以在這個頁面移除應用程式的存取權,也可以變更應用程式可存取的裝置類型或特定敏感裝置。

「Ok Google」權限

okGoogle 指令是裝置層級的指令,可用於自動化結構中的任何裝置。不過,Home API 應用程式可能無法存取所有裝置。下表說明在這種情況下如何強制執行權限。

自動化 特徵 權限強制執行
晚上 10 點透過臥室音箱廣播「就寢時間」。 AssistantBroadcastTrait 裝置。 建立自動化動作
  • 廣播裝置必須是 Google 助理裝置。
  • 應用程式和使用者必須有權存取廣播裝置。
自動化執行
  • 應用程式和使用者必須有權存取廣播裝置。
晚上 10 點透過所有裝置廣播「就寢時間」 AssistantBroadcastTrait 結構。 建立自動化動作
  • 應用程式和使用者可存取的結構中,必須至少有一部 Google 助理裝置。
  • 應用程式和使用者必須有權存取該結構。
自動化執行
  • 應用程式和使用者必須有權存取該結構。
晚上 10 點「播放音樂」 AssistantFulfillmentTrait.OkGoogleCommand 建立自動化動作
  • 應用程式和使用者必須有權存取自動化功能發出指令的裝置。
自動化執行
  • 應用程式和使用者必須有權存取自動化動作發出指令的裝置。
只要有人說「播點音樂」 VoiceStarterTrait.OkGoogleEvent 建立自動化動作
  • 應用程式和使用者必須有權存取該結構。自動化動作不需要通過驗證或執行,因為只要使用者有權存取住家,就能使用手機 (透過相同 Google 帳戶) 與 Google 助理互動,並觸發 VoiceStarter。
自動化執行
  • 應用程式不需要存取啟動自動化作業的裝置權限。
  • 應用程式和使用者必須具備相關權限,才能存取執行動作的裝置。