Android의 Permissions API

Android용 Home API를 사용하기 전에 앱에 API에서 구조라고 하는 사용자의 홈에 있는 기기에 액세스할 수 있는 권한이 있어야 합니다. 권한 API를 사용하면 사용자가 Google 계정을 사용하여 Home API 앱에 홈의 기기 액세스 권한을 부여할 수 있습니다.

Permissions API 통합

계속하기 전에 Android에서 홈 초기화를 따랐는지 확인하세요. 이 단계의 homeManager 인스턴스는 여기의 모든 권한 예시에서 사용됩니다.

먼저 SDK에 ActivityResultCaller를 등록합니다. 예를 들어 샘플 앱은 다음과 같이 처리합니다.

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

권한 확인

권한을 요청하기 전에 앱 사용자가 이미 동의를 부여했는지 확인하는 것이 좋습니다. 이렇게 하려면 홈 인스턴스의 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_GRANTED 또는 PERMISSIONS_STATE_UNAVAILABLE이면 권한을 요청해야 합니다. 확인에서 PermissionsStateGRANTED을 반환하지만 후속 structures() 호출에서 구조체를 반환하지 않으면 사용자가 Google Home app (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를 설정해야 합니다.

권한 부여

이제 앱을 실행하고 사용자가 권한을 부여할 수 있습니다. 권한을 부여할 수 있는 사용자 유형과 권한을 부여할 수 있는 기기 유형은 Google Home Developer Console에 앱을 등록했는지에 따라 달라집니다.

Developer Console 등록은 Home API를 사용하여 앱을 게시하는 데 필요합니다. 홈 API를 테스트하고 사용할 필요는 없습니다.

앱이 Developer Console에 등록되지 않은 경우 인증되지 않음 상태가 됩니다. 홈 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. 앱이 관리할 수 있는 민감한 기기 유형의 경우 사용자가 기기별로 액세스를 제한할 수 있습니다. 예를 들어 사용자에게 도어락이 3개 있는 경우 도어락 중 하나에만 액세스 권한을 부여할 수 있습니다.
  • 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에서 를 클릭하면 설정 페이지로 이동합니다. 여기에서 연결된 앱 타일을 클릭하면 동의 화면과 유사한 페이지로 이동합니다. 이 페이지에서 사용자는 앱에 대한 액세스 권한을 삭제할 수 있습니다. 사용자는 이 페이지를 사용하여 앱이 액세스할 수 있는 기기 유형 또는 특정 민감한 기기를 변경할 수 있습니다.

OkGoogle 권한

okGoogle 명령어는 기기 수준 명령어이며 구조의 모든 기기를 자동화하는 데 사용할 수 있습니다. 하지만 Home API 앱은 모든 기기에 액세스하지 못할 수 있습니다. 다음 표에서는 이러한 경우 권한이 적용되는 방식을 설명합니다.

자동화 특성 권한 적용
오후 10시에 침실 스피커에서 '취침 시간'을 브로드캐스트합니다. AssistantBroadcastTrait 를 사용합니다. 자동화 생성:
  • 브로드캐스트 기기는 어시스턴트 기기여야 합니다.
  • 앱과 사용자는 브로드캐스트가 발생하는 기기에 액세스할 수 있어야 합니다.
자동화 실행:
  • 앱과 사용자는 브로드캐스트가 발생하는 기기에 액세스할 수 있어야 합니다.
오후 10시에 모든 기기에서 '취침 시간'을 브로드캐스트합니다. 구조에 대한 AssistantBroadcastTrait 자동화 생성:
  • 앱과 사용자가 액세스할 수 있는 구조에 어시스턴트 기기가 하나 이상 있어야 합니다.
  • 앱과 사용자에게 구조에 대한 액세스 권한이 있어야 합니다.
자동화 실행:
  • 앱과 사용자에게 구조에 대한 액세스 권한이 있어야 합니다.
오후 10시에 '음악 틀어 줘' AssistantFulfillmentTrait.OkGoogleCommand 자동화 생성:
  • 앱과 사용자는 자동화가 명령어를 실행하는 기기에 액세스할 수 있어야 합니다.
자동화 실행:
  • 앱과 사용자는 자동화가 명령어를 실행하는 기기에 액세스할 수 있어야 합니다.
누군가 '음악 틀어 줘'라고 말할 때마다 VoiceStarterTrait.OkGoogleEvent 자동화 생성:
  • 앱과 사용자에게 구조에 대한 액세스 권한이 있어야 합니다. 구조에 액세스할 수 있는 사용자는 누구나 동일한 Google 계정을 사용하여 휴대전화로 어시스턴트와 상호작용하고 VoiceStarter를 트리거할 수 있으므로 자동화에는 어시스턴트 기기가 유효성 검사를 통과하거나 실행될 필요가 없습니다.
자동화 실행:
  • 앱에 자동화를 시작하는 기기에 액세스할 수 있는 권한이 필요하지 않습니다.
  • 앱과 사용자에게는 작업이 발생하는 기기에 액세스할 수 있는 권한이 있어야 합니다.