使用任何 Android 適用的 Home API 前,應用程式必須取得存取使用者住家裝置的權限 (在 API 中稱為「結構」)。使用者可以透過 Permissions API,使用 Google 帳戶授權 Home API 應用程式存取家中裝置。
如果使用者尚未設定結構,權限流程會讓他們建立結構,不必使用 Google Home app (GHA)。
整合 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 ->
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 設定頁面撤銷應用程式的存取權,或使用者沒有必要的存取權。
要求權限
您必須授予應用程式權限,才能存取特定住家結構體內的裝置。
如果使用者尚未授予權限,請使用 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 中註冊應用程式而異。
Developer Console如要使用 Home API 發布應用程式,必須先完成註冊。測試及使用 Home API 時,不一定要有裝置。
如果應用程式未在 Developer Console 中註冊,就會處於「未驗證」狀態。建議您使用這個方法測試 Home API:
只有在 OAuth 控制台中註冊為測試使用者的使用者,才能授予應用程式權限。未經驗證的應用程式最多只能有 100 位測試使用者。
未經驗證的應用程式可以存取 OAuth 支援的任何裝置類型 (裝置類型清單請參閱Developer Console)。系統會授予存取結構中所有裝置的權限。
如果應用程式已在Developer Console 中註冊,並獲准存取一或多種裝置類型,且已完成 OAuth 的品牌驗證,就會處於「已驗證」狀態。如要發布應用程式,必須處於這個狀態:
- 測試使用者限制不再適用。任何使用者都可以授予應用程式權限。
- 使用者只能將權限授予 Developer Console 中核准的裝置類型。
OAuth 設定完成後,應用程式對 requestPermissions() 的呼叫會觸發下列對話方塊:
- 系統會提示使用者選取想使用的 Google 帳戶。
- 系統會提示使用者選取要授予應用程式存取權的住家結構體。
- 如果應用程式未經驗證,則可使用 Home API 支援的所有裝置類型。
- 如果是已驗證的應用程式,使用者只能將權限授予 Developer Console 中核准的裝置類型。
- 如果應用程式有權管理敏感裝置類型,使用者可以限制個別裝置的存取權。舉例來說,如果使用者有三把鎖,只能授予其中一把鎖的存取權。
取得授權後,應用程式就能使用 Home API 讀取及控制結構中的裝置狀態。如果使用者未授予應用程式特定裝置類型或敏感裝置的權限,應用程式就無法使用 Home API 存取、控制或自動化這類裝置。
變更權限
如要授予存取不同結構中裝置的權限,可以啟動帳戶挑選器,讓使用者挑選要切換的 Google 帳戶和結構。在此期間,系統會再次向使用者顯示同意畫面,即使使用者先前已同意也一樣。
只要再次呼叫 requestPermissions(),並將 forceLaunch 旗標設為 true 即可:
homeManager.requestPermissions(forceLaunch=true)
使用結構提示變更權限
當應用程式要求使用者住家 API 權限的增量變更時,結構提示可讓應用程式預先選取特定結構,或限制可用結構的清單。將結構參數傳遞至授權要求後,權限對話方塊會自動聚焦於所選結構,減少使用者不便並避免設定錯誤。
結構提示是使用 ConsentScreenOptions 資料類別管理。ConsentScreenOptions 類別接受下列設定參數:
structureId- 要在權限對話方塊中預先選取的特定結構 ID。如要取得這項資訊,請檢查要更新的結構體結構體屬性。allowedStructureIds:結構 ID 清單。如果提供這項屬性,權限對話方塊會篩選可用的結構,只顯示這份清單中的結構。在大多數情況下,這項參數可以不指定,除非您想確保使用者留在已授予的結構清單中。allowStructureChange:決定使用者是否可以變更預先選取的結構。在大多數情況下,如果指定了allowedStructureIds和structureId至少其中一個,請將此值設為true,以支援使用者的自然行為。
在 requestPermissions() 呼叫中,將這個物件做為選用參數傳遞,並將 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
)
撤銷權限
使用者可以撤銷先前授予的存取權:
透過 Google 我的帳戶頁面 >「資料與隱私權」>「第三方應用程式和服務」。這會撤銷使用者授予初始同意聲明時核發的 OAuth 權杖,並撤銷使用者在所有介面 (手機) 和結構體上使用應用程式例項的存取權。
使用者可能會透過深層連結導向「第三方應用程式和服務」子頁面,網址配置如下:
https://myaccount.google.com/connections/link?project_number=Cloud project_number透過「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 API 應用程式可能無法存取所有裝置。下表說明在這種情況下如何強制執行權限。
| 自動化 | 特徵 | 權限強制執行 |
|---|---|---|
| 晚上 10 點透過臥室音箱廣播「就寢時間」。 |
AssistantBroadcastTrait
裝置。 |
建立自動化動作:
|
| 晚上 10 點透過所有裝置廣播「就寢時間」 |
AssistantBroadcastTrait
。 |
建立自動化動作:
|
| 晚上 10 點「播放音樂」 |
AssistantFulfillmentTrait.OkGoogleCommand
|
建立自動化動作:
|
| 只要有人說「播點音樂」 |
VoiceStarterTrait.OkGoogleEvent
|
建立自動化動作:
|
使用者撤銷完整權限時的指引
如果使用者撤銷完整權限,所有現有的自動化動作都會停止運作。此外,如果使用者撤銷特定裝置的存取權,與這些裝置相關聯的啟動條件、限制條件和動作就會停止運作。
每次啟動應用程式時,請務必檢查權限是否仍有效。如果已撤銷,請務必移除所有先前的資料,包括應用程式中快取的資料。


