Permissions API

在使用任何 Home API 之前,应用必须有权访问用户住宅中的设备(在 API 中称为结构)。

Home API 使用 OAuth 2.0 授予对结构中设备的访问权限。借助 OAuth,用户无需泄露其登录凭据即可向应用或服务授予权限。借助 Permissions API,用户可以使用其 Google 账号向 Home API 应用授予对其住宅中设备的访问权限。

使用 Permissions API 需要在应用、Google Cloud 和 Google Home Developer Console 中执行一系列步骤:

  1. 在 Google Cloud 中设置 OAuth
    1. 为应用签名
    2. 设置 OAuth 同意屏幕
    3. 注册应用并创建凭据
  2. 集成 Permissions API
    1. 检查权限
    2. 请求权限
  3. 授予权限
    1. 更改权限
    2. 撤消权限

在 Google Cloud 中设置 OAuth

如果您已经拥有经过验证的 OAuth 客户端,则无需设置新的客户端即可使用该客户端。如需了解详情,请参阅如果您已有 OAuth 客户端

为应用签名

  1. Android Studio 中运行应用以生成 OAuth 密钥。当您在 Android Studio 中运行或调试应用时,系统会自动生成一个用于开发和调试的 OAuth 密钥。如需完整说明,请参阅 Android Studio:为调试 build 签名

    将移动设备连接到本地机器。 Android Studio 会按型号列出已连接的设备。从列表中选择您的设备,然后点击运行项目。这会在您的移动设备上构建并安装示例应用。

    如需更详细的说明,请参阅 Android 开发者网站上的在硬件设备上运行应用

    现在,停止运行的应用。

  2. 按照 Google Cloud 控制台帮助网站上设置 OAuth 2.0 / 原生应用/Android 中详述的说明获取 OAuth 证书的 SHA-1 指纹。

  1. 在 Google Cloud 控制台中,前往“项目选择器”信息中心,然后选择要用于创建 OAuth 凭据的项目。
  2. 前往 API 和服务页面,然后点击导航菜单中的凭据
  3. 如果您尚未为此 Google Cloud 项目配置同意屏幕,系统会显示配置同意屏幕按钮。在这种情况下,请按照以下步骤配置同意屏幕。否则,请直接进入下一部分。

    1. 点击配置同意屏幕。系统会显示 OAuth 权限请求页面
    2. 根据您的用例,选择内部外部,然后点击创建。系统会显示 OAuth 权限请求页面窗格。
    3. 按照屏幕上的说明在“应用信息”页面上输入信息,然后点击保存并继续。系统随即会显示 Scopes 窗格。
    4. 您无需添加任何镜重,因此请点击保存并继续。系统会显示测试用户窗格。
    5. 如果您想添加用户来测试对应用的访问权限,请点击添加用户。系统随即会显示添加用户窗格。测试用户有权在您的应用中授予权限。
    6. 在空白字段中,添加一个或多个 Google 账号电子邮件地址,然后点击添加
    7. 点击保存并继续。系统随即会显示摘要窗格。
    8. 查看您的 OAuth 同意屏幕信息,然后点击返回信息中心

如需了解完整详情,请参阅 Google Cloud 控制台帮助网站上的设置 OAuth 权限请求页面

注册应用并创建凭据

如需为 OAuth 2.0 注册应用并创建 OAuth 凭据,请按照设置 OAuth 2.0 中提供的说明操作。您需要指明应用类型,即原生/Android 应用

按照 Google Cloud 控制台帮助网站上设置 OAuth 2.0 / 原生应用中的说明,将您在为应用签名时获得的 SHA-1 指纹添加到您在 Google Cloud 控制台中设置的 OAuth 客户端。

将移动设备连接到本地机器后,从列表中选择您的设备,然后再次点击运行项目以运行项目。如需更详细的说明,请参阅 Android 开发者网站上的在硬件设备上运行应用

集成 Permissions API

用户必须向您的应用授予权限,才能访问给定结构中的设备。首先,请确保您已按照初始化 Home API 中的说明操作。此步骤中的 homeManager 实例会在此处的所有权限示例中使用。

首先,向 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,您需要请求权限。如果检查返回 GRANTEDPermissionsState,但对 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

授予权限

现在,您应该能够运行应用并让用户授予权限。可以授予权限的用户类型以及可授予权限的设备类型因您是否已在 Developer Console 中注册应用而异。

若要使用 Home API 发布应用,必须进行 Developer Console 注册。无需进行测试即可使用 Home API。如需使用控制台注册功能,请与您的 Google Technical Account Manager (TAM) 联系。

如果应用未在 Developer Console 中注册,则处于未验证状态。建议您使用以下方法测试 Home API 的使用情况:

  • 只有在 OAuth 控制台中注册为测试用户的用户才能为应用授予权限。未经验证的应用的测试用户数量上限为 100 人。

  • 未经验证的应用将有权访问 Home API 的 OAuth 支持的任何类型的设备(Developer Console 中的设备类型列表)。系统会授予结构中的所有设备访问权限。

如果应用已在 Developer Console 中注册 ,并且已获准访问一种或多种设备类型,并且已完成 OAuth 品牌验证,则该应用将处于已验证状态。必须处于此状态才能将应用发布到生产环境:

  • 测试用户数上限已不再适用。任何用户都可以向应用授予权限。
  • 用户只能向 Developer Console 中已获批准的设备类型授予权限。

现在,OAuth 已设置完毕,应用对 requestPermissions() 的调用会触发以下对话框:

  1. 系统会提示用户选择要使用的 Google 账号。
  2. 系统会提示用户选择要向应用授予访问权限的结构。
    1. 对于未经验证的应用,Home API 支持的所有设备类型均可供该应用使用。
    2. 对于经过验证的应用,用户只能向在 Developer Console 中获得批准的设备类型授予权限。
    3. 对于应用有权管理的敏感设备类型,用户可以按设备限制访问权限。例如,如果用户有三个锁,则只能向其中一个锁授予访问权限。
  • OAuth 同意 - 选择账号
  • OAuth 意见征求 - 关联设备 01
  • OAuth 权限请求 - 关联设备 02
  • OAuth 权限请求 - 已授予设备
图 1:OAuth 同意流程示例

授予权限后,应用便可以使用 Home API 读取结构中的设备状态并控制这些设备。如果用户不向应用授予特定类型的设备或敏感设备的权限,该应用将无法使用 Home API 访问、控制或自动执行相应设备。

更改权限

如需授予访问不同结构中设备的权限,可以启动账号选择器,以便用户选择要切换到的 Google 账号和结构。在此过程中,系统会再次向用户显示意见征求界面,即使用户之前已同意授权也是如此。

为此,您可以再次调用 requestPermissions(),并将 forceLaunch 标志设置为 true

homeManager.requestPermissions(forceLaunch=true)

撤消权限

用户可以撤消之前授予的访问权限:

  1. 依次前往 Google“我的账号”页面 >“数据和隐私”>“第三方应用和服务”。这会撤消在用户首次授予意见时签发的 OAuth 令牌,并撤消对用户在所有平台(手机)和结构中使用的应用的任何实例的访问权限。

  2. 依次前往 GHA > 设置 > 关联的应用页面。 点击 GHA 中的 会进入设置页面。然后,点击关联的应用功能块,您会看到一个与意见征求界面类似的页面。用户可以在该页面上移除对应用的访问权限。用户还可以使用同一页面更改应用可以访问哪些类型的设备或特定敏感设备。

  3. 直接在网页上通过“关联的应用”页面

如果您已有 OAuth 客户端

如果您已为已发布的应用拥有经过验证的 OAuth 客户端,则可以使用现有的 OAuth 客户端测试 Home API。

无需进行 Developer Console 注册即可测试和使用 Home API。不过,即使您有通过其他集成验证的 OAuth 客户端,仍需要获得已获批准的 Developer Console 注册才能发布应用。

需要注意以下几点:

  • 使用现有 OAuth 客户端时,用户数上限为 100 人。如需了解如何添加测试用户,请参阅设置 OAuth 权限请求页面。无论是否通过 OAuth 验证,Home API 都限制只能有 100 位用户可以向您的应用授予权限。完成 Developer Console 注册后,此限制将解除。

  • 当您准备好通过 OAuth 限制设备类型授予权限,以便使用 Home API 更新应用时,应发送Developer Console注册 以供审批。

对于仍在等待 OAuth 验证的 Google Cloud 应用,用户在验证完成之前无法完成 OAuth 流程。尝试授予权限将会失败,并显示以下错误:

Access blocked: <Project Name> has not completed the Google verification process.

OkGoogle 权限

okGoogle 命令是一个结构级命令,可用于自动执行结构中的任何设备。不过,Home API 应用可能无法访问每台设备。下表介绍了在这种情况下如何强制执行权限。

自动化 特征 权限强制执行
晚上 10:00 在卧室音箱上广播“睡觉了”。 设备上的 AssistantBroadcastTrait 创建自动化操作
  • 广播设备必须是 Google 助理设备。
  • 应用和用户必须有权访问发生广播的设备。
自动化执行
  • 应用和用户必须有权访问发生广播的设备。
晚上 10:00 在所有设备上广播“就寝时间” AssistantBroadcastTrait 结构。 创建自动化操作
  • 结构中必须至少有一个 Google 助理设备,且应用和用户对其有访问权限。
  • 应用和用户必须有权访问该结构。
自动化执行
  • 应用和用户必须有权访问该结构。
晚上 10:00,“播放音乐” AssistantFulfillmentTrait.OkGoogleCommand 创建自动化操作
  • 应用和用户必须有权访问用户的所有设备(摄像头除外)。
自动化执行
  • 应用和用户必须有权访问发生相应操作的所有设备。
每当有人说“放点音乐”时 VoiceStarterTrait.OkGoogleEvent 创建自动化操作
  • 应用和用户必须有权访问结构和至少一台 Google 助理设备。
自动化执行
  • 应用无需权限即可访问启动自动化操作的设备。
  • 应用和用户必须拥有访问发生相应操作的设备的权限。