오디오 글래스 및 디스플레이 글래스의 하드웨어 권한 요청

적용 가능한 XR 기기
이 가이드에서는 이러한 유형의 XR 기기를 위한 환경을 구축하는 방법을 설명합니다.
오디오 및
디스플레이 안경

휴대전화와 마찬가지로 오디오 글라스와 디스플레이 글라스의 카메라 및 마이크와 같은 민감한 하드웨어에 액세스하려면 명시적인 사용자 동의가 필요합니다. 이러한 권한은 스마트 안경 전용 권한으로 간주되며, 휴대전화에 이미 해당 권한이 있더라도 앱은 런타임에 이러한 권한을 요청해야 합니다.

앱의 매니페스트에서 권한 선언

권한을 요청하기 전에 <uses-permission> 요소를 사용하여 앱의 매니페스트 파일에서 권한을 선언해야 합니다. 이 선언은 권한이 휴대전화 또는 글래스 전용 기능에 대한 것인지와 관계없이 동일하지만 글래스 전용 하드웨어 또는 기능에 대해서는 명시적으로 요청해야 합니다.

<manifest ...>
    <!-- Only declare permissions that your app actually needs. In this example,
    we declare permissions for the camera. -->
    <uses-permission android:name="android.permission.CAMERA"/>
    <application ...>
        ...
    </application>
</manifest>

글라스 권한을 요청하기 전

권한 원칙 및 워크플로를 검토하여 사용자에게 최상의 환경을 제공하는지 확인합니다. 예를 들어 앱에 필요한 런타임 권한을 사용자가 이미 부여했는지, 스마트 안경 전용 권한을 요청하기 전에 사용자에게 앱에서 근거를 표시해야 하는지를 확인합니다.

권한 시나리오

오디오 및 디스플레이 글래스에서 위험한 런타임 권한을 요청할 때 발생할 수 있는 몇 가지 시나리오는 다음과 같습니다.

  • 예측된 활동에서 런타임 권한 요청
  • 휴대전화 활동에서 런타임 권한 요청

각 시나리오에 관한 자세한 내용은 이 가이드의 다음 섹션을 참고하세요.

투사된 활동에서 런타임 권한 요청

프로젝션된 활동에서 오디오 또는 디스플레이 글래스의 런타임 권한을 요청하려면 ProjectedActivityCompat.requestPermissions 메서드를 사용합니다.

이 메서드를 호출하면 안경과 호스트 휴대전화 모두에서 조정된 사용자 흐름이 트리거됩니다.

  1. 글래스에서: 시스템이 글래스에서 프로젝션된 동반자 활동을 열어 사용자에게 휴대전화를 확인하여 권한 요청에 응답하도록 안내합니다.
  2. 휴대전화: Android 시스템 권한 대화상자가 휴대전화 화면에 표시됩니다. 대화상자에는 사용자가 휴대전화 자체가 아닌 글래스에 권한을 부여하고 있다고 명시되어 있습니다. 그러면 사용자는 요청을 부여하거나 거부할 수 있습니다.

다음 예시에서는 프로젝션된 활동에서 글래스 권한을 요청하는 방법을 보여줍니다.

@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
private fun requestCameraPermission() {
    lifecycleScope.launch {
        try {
            ProjectedActivityCompat.requestPermissions(
                this@PermissionsFromProjectedActivity,
                arrayOf(Manifest.permission.CAMERA),
                // CAMERA_PERMISSION_REQUEST_CODE is a developer defined constant
                CAMERA_PERMISSION_REQUEST_CODE,
            )
        } catch (e: IllegalStateException) {
            // Thrown when the projected system service can't be bound.
            Log.e(TAG, "Camera permission request failed: projected service unavailable.", e)
        }
    }
}

코드에 관한 핵심 사항

  • 표준 ActivityCompat 메서드 대신 ProjectedActivityCompat.requestPermissions을 사용합니다. 이 메서드는 호스트 휴대전화가 아닌 오디오 및 디스플레이 글래스의 런타임 권한을 명시적으로 타겟팅합니다.

권한 결과 처리

사용자가 휴대전화에서 권한 대화상자에 응답하면 onRequestPermissionsResult 콜백을 호출하여 결정이 앱에 전달됩니다.

시스템에서 투영된 동반자 활동을 자동으로 닫습니다. 오디오 안경에서는 오디오 알림 재생이 완료된 후에 이 문제가 발생합니다. 디스플레이 안경에서는 사용자가 모든 권한 대화상자에 응답한 후에 발생합니다.

응답을 처리하려면 권한 요청을 시작한 Activity 인스턴스 내에서 onRequestPermissionsResult()를 재정의합니다.

다음 코드 스니펫은 콜백을 처리하고 사용자가 요청된 권한을 부여했는지 확인하는 방법을 보여줍니다.

@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<String>,
    grantResults: IntArray,
    deviceId: Int,
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId)
    if (requestCode != CAMERA_PERMISSION_REQUEST_CODE) return

    val isCameraGranted =
        grantResults.getOrNull(permissions.indexOf(Manifest.permission.CAMERA)) ==
            PackageManager.PERMISSION_GRANTED

    if (isCameraGranted) {
        initializeCameraFeatures()
    } else {
        onCameraPermissionDenied()
    }
}

코드에 관한 핵심 사항
  • onRequestPermissionsResult 콜백과 함께 deviceId 오버로드를 사용하여 권한 상태가 호스트 전화가 아닌 오디오나 디스플레이 글래스와 같은 특정 컨텍스트에 올바르게 매핑되도록 합니다.
  • 앱은 승인된 결과와 거부된 결과를 모두 적절하게 처리해야 합니다.

전화 활동에서 런타임 권한 요청

앱이 휴대전화 활동에서 실행되지만 오디오 또는 디스플레이 글래스 권한이 필요한 경우(예: 사용자가 1인칭 시점을 위해 동영상 스트림을 글래스 카메라로 전환할 수 있도록) 기기별 Activity#requestPermissions(permissions, requestCode, deviceId) 메서드를 사용하여 권한을 요청합니다.

// Request the projected permission from phone activity
requestPermissions(
    arrayOf(Manifest.permission.CAMERA),
    // REQUEST_CODE_GLASSES_CAMERA is a developer-defined constant
    REQUEST_CODE_GLASSES_CAMERA,
    projectedDeviceId
)

코드에 관한 핵심 사항

  • 오디오 및 디스플레이 글래스를 타겟팅하려면 createProjectedDeviceContext를 사용하여 만든 프로젝션 컨텍스트에서 적절한 기기 ID를 가져옵니다. requestPermissions 메서드 호출 시 이 ID를 전달합니다.

권한 결과 처리

사용자가 휴대전화에서 권한 대화상자에 응답하면 onRequestPermissionsResult 콜백을 호출하여 결정이 앱에 전달됩니다.

응답을 처리하려면 권한 요청을 시작한 Activity 인스턴스 내에서 onRequestPermissionsResult를 재정의합니다.

다음 코드 스니펫은 콜백을 처리하고 사용자가 요청된 권한을 부여했는지 확인하는 방법을 보여줍니다.

@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<String>,
    grantResults: IntArray,
    deviceId: Int,
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId)
    if (requestCode != CAMERA_PERMISSION_REQUEST_CODE) return

    val isCameraGranted =
        grantResults.getOrNull(permissions.indexOf(Manifest.permission.CAMERA)) ==
            PackageManager.PERMISSION_GRANTED

    if (isCameraGranted) {
        initializeCameraFeatures()
    } else {
        onCameraPermissionDenied()
    }
}

코드에 관한 핵심 사항
  • onRequestPermissionsResult 콜백과 함께 deviceId 오버로드를 사용하여 권한 상태가 호스트 휴대전화가 아닌 오디오 또는 디스플레이 글래스와 같은 특정 컨텍스트에 올바르게 매핑되도록 합니다.
  • 앱은 승인된 결과와 거부된 결과를 모두 적절하게 처리해야 합니다.