使用任何 Android 版 Home API 之前,應用程式必須取得存取使用者住家裝置的權限,在 API 中稱為住家結構體。使用者可以透過 Permissions API,使用 Google 帳戶授予 Home API 應用程式存取家中裝置的權限。
使用者可以透過權限流程建立住家結構體,並指派街道地址 (如果尚未設定),不必使用 Google Home app (GHA)。
整合 Permissions API
繼續操作前,請務必按照「在 Android 上初始化住家」一節的指示操作。這裡的所有權限範例都會使用該步驟中的 homeManager 執行個體。
首先,請向 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())
}
}
如果檢查傳回 NOT_GRANTED 或 PERMISSIONS_STATE_UNAVAILABLE 的 PermissionsState,表示使用者或應用程式無法存取結構體。如果檢查傳回 GRANTED 的 PermissionsState,但後續對 structures() 的呼叫未傳回任何結構,則表示使用者已透過 GHA 設定頁面撤銷應用程式的存取權,或使用者不具備必要的存取權。
要求權限
您必須授予應用程式權限,才能存取住家和住家中的裝置。
如果使用者尚未授予權限,請使用 Home 執行個體的 requestPermissions() 方法啟動權限 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,才能正確啟動權限使用者介面。
權限同意聲明使用者介面會以 HomeClient.setLocale() 設定的語言代碼顯示,如果未設定,則預設為應用程式或裝置的語言代碼。如要以特定語言顯示同意畫面,請先在 HomeClient 執行個體上呼叫 setLocale(),再呼叫 requestPermissions()。詳情請參閱「設定應用程式語言代碼」。
授予權限
現在,您應該可以執行應用程式,並讓使用者授予權限。可授予權限的使用者類型,以及可授予權限的裝置類型,會因您是否已在 Google Home Developer Console 註冊應用程式而異。
必須註冊 Developer Console,才能使用 Home API 發布應用程式。不需通過認證,即可測試及使用 Home API。
如果應用程式未在 Developer Console 中註冊,則會處於「未驗證」狀態。建議用於測試 Home API:
只有在 OAuth 控制台中註冊為測試使用者的使用者,才能授予應用程式權限。未經驗證的應用程式最多可有 100 位測試使用者。
未經驗證的應用程式可存取 Home API OAuth 支援的任何裝置類型 (Developer Console 中的裝置類型清單)。住家中的所有裝置都會獲得授權。
如果應用程式已在Developer Console 註冊,且已獲准存取一或多種裝置類型,並已完成 OAuth 品牌驗證,就會處於「已驗證」狀態。必須處於這個狀態,才能將應用程式發布至正式版:
- 測試使用者人數限制不再適用。任何使用者都能授予應用程式權限。
- 使用者只能授予 Developer Console 中核准的裝置類型權限。
設定 OAuth 後,應用程式對 requestPermissions() 的呼叫會觸發下列對話方塊:
- 系統會提示使用者選取要使用的 Google 帳戶。
- 系統會提示使用者選取要授予應用程式存取權的住家結構體。
- 如果應用程式未經驗證,則可使用 Home API 支援的所有裝置類型。
- 如果是已驗證的應用程式,使用者只能授予 Developer Console 中已核准的裝置類型權限。
- 如果應用程式可管理敏感裝置類型,使用者可以限制個別裝置的存取權。舉例來說,如果使用者有三個智慧門鎖,可以只授予其中一個門鎖的存取權。
取得權限後,應用程式就能使用 Home API 讀取住家裝置的狀態並加以控制。如果使用者未授予應用程式特定裝置類型或機密裝置的權限,應用程式就無法使用 Home API 存取、控制或自動化該裝置。
變更權限
如要授予其他結構體中裝置的存取權,可以啟動帳戶挑選器,讓使用者選擇要切換的 Google 帳戶和結構體。在這個過程中,即使使用者先前已授予同意聲明,系統仍會再次顯示同意畫面。
方法是再次呼叫 requestPermissions(),並將 forcePermissionFlow 設為 ForcePermissionFlow.FORCE_LAUNCH:
homeManager.requestPermissions(forcePermissionFlow = ForcePermissionFlow.FORCE_LAUNCH)
使用住家結構體提示變更權限
應用程式要求逐步變更使用者的 Home API 權限時,可透過住家結構體提示預先選取特定結構體,或限制可用結構體清單。只要將住家結構參數傳入授權要求,權限對話方塊就會自動聚焦於所選住家結構,減少使用者不便,並避免設定錯誤。
住家結構體提示是使用 ConsentScreenOptions 資料類別管理。ConsentScreenOptions 類別接受下列設定參數:
structureId:在權限對話方塊中預先選取的特定結構 ID。如要取得這項資訊,請查看要更新的結構體結構體屬性。allowedStructureIds:住家結構體 ID 清單。如果提供,權限對話方塊會篩選可用的結構,只顯示這份清單中的結構。在大多數情況下,您可以不指定這個參數,除非您想確保使用者只能存取已授予權限的住家清單。allowStructureChange:決定是否允許使用者變更預先選取的結構。如果至少指定allowedStructureIds和structureId其中之一,請在多數情況下將此值設為true,以支援使用者的自然行為。
在 requestPermissions() 呼叫中,將這個物件做為選用參數傳遞,並將 forcePermissionFlow 設為 ForcePermissionFlow.FORCE_LAUNCH:
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(forcePermissionFlow = ForcePermissionFlow.FORCE_LAUNCH, consentScreenOptions = 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 帳戶或離開住家結構體時,平台會自動管理後端資料刪除作業:
- 如果遭刪除的使用者是住家的唯一擁有者,平台會刪除住家和相關聯的裝置。
- 如果共用住家結構體還有其他擁有者,則該結構體和共用裝置仍會保留給其他成員。平台會移除離職使用者的成員資格,並取消連結任何僅透過該使用者憑證連結的第三方 Cloud-to-cloud 裝置。
- 刪除帳戶後,系統會立即永久移除使用者的住家結構資料和應用程式權限。即使使用者日後復原 Google 帳戶,住家結構體和權限也不會還原。
Home API 不提供匯出或刪除使用者 Google 帳戶資料的端點。請引導擁有 Google 帳戶的使用者前往 Google 匯出匯出 Google Home 資料,並前往 Google 帳戶設定管理帳戶刪除事宜。
查看使用者已授予權限的裝置類型
在 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 應用程式可能無法存取所有裝置。下表說明這類情況下的權限強制執行方式。
| 自動化 | Trait | 權限強制執行 |
|---|---|---|
| 晚上 10 點透過臥室音箱廣播「該睡覺了」。 |
AssistantBroadcastTrait
在裝置上。 |
建立自動化動作:
|
| 晚上 10 點透過所有裝置廣播「該睡覺了」 |
AssistantBroadcastTrait
:結構。 |
建立自動化動作:
|
| 晚上 10:00 執行「播放音樂」 |
AssistantFulfillmentTrait.OkGoogleCommand
|
建立自動化動作:
|
| 只要有人說「播點音樂」 |
VoiceStarterTrait.OkGoogleEvent
|
建立自動化動作:
|
使用者撤銷完整權限時的指引
如果使用者撤銷完整權限,所有現有自動化動作都會停止運作。此外,如果使用者撤銷特定裝置的存取權,與這些裝置相關聯的啟動條件、限制條件和動作就會停止運作。
每次應用程式啟動時,請務必檢查權限是否仍有效。如果權限已撤銷,請務必移除所有先前的資料,包括應用程式中快取的任何資料。
當住家結構體存取權遭到撤銷時,系統會將 StructureAccessRevokedEvent 傳送至雲端後端。如要瞭解端對端合作夥伴雲端和行動應用程式撤銷工作流程,請參閱「住家結構體授權」。


