スマートフォンと同様に、オーディオ グラスやディスプレイ グラスのカメラなどの機密性の高いハードウェアにアクセスするには、ユーザーの明示的な同意が必要です。これらはグラス固有の権限と見なされ、スマートフォンで対応する権限がすでに付与されている場合でも、アプリは実行時にこれらの権限をリクエストする必要があります。
アプリのマニフェストで権限を宣言する
権限をリクエストする前に、<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 メソッドを使用します。
このメソッドを呼び出すと、グラスとホスト スマートフォンの両方で調整されたユーザーフローがトリガーされます。
- グラス上: システムは、グラス上で投影されたコンパニオン アクティビティを開き、権限のリクエストに応答するためにスマートフォンを確認するようユーザーに指示します。
- スマートフォン: スマートフォンの画面に 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オーバーロードを使用して、権限ステータスがホスト スマートフォンではなく、オーディオ グラスやディスプレイ グラスなどの特定のコンテキストに正しくマッピングされるようにします。- アプリは、許可された結果と拒否された結果の両方を適切に処理する必要があります。
スマートフォン アクティビティで実行時の権限をリクエストする
アプリがスマートフォン アクティビティで実行されているが、オーディオまたはディスプレイ グラスの権限が必要な場合(たとえば、ユーザーが動画ストリームをグラスのカメラに切り替えて一人称視点にできるようにする場合)は、デバイス固有の 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 を取得します。この ID を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オーバーロードを使用して、権限ステータスが特定のコンテキスト(ホスト スマートフォンではなく、オーディオ グラスやディスプレイ グラスなど)に正しくマッピングされるようにします。- アプリは、許可された結果と拒否された結果の両方を適切に処理する必要があります。