Android の Permissions API

Android 用の Home API を使用する前に、アプリはユーザーの家にあるデバイス(API ではストラクチャと呼ばれます)にアクセスする権限を持っている必要があります。 Permissions API を使用すると、ユーザーは Google アカウントを使用して、Home API アプリに家にあるデバイスへのアクセス権を付与できます。

権限フローを使用すると、Google Home app (GHA)を使用しなくても、ストラクチャがまだ設定されていない場合にユーザーがストラクチャを作成できます。

Permissions API を統合する

先に進む前に、 Android でホームを初期化するの手順を完了していることを確認してください。 この手順の homeManager インスタンスは、ここに示すすべての権限の例で使用されます。

まず、 ActivityResultCaller を SDK に登録します。たとえば、サンプルアプリでは次のように処理されます。

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

権限を確認する

権限をリクエストする前に、アプリのユーザーがストラクチャへのアクセスに同意しているかどうかを確認することをおすすめします。これを行うには、Home インスタンスの hasPermissions() メソッドを呼び出して、FlowPermissionsState 値を取得します。

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 が返された場合、ユーザーまたはアプリケーションにストラクチャへのアクセス権がないことを意味します。 チェックで PermissionsStateGRANTED が返されたものの、後続の 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}")
      }
    }
  }
}
PermissionsManager

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

権限を付与する

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

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

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

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

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

OAuth が設定されると、アプリの requestPermissions() 呼び出しによって次のダイアログが表示されます。

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

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

権限を変更する

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

これを行うには、forceLaunch フラグを true に設定して requestPermissions() を再度呼び出します。

homeManager.requestPermissions(forceLaunch=true)

権限を取り消す

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

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

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

    https://myaccount.google.com/connections/link?project_number=Cloud project_number
    
  2. GHA[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
            }
        }
    }
}

OkGoogle の権限

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

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

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

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

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