機密性の高い情報へのアクセスについて説明する

位置情報、マイク、カメラに関連する権限により、ユーザーに関する特に機密性の高い情報へのアクセス権がアプリに付与されます。プラットフォームには、このページで説明するメカニズムがいくつか組み込まれており、ユーザーは常に情報を入手して、位置情報、マイク、カメラにアクセス可能なアプリを制御できます。

こうしたプライバシーの保護に関するシステムの機能は、プライバシーに関するベスト プラクティスに従う限り、アプリが位置情報、マイク、カメラに関連する権限を処理する方法に影響を与えません。

特に、アプリでは次のようにする必要があります。

  • ユーザーがアプリに CAMERA 権限を付与するまで、デバイスのカメラへのアクセスを待機する。
  • ユーザーがアプリに RECORD_AUDIO 権限を付与するまで、デバイスのマイクへのアクセスを待機する。
  • 位置情報の利用許可をリクエストする方法についてのガイドで説明されているように、位置情報を必要とするアプリ内の機能をユーザーが操作するまで待ってから、ACCESS_COARSE_LOCATION 権限または ACCESS_FINE_LOCATION 権限をリクエストする。
  • ユーザーがアプリに ACCESS_COARSE_LOCATION 権限または ACCESS_FINE_LOCATION 権限を付与するまで待ってから、ACCESS_BACKGROUND_LOCATION 権限をリクエストする。

プライバシー ダッシュボード

縦のタイムラインに、位置情報にアクセスしたさまざまなアプリと、そのアクセスが発生した時刻が表示されます
図 1. プライバシー ダッシュボードの一部である位置情報使用状況画面。

Android 12 以降を搭載するサポート対象デバイスでは、システム設定にプライバシー ダッシュボードの画面が表示されます。この画面では、ユーザーは位置情報、カメラ、マイクの情報にアプリがいつアクセスしたのかが表示される個別画面にアクセスできます。各画面には、さまざまなアプリが特定の種類のデータにいつアクセスしたのかを示すタイムラインが表示されます。図 1 に、位置情報のデータアクセス タイムラインを示します。

データアクセスの根拠を示す

アプリは、位置情報、カメラ、マイクの情報にアクセスする理由をユーザーが理解できるよう、根拠を示すことができます。この根拠は、新しいプライバシー ダッシュボード画面、アプリの権限画面、またはそれらの両方に表示できます。

アプリが位置情報、カメラ、マイクの情報にアクセスする理由を説明する手順は次のとおりです。

  1. 起動時にアプリが特定の種類のデータアクセス アクションを行う根拠を示すアクティビティを追加します。このアクティビティ内で、android:permission 属性を START_VIEW_PERMISSION_USAGE に設定します。

    Android 12 以降をターゲットとするアプリの場合は、明示的に android:exported 属性の値を定義する必要があります。

  2. 新しく追加したアクティビティに次のインテント フィルタを追加します。

    <!-- android:exported required if you target Android 12. -->
    <activity android:name=".DataAccessRationaleActivity"
              android:permission="android.permission.START_VIEW_PERMISSION_USAGE"
              android:exported="true">
           <!-- VIEW_PERMISSION_USAGE shows a selectable information icon on
                your app permission's page in system settings.
                VIEW_PERMISSION_USAGE_FOR_PERIOD shows a selectable information
                icon on the Privacy Dashboard screen. -->
        <intent-filter>
           <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
           <action android:name="android.intent.action.VIEW_PERMISSION_USAGE_FOR_PERIOD" />
           <category android:name="android.intent.category.DEFAULT" />
           ...
        </intent-filter>
    </activity>
    
  3. データアクセス根拠アクティビティで表示する内容を決定します。たとえば、アプリのウェブサイトやヘルプセンターの記事を表示できます。アプリがアクセスするデータの種類と、そのアクセスがいつ発生したのかについて、より詳細な説明を提供するには、権限使用状況インテントを呼び出したときに追加されるエクストラを処理します。

追加したインテント フィルタに応じて、特定の画面でアプリ名の横に情報アイコンが表示されます。

  • VIEW_PERMISSION_USAGE アクションを含むインテント フィルタを追加した場合、システム設定にあるアプリの権限ページにアイコンが表示されます。
  • VIEW_PERMISSION_USAGE_FOR_PERIOD アクションを含むインテント フィルタを追加した場合、プライバシー ダッシュボード画面にアプリが表示されるたびに、アプリ名の横にアイコンが表示されます。

ユーザーがアイコンを選択すると、アプリの根拠アクティビティが開始されます。

右上隅に角の丸い長方形があり、その中にカメラアイコンとマイクアイコンがある
図 2. 最近のデータアクセスが表示されるマイクとカメラのインジケーター。

インジケーター

Android 12 以降を搭載しているデバイスでは、アプリがマイクまたはカメラにアクセスすると、ステータスバーにアイコンが表示されます。アプリが没入モードの場合は、画面の右上隅にアイコンが表示されます。ユーザーはクイック設定を開き、アイコンを選択することで、現在どのアプリがマイクまたはカメラを使用しているのかを確認できます。図 2 に、アイコンを含むスクリーンショットの例を示します。

インジケーターの画面位置を特定する

アプリが没入モードまたはフルスクリーン UI をサポートしている場合は、インジケーターがアプリの UI と一時的に重複する可能性があります。UI がこれらのインジケーターに適応できるように、システムによって getPrivacyIndicatorBounds() メソッドが導入されています。これについては、次のコード スニペットをご覧ください。この API を使用すると、インジケーターが表示される可能性がある境界を特定できます。その後、画面の UI を整理する方法を変更できます。

Kotlin

view.setOnApplyWindowInsetsListener { view, windowInsets ->
    val indicatorBounds = windowInsets.getPrivacyIndicatorBounds()
    // change your UI to avoid overlapping
    windowInsets
}

Toggles

「カメラへのアクセス」、「マイクへのアクセス」というラベルが付いたクイック設定タイル。
図 3. クイック設定でのマイクとカメラの切り替え。

Android 12 以降を搭載するサポート対象デバイスでは、切り替えオプションを 1 回押すだけで、デバイス上のすべてのアプリに対するカメラとマイクへのアクセスを有効または無効にできます。ユーザーは図 3 に示すように、クイック設定から、またはシステム設定の [プライバシー] 画面から、切り替えオプションにアクセスできます。

カメラとマイクの切り替えは、デバイス上のすべてのアプリに影響します。

  • ユーザーがカメラへのアクセスをオフにすると、アプリは空白のカメラフィードを受け取ります。
  • ユーザーがマイクへのアクセスをオフにすると、アプリはサイレント オーディオを受け取ります。また、HIGH_SAMPLING_RATE_SENSORS 権限を宣言しているかどうかにかかわらず、モーション センサーはレート制限されます。

ユーザーがカメラまたはマイクへのアクセスをオフにしてから、カメラまたはマイクの情報にアクセスする必要があるアプリを起動すると、システムからユーザーに対し、デバイス全体の切り替えがオフになっていることが通知されます。

デバイスのサポートを確認する

デバイスがマイクとカメラの切り替えをサポートしているかどうかを確認するには、次のコード スニペットに示すロジックを追加します。

Kotlin

val sensorPrivacyManager = applicationContext
        .getSystemService(SensorPrivacyManager::class.java)
        as SensorPrivacyManager
val supportsMicrophoneToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.MICROPHONE)
val supportsCameraToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.CAMERA)

Java

SensorPrivacyManager sensorPrivacyManager = getApplicationContext()
        .getSystemService(SensorPrivacyManager.class);
boolean supportsMicrophoneToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.MICROPHONE);
boolean supportsCameraToggle = sensorPrivacyManager
        .supportsSensorToggle(Sensors.CAMERA);