Permission GroupはAndroidの権限グループ化メカニズムであり、機能的に関連する危険な権限を1つの論理カテゴリにまとめます。Android Permissions Overview, 2024によると、権限グループはユーザーインターフェースを簡素化します。ユーザーがグループ内の1つの権限を付与すると、残りは追加のダイアログなしで自動的に付与されます。これによりリクエスト数が減少し、UXが向上します。
重要なポイント
Permission GroupはAndroidのシステムメカニズムで、複数の危険な権限を機能的な目的に基づいて1つのグループにまとめます。各グループには文字列識別子があり、例えばandroid.permission-group.CAMERAやandroid.permission-group.LOCATIONなどがあります。1つのグループ内のすべての権限は論理的に関連し、デバイスの関連機能へのアクセスを提供します。
権限グループは、Android 6.0 Marshmallowでランタイム権限モデルとともに登場しました。その主な目的は、ユーザーとの対話を簡素化することです。個々の権限ごとに一連のダイアログを表示する代わりに、システムはグループごとに1つのダイアログを表示します。ユーザーがグループ内の1つの権限を付与すると、残りは自動的に承認されたと見なされます。Android UX Research(2015)によると、これにより初回起動時の拒否数が20パーセント減少しました。
開発者が独自のPermission Groupを作成できないことを理解することが重要です。グループはオペレーティングシステムレベルで事前定義され、各デバイスのpermissions.xmlファイルに記述されています。アプリはuses-permissionを宣言するだけで、システムはprotectionLevelとAOSPでの分類に基づいて、権限を自動的にそのグループにマッピングします。
権限とグループのマッピングは、システム権限定義のpermissionGroup属性を介して行われます。例えば、CAMERAはpermissionGroup="android.permission-group.CAMERA"、ACCESS_FINE_LOCATIONはpermissionGroup="android.permission-group.LOCATION"で宣言されています。このマッピングはAndroid Open Source Projectのコードにハードコードされており、すべての認定デバイスで同一です。
グループメカニズムは「グループごとに1つのダイアログ」の原則で動作します。アプリが初めて危険な権限をリクエストすると、システムはそのPermission Groupを確認します。このグループからまだ権限が付与されていない場合 — ダイアログが表示されます。同意後、システムはグループ全体を付与済みとしてマークし、同じグループからの他の権限の後続リクエストはUIなしで処理されます。
簡略化されたアルゴリズムは次のようになります:
このメカニズムは危険な権限にのみ適用されます。通常の権限にはグループがなく、このロジックには関与しません。特権権限と署名権限もグループ化されません — これらには別のアクセス制御システムがあります。
グループは「逆方向」には機能しません。設定からグループ内の1つの権限を撤回しても、その権限のみが撤回され、他は影響を受けません。また、ユーザーがグループのダイアログを拒否しても、他のグループはブロックされません — 別のグループからの新しい権限はそれぞれ独自のダイアログを表示します。Permission GroupはリクエストのUXのみに影響し、セキュリティモデルには影響しません。
Androidは危険な権限に対して以下のシステムPermission Groupを定義しています。各グループには、共通の機能的目的で結合された1つ以上の権限が含まれます。
| グループ識別子 | グループ内の権限 | 説明 |
|---|---|---|
| CAMERA | CAMERA | デバイスカメラへのアクセス |
| LOCATION | ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION | 位置情報(正確およびおおよそ) |
| MICROPHONE | RECORD_AUDIO | マイク経由の音声録音 |
| PHONE | READ_PHONE_STATE、CALL_PHONE、READ_CALL_LOG、WRITE_CALL_LOG、ADD_VOICEMAIL、USE_SIP | 電話機能 |
| CONTACTS | READ_CONTACTS、WRITE_CONTACTS、GET_ACCOUNTS | 連絡先とアカウントへのアクセス |
| SMS | READ_SMS、SEND_SMS、RECEIVE_SMS、RECEIVE_WAP_PUSH、RECEIVE_MMS | SMSの送受信 |
| STORAGE | READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE | 外部ストレージの読み取りと書き込み |
| CALENDAR | READ_CALENDAR、WRITE_CALENDAR | カレンダーへのアクセス |
| SENSORS | BODY_SENSORS | 生体センサー(心拍数など) |
| ACTIVITY_RECOGNITION | ACTIVITY_RECOGNITION | 身体活動の認識 |
Android 13(API 33)では、新しいグループNEARBY_DEVICESが追加され、BLUETOOTH_SCAN、BLUETOOTH_CONNECT、BLUETOOTH_ADVERTISEを統合しています。また、STORAGEグループは部分的にメディア権限READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIOに置き換えられました。これらはSTORAGEの一部ではなく、グループ化されない独立した危険な権限です。
開発者は、マニフェストのpermissionGroup属性を介して、カスタムPermission Groupを持つ独自の権限を宣言できます。ただし、これは同じアプリのカスタム権限に対してのみ機能し、システムUIダイアログには影響しません。実際には、カスタムPermission Groupはほとんど使用されません — 同じスタック内のアプリ間の連携のために使用されます。
Permission Groupの影響はユーザーエクスペリエンスに大きなものです。グループ化のおかげで、ユーザーは異なる権限に対して8つの個別のダイアログではなく、いくつかのグループダイアログを目にします。これにより認知負荷が軽減され、ユーザーがその目的を理解せずに重要な権限を拒否する可能性が低減します。
UX調査によると、グループダイアログはユーザーにとってより透過的であると認識されています。アプリが「カメラへのアクセス権限」をリクエストすると、ユーザーはコンテキストを理解します。各権限が個別にリクエストされた場合 — CAMERA、CAMERA2、FLASHLIGHT — 冗長性の印象を与えるでしょう。Permission Groupはこの細かさを抽象化します。
ベストプラクティスは、一度に1つのグループからのみ権限をリクエストすることです。アプリがカメラと位置情報の両方を必要とする場合、1回のrequestPermissions呼び出しでリクエストしないでください。最初に1つのグループを、その必要性を説明した後にリクエストし、次に2つ目をリクエストします。これにより、ユーザーは制御権と各機能の順次理解を得ることができます。
Permission GroupとProtectionLevelはAndroidの権限システムの2つの異なる次元です。ProtectionLevelは権限の付与方法(normal、dangerous、signature、privileged)を決定し、Permission GroupはUI表示のためのカテゴリです。これらは独立していますが、実際にはdangerous + permission groupの組み合わせが最も一般的です。
同じ ProtectionLevel の権限でも異なるグループに属することができます。例えば、ACCESS_FINE_LOCATIONとCAMERAはどちらもprotectionLevel dangerousですが、異なるグループ — LOCATIONとCAMERAに属します。逆に、同名の権限は常に同じグループに属します:ACCESS_FINE_LOCATIONとACCESS_COARSE_LOCATIONは両方ともLOCATIONにあります。
より上位の保護レベル — signatureとprivileged — はUIにPermission Groupを使用しません。その付与はシステムレベルで制御されます。signatureはシステムと同じ証明書で署名されたアプリに付与され、privilegedはシステムイメージ内のアプリに付与されます。これらの権限のグループは存在しますが、UXダイアログに影響しません。なぜなら、これらのダイアログは単に表示されないからです。
開発者はPackageManagerを介してプログラムで任意の権限のPermission Groupを特定できます。getPermissionInfoメソッドは、グループの文字列識別子を含むgroupフィールドを持つPermissionInfoを返します。これはログ記録、分析、カスタム権限UI画面に役立ちます。
fun getPermissionGroupName(
permission: String
): String? {
return try {
val pm = packageManager
val info = pm.getPermissionInfo(
permission,
PackageManager.GET_META_DATA
)
info.group
} catch (e: NameNotFoundException) {
null
}
}
fun getPermissionsByGroup(
group: String
): List<String> {
val pm = packageManager
val perms = pm.queryPermissionsByGroup(
group,
PackageManager.GET_META_DATA
)
return perms.map { it.name }
}
Permission Groupの知識はリクエストアーキテクチャの構築に役立ちます。特定のグループの権限リストを返すPermissionGroupProviderという抽象化を作成できます。これによりテストが簡素化されます:単体テストでは、プロバイダーはPackageManagerを呼び出さずにモックデータを返します。インストルメンテーションテストでは、システムから実際のグループを返します。
Dagger HiltやKoinを介したPermissionGroupProviderの統合により、権限とグループのマッピングを集中管理できます。プロバイダーでは、PackageManager.queryPermissionsByGroupの結果をキャッシュして、リクエストごとに繰り返しシステム呼び出しを行うことを避けられます。これは、権限の完全なリストとそのステータスが表示される設定画面で特に重要です。
拒否に関する分析を収集する際には、権限名だけでなくそのPermission Groupも記録することが有用です。これにより、どの機能領域が最も多くの拒否を引き起こしているかを特定できます。例えば、LOCATIONグループは伝統的に最も高い拒否率を持っています — Google Play Consoleの統計によると約40パーセントです。
グループ別の分析は製品決定に役立ちます。CONTACTSグループの拒否率が高い場合、リクエストのタイミングを再検討するか、理由説明ダイアログを追加する必要があるかもしれません。分析へのグループベースのアプローチは、個々の権限の分析よりも完全な全体像を提供します。グループ全体での拒否数は、機能領域に対するユーザーの全体的な態度を反映するからです。
よくある質問
Permission Groupは、機能的に関連する危険な権限を1つのカテゴリにまとめるメカニズムです。ユーザーがグループ内の1つの権限を付与すると、残りは追加のダイアログなしで自動的に付与されます。
標準のAndroidには約10の主要グループがあります:CAMERA、LOCATION、MICROPHONE、PHONE、CONTACTS、SMS、STORAGE、CALENDAR、SENSORS、ACTIVITY_RECOGNITION。Android 13+でNEARBY_DEVICESが追加されました。
はい、カスタム権限用にAndroidManifest.xmlのpermissionGroup属性を介して可能です。ただし、これはアプリ内の権限に対してのみ機能し、システムUIダイアログには影響しません。実際にはほとんど使用されません。
グループから1つの権限を取り消しても、他は取り消されません。ユーザーはACCESS_FINE_LOCATIONを無効にできますが、ACCESS_COARSE_LOCATIONはアクティブのままです。グループは付与にのみ影響し、取り消しには影響しません。
PackageManager.getPermissionInfoを使用し、groupフィールドを読み取ります。メソッドはグループの文字列識別子を返します。例:android.permission-group.CAMERA。権限にグループがない場合、フィールドはnullになります。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。