Android の Permissions API

Android 向け Google Home API を使用する前に、アプリはユーザーの家(API ではストラクチャと呼ばれる)内のデバイスにアクセスする権限を持っている必要があります。Permissions API を使用すると、ユーザーは Google アカウントを使用して、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}")
      }
    }
  }
}

権限 UI を適切に起動するには、アプリに OAuth を設定しておく必要があります。

権限の同意 UI は、HomeClient.setLocale() で構成された言語 / 地域でレンダリングされます。設定されていない場合は、デフォルトでアプリまたはデバイスの言語 / 地域が使用されます。同意画面を特定の言語で表示するには、requestPermissions() を呼び出す前に、HomeClient インスタンスで setLocale() を呼び出します。詳細については、アプリの言語 / 地域を構成するをご覧ください。

権限を付与する

これで、アプリを実行してユーザーに権限を付与できるようになりました。権限を付与できるユーザーのタイプと、権限を付与できるデバイスのタイプは、アプリを Google Home Developer Console に登録しているかどうかによって異なります。

Google Home API を使用してアプリを公開するには、Developer Console への登録が必要です。Google Home API のテストと使用には必要ありません。

アプリが Developer Console に登録されていない場合、未確認の状態になります。Home API の使用をテストする場合は、次の方法をおすすめします。

  • OAuth コンソールでテストユーザーとして登録されているユーザーのみが、アプリに権限を付与できます。未確認のアプリのテストユーザーは 100 人までです。

  • 未確認のアプリは、Home API の OAuth でサポートされているデバイスタイプ(Developer Console のデバイスタイプのリスト)のデバイスにアクセスできます。ストラクチャ内のすべてのデバイスにアクセス権が付与されます。

アプリが Developer Console に登録され、 1 つ以上のデバイスタイプへのアクセスが承認され、OAuth のブランド確認が完了している場合、アプリは確認済みの状態になります。この状態は、アプリを製品版にリリースするために必要です。

  • テストユーザーの上限は適用されなくなりました。どのユーザーでもアプリに権限を付与できます。
  • ユーザーは、Developer Console で承認されたデバイスタイプにのみ権限を付与できます。

OAuth が設定されたので、アプリが requestPermissions() を呼び出すと、次のダイアログが表示されます。

  1. 使用する Google アカウントを選択するよう求められます。
  2. アプリにアクセスを許可するストラクチャを選択するよう求めるメッセージが表示されます。
    1. 未確認のアプリの場合、Home API でサポートされているすべてのデバイスタイプをアプリで使用できます。
    2. 確認済みのアプリの場合、ユーザーは Developer Console で承認されたデバイスタイプにのみ権限を付与できます。
    3. アプリが管理アクセス権を持つ機密性の高いデバイスタイプについては、ユーザーがデバイスごとにアクセスを制限できます。たとえば、ユーザーが 3 つのロックを所有している場合、そのうちの 1 つのロックにのみアクセス権を付与できます。
  • OAuth 同意 - アカウントを選択
  • OAuth 同意 - デバイスのリンク 01
  • OAuth 同意 - デバイスのリンク 02
図 1: OAuth 同意フローの例

権限が付与されると、アプリは Google Home API を使用して、ストラクチャ内のデバイスの状態を読み取り、制御できるようになります。ユーザーが特定のデバイスタイプまたは機密性の高いデバイスに対する権限をアプリに付与しない場合、アプリは Home API を使用してそのデバイスにアクセス、制御、自動化することはできません。

権限を変更

別のストラクチャ内のデバイスにアクセスする権限を付与するには、アカウント選択ツールを起動して、ユーザーが切り替え先の Google アカウントとストラクチャを選択できるようにします。このプロセスでは、以前に同意が得られていた場合でも、ユーザーに同意画面が再度表示されます。

これを行うには、forcePermissionFlow を ForcePermissionFlow.FORCE_LAUNCH に設定して requestPermissions() を再度呼び出します。

homeManager.requestPermissions(forcePermissionFlow = ForcePermissionFlow.FORCE_LAUNCH)

構造ヒンティングを使用して権限を変更する

構造ヒンティングを使用すると、アプリはユーザーの Google Home API 権限の増分変更をリクエストするときに、特定の構造を事前に選択したり、使用可能な構造のリストを制限したりできます。構造パラメータを認可リクエストに渡すことで、権限ダイアログは選択した構造に自動的にフォーカスし、ユーザーの負担を軽減して構成エラーを防ぎます。

構造ヒンティングは、ConsentScreenOptions データクラスを使用して管理されます。ConsentScreenOptions クラスは、次の構成パラメータを受け入れます。

  • structureId - 権限ダイアログで事前に選択する特定のストラクチャ ID。これを確認するには、更新するストラクチャのストラクチャ プロパティを確認します。
  • allowedStructureIds - ストラクチャ ID のリスト。指定すると、権限ダイアログで利用可能なストラクチャがフィルタされ、このリスト内のストラクチャのみが表示されます。ユーザーがすでに付与されているストラクチャのリスト内に留まるようにする場合を除き、ほとんどの場合は指定する必要はありません。
  • allowStructureChange - ユーザーが事前に選択されたストラクチャを変更できるかどうかを指定します。allowedStructureIds と structureId の少なくとも 1 つが指定されている場合は、通常、これを 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 オブジェクトに記載されているストラクチャにすでにフィルタされた同意画面が表示されます。

構造ヒンティングを使用してユーザーがストラクチャを切り替えられるようにする

ユーザーがアプリに複数のストラクチャを設定していて、そのうちの 1 つを事前に選択しつつ、利用可能なストラクチャを切り替えられるようにするには、allowStructureChange フラグでストラクチャの変更を有効にし、allowedStructureIds でストラクチャのリストを指定します。

val consentOptions = ConsentScreenOptions(
    structureId = target-structure-id,
    allowedStructureIds = listOf(target-structure-id, another-structure-id),
    allowStructureChange = true
)

権限を取り消す

ユーザーは、以前に付与したアクセス権を取り消すことができます。

  1. Google アカウントの設定 > [データとプライバシー] > [サードパーティ製アプリとサービス]。これにより、最初の同意時に発行された OAuth トークンが取り消され、ユーザーがすべてのサーフェス(スマートフォン)とストラクチャで使用していたアプリのすべてのインスタンスへのアクセス権が取り消されます。

    次の URL スキームを使用して、ディープリンクで [サードパーティ製のアプリとサービス] サブページにユーザーを誘導できます。

    https://myaccount.google.com/connections/link?project_number=Cloud project_number
    
  2. [GHA] > [設定] > [リンク済みアプリ] ページ。 GHA の をクリックすると、[設定] ページに移動します。そこから [リンク済みアプリ] タイルをクリックすると、同意画面に似たページが表示されます。このページから、ユーザーはアプリへのアクセス権を削除できます。ユーザーは同じページを使用して、アプリがアクセスできるデバイスタイプや特定の機密性の高いデバイスを変更できます。

ユーザーデータの削除とエクスポート

ユーザーが Google アカウントを削除するか、ストラクチャから離れると、プラットフォームはバックエンド データの削除を自動的に管理します。

  • 削除されたユーザーがストラクチャの唯一のオーナーである場合、プラットフォームはストラクチャとそのデバイスの関連付けを削除します。
  • 共有ストラクチャに他の所有者が残っている場合、そのストラクチャと共有デバイスは残りのメンバーに対して保持されます。プラットフォームは、退職したユーザーのメンバーシップを削除し、そのユーザーの認証情報のみで接続されているサードパーティの Cloud-to-cloud デバイスのリンクを解除します。
  • アカウントを削除すると、ユーザーのストラクチャ データとアプリケーション権限が直ちに完全に削除されます。ユーザーが後で Google アカウントを復元しても、ストラクチャと権限は復元されません。

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
            }
        }
    }
}

OK Google の権限

okGoogle コマンドはデバイスレベルのコマンドであり、ストラクチャ内の任意のデバイスを自動化するために使用できます。ただし、Home APIs アプリがすべてのデバイスにアクセスできるとは限りません。次の表に、このような場合に権限がどのように適用されるかを示します。

自動化 トレイト 権限の適用
午後 10 時に、寝室のスピーカーで「おやすみ」とブロードキャストする。 デバイスに AssistantBroadcastTrait 。 自動化の作成:
  • ブロードキャスト デバイスはアシスタント デバイスである必要があります。
  • アプリとユーザーは、ブロードキャストが行われるデバイスにアクセスできる必要があります。
自動化の実行:
  • アプリとユーザーは、ブロードキャストが行われるデバイスにアクセスできる必要があります。
午後 10 時に、すべてのデバイスで「おやすみ時間です」とブロードキャストする AssistantBroadcastTrait (ストラクチャ)。 自動化の作成:
  • アプリとユーザーがアクセスできるストラクチャに、アシスタント デバイスが少なくとも 1 台必要です。
  • アプリとユーザーがストラクチャにアクセスできる必要があります。
自動化の実行:
  • アプリとユーザーがストラクチャにアクセスできる必要があります。
午後 10 時に「音楽をかけて」 AssistantFulfillmentTrait.OkGoogleCommand 自動化の作成:
  • アプリとユーザーは、自動化がコマンドを発行するデバイスにアクセスできる必要があります。
自動化の実行:
  • アプリとユーザーは、自動化がコマンドを発行するデバイスにアクセスできる必要があります。
「音楽をかけて」と言われたとき VoiceStarterTrait.OkGoogleEvent 自動化の作成:
  • アプリとユーザーがストラクチャにアクセスできる必要があります。ストラクチャにアクセスできるユーザーは、スマートフォン(同じ Google アカウントを使用)を使用してアシスタントを操作し、VoiceStarter をトリガーできるため、自動化の検証や実行にアシスタント デバイスは必要ありません。
自動化の実行:
  • アプリは、自動化を開始するデバイスにアクセスするための権限を必要としません。
  • アプリとユーザーには、アクションが発生するデバイスにアクセスする権限が必要です。

ユーザーがすべての権限を取り消した場合のガイダンス

ユーザーが完全な権限を取り消すと、既存の自動化はすべて機能しなくなります。また、ユーザーが特定のデバイスへのアクセスを取り消すと、それらのデバイスに関連付けられている開始条件、条件、アクションは機能しなくなります。

アプリを起動するたびに、権限がまだ有効であることを確認してください。取り消された場合は、アプリケーションにキャッシュされたデータを含め、以前のデータがすべて削除されていることを確認してください。

ストラクチャへのアクセスが取り消されると、StructureAccessRevokedEvent がクラウド バックエンドに配信されます。エンドツーエンドのパートナー クラウドとモバイルアプリの取り消しワークフローについては、ストラクチャの権限付与をご覧ください。