AndroidManifest Permissions:重要な概念、宣言と許可の種類

著者: IT Sectr 公開日: 2026-05-21 読了時間: 10 分

AndroidManifest Permissions は、AndroidManifest.xml ファイル内の権限宣言であり、アプリケーションがアクセスできるシステムリソースとデータを決定します。Androidでは、対応するAPIを使用する前に、マニフェストで各権限を宣言する必要があります。カメラや位置情報からSMS送信や連絡先へのアクセスまで、すべての権限が対象です。Android Developer Documentation によると、各権限は4つの保護レベルのいずれかに分類されます:normal、dangerous、signature、specialです。

重要なポイント

  • AndroidManifest.xml — すべてのアプリケーション権限の宣言を含むマニフェストファイル
  • 保護レベル — normal、dangerous、signature、special。それぞれ異なる要求メカニズム
  • Runtime Permission — dangerous権限は実行時の要求が必要(Android 6+)
  • 宣言と要求の違い — マニフェストでの宣言は必須だが、dangerousはコード内での追加要求が必要
  • グループ — 権限はグループ化され、1つへの同意でグループ全体へのアクセスが許可される

AndroidManifest Permissionsとは?

AndroidManifest Permissions は、保護されたデータやシステム機能へのアプリケーションのアクセスを制御するAndroidのセキュリティメカニズムです。すべてのアプリケーションは、 要素を使用して AndroidManifest.xml ファイルで必要な権限を宣言する必要があります。宣言がない場合、対応するAPIを呼び出すと SecurityException セキュリティエラーが発生します。

Androidの権限モデルはいくつかの進化段階を経てきました。Android 6.0(API 23)より前は、すべての権限がインストール時に付与されていました。ユーザーは完全なリストを確認し、アプリケーションのインストールに同意するか拒否していました。Android 6.0以降、dangerousレベルの権限は実行時に(Runtime Permissions)要求されるようになり、ユーザーにより柔軟な制御を提供しています。

権限は4つの保護レベルに分かれています:normal(インストール時に自動付与)、dangerous(実行時の要求が必要)、signature(同じ証明書で署名されたアプリケーションのみ利用可能)、special(設定で個別に有効化が必要)。各レベルには独自の付与と取り消しのメカニズムがあります。

Google I/O 2024 によると、Android 15ではより細かい権限が導入される予定です。ユーザーはメディアライブラリ全体ではなく、特定のファイルのみへのアクセスを許可できるようになります。これは、デフォルトで提供されるデータ量を最小限に抑えるというAndroidのトレンドを継続するものです。

iOSの権限モデルとの違い

すべての権限が実行時に要求されるiOSとは異なり、Androidは権限をインストール時と実行時に分割しています。normalレベルはユーザーに通知することなくインストール時に自動的に付与されます。dangerousレベルはiOSと同様に明示的なダイアログが必要です。

もう1つの違い:Androidでは、権限は権限グループにグループ化されています。ユーザーがカメラへのアクセスに同意すると、アプリケーションは自動的にマイクへのアクセスも取得します。これらは同じMICROPHONEグループに属しているためです。iOSでは、各権限はグループに関係なく個別に要求されます。

Androidバージョンごとの権限の進化

Androidバージョン権限モデルの変更
Android 1.0~5.xすべての権限がインストール時に付与
Android 6.0(API 23)dangerousレベル向けRuntime Permissionsの導入
Android 10(API 29)Scoped Storage — ファイルシステムへのアクセス制限
Android 11(API 30)自動リセット権限 — 未使用の権限がリセット
Android 14(API 34)メディアアクセス(写真、動画、音声)の実行時権限

権限の種類

Androidは権限に対して4つの保護レベルを定義しており、それぞれに独自の付与ルールがあります。各レベルを詳しく見ていきましょう。

Normal権限(インストール時)

Normal権限は、ユーザーへの通知や要求なしにアプリケーションのインストール時に自動的に付与されます。これらはユーザーのプライバシーを脅かさない低リスクの機能をカバーします:INTERNET、ACCESS_NETWORK_STATE、VIBRATE、BLUETOOTH。ユーザーは同意ダイアログを表示されません。権限はインストール時に付与されたものと見なされます。

開発者はnormal権限のためにコード内で要求を処理する必要はありません。マニフェストで宣言するだけで十分です。ただし、Android 12+では、Google Playからインストールする際に、ユーザーはすべてのnormal権限を一覧表示する「権限」タブを表示し、透明性が向上しています。Statista(2024) によると、Google Playの90%以上のアプリケーションが最も一般的なnormal権限としてINTERNETを使用しています。

Dangerous権限(実行時)

Dangerous権限は、プライバシーを侵害する可能性のあるデータや機能へのアクセスをカバーします:カメラ、マイク、位置情報、連絡先、SMS、電話、カレンダー、身体センサー。これらの権限には2段階のメカニズムが必要です:マニフェストでの宣言 + ActivityCompat.requestPermissions() による実行時の要求。

ユーザーはdangerous権限を拒否でき、アプリケーションはこのシナリオを適切に処理する必要があります。Android 11+では、ユーザーが2回拒否すると、以降の要求はシステムダイアログを表示せず、システムは自動的にDENIEDを返します。この場合、アプリケーションはユーザーを設定に誘導する必要があります。

Signature権限とSpecial権限

signatureレベル — アプリケーションがシステムまたは権限を定義した別のアプリケーションと同じ証明書で署名されている場合、権限は自動的に付与されます。システムアプリやエンタープライズアプリで使用されます。例:BIND_ACCESSIBILITY_SERVICE — システムアプリのみ利用可能。

specialレベル(SYSTEM_ALERT_WINDOW、WRITE_SETTINGS、REQUEST_INSTALL_PACKAGES、MANAGE_EXTERNAL_STORAGE) — システム設定を通じてユーザーの明示的な操作が必要です。アプリケーションは Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION) を使用して設定ページを開くことができます。Google Playではspecial権限の使用が制限されており、公開時にフォームでの正当性の説明が必要です。

Runtime Permission:dangerous権限の扱い方

Android 6.0以降、すべてのdangerous権限は実行時に要求する必要があります。Kotlinでのruntime permissionsの完全なワークフローを見ていきましょう。

権限の確認と要求

dangerous権限を必要とするAPIを呼び出す前に、常に ContextCompat.checkSelfPermission() で現在のステータスを確認してください。ステータスが PERMISSION_GRANTED の場合はAPIを呼び出せます。PERMISSION_DENIED の場合は、ActivityResultContract RequestPermission(AndroidX)または非推奨の requestPermissions() を使用して権限を要求する必要があります。

複数の権限を同時に要求するには、ActivityResultContracts.RequestMultiplePermissions を使用することを推奨します。Googleは、関連する権限(例:動画撮影用のカメラ+マイク)を1つのダイアログにグループ化し、ユーザーが要求の全体的なコンテキストを理解できるようにすることを推奨しています。

kotlin
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat

class CameraActivity : AppCompatActivity() {
    private val requestPermissionLauncher =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted: Boolean ->
            if (isGranted) {
                openCamera()
            } else {
                explainWhyPermissionNeeded()
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        checkCameraPermission()
    }

    private fun checkCameraPermission() {
        when {
            ContextCompat.checkSelfPermission(this,
                Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED -> {
                openCamera()
            }
            shouldShowRequestPermissionRationale(
                Manifest.permission.CAMERA
            ) -> {
                showRationale()
            }
            else -> {
                requestPermissionLauncher.launch(
                    Manifest.permission.CAMERA
                )
            }
        }
    }
}

「今後は確認しない」拒否の処理

ユーザーが2回拒否すると、Androidは要求を「Never ask again」状態に移行します。この場合、shouldShowRequestPermissionRationale() は false を返し、システムダイアログは表示されません。アプリケーションは Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) を使用してユーザーをシステム設定に誘導する必要があります。

重要:最初の拒否の直後に設定を開くダイアログを表示しないでください。これは攻撃的な動作と見なされます。shouldShowRequestPermissionRationale() を使用して、説明を表示する必要があるかどうかを判断してください。Material Design Guidelines は、単なる「設定を開く」ボタンではなく、アクセスの価値を説明する画面を表示することを推奨しています。

kotlin
private fun openAppSettings() {
    Intent(
        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
        Uri.fromParts("package", packageName, null)
    ).also { intent ->
        startActivity(intent)
    }
}

private fun showPermissionSettings() {
    AlertDialog.Builder(this)
        .setTitle("カメラへのアクセス")
        .setMessage("設定でカメラへのアクセスを許可、"
            + "プロフィール写真を撮影するため")
        .setPositiveButton("設定を開く") { _, _ ->
            openAppSettings()
        }
        .setNegativeButton("キャンセル", null)
        .show()
}

AndroidManifest.xmlでの権限宣言

AndroidManifest.xmlファイルには、アプリケーションが使用する各権限の 要素が含まれます。権限は レベルで 要素の前に宣言されます。

宣言の構文

各権限は、android:name 属性を使用して完全な権限名を指定する個別の 要素で宣言されます。特定のAndroidバージョンで導入された権限については、maxSdkVersion 属性を使用して宣言を必要なバージョンに限定してください。これにより互換性が向上します。

たとえば、WRITE_EXTERNAL_STORAGE 権限は Android 10+(Scoped Storage)では不要なため、maxSdkVersion="28"(Android 9)を指定します。これにより、新しいバージョンでのユーザーからの不要な質問を防げます。Android Studio はLintを通じて推奨される maxSdkVersion について警告します。

xml
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Normal permissions (install-time) -->
    <uses-permission
        android:name="android.permission.INTERNET" />
    <uses-permission
        android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- Dangerous permissions (runtime) -->
    <uses-permission
        android:name="android.permission.CAMERA" />
    <uses-permission
        android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!-- Legacy storage permission limited to API 28 and below -->
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="28" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />

    <application>
        <!-- ... -->
    </application>
</manifest>

フィルタリングのための の使用

要素は、アプリケーションが特定のハードウェア(カメラ、GPS、NFC)を必要とすることを示します。android:required="false" 属性を使用すると、そのハードウェアがないデバイスにもアプリケーションをインストールできます。可用性はコードで確認されます。required="true" の場合、Google Playはアプリケーションをフィルタリングし、不適切なデバイスでは利用できなくなります。

すべてのハードウェア機能について required="false" を設定し、PackageManager.hasSystemFeature() でプログラム的に可用性を確認することをお勧めします。これにより、アプリケーションの対象ユーザーが広がります。唯一の例外は、その機能がアプリケーションの動作に不可欠な場合です(GPSなしのタクシー配車アプリは意味がありません)。

ベストプラクティスとよくあるエラー

適切な権限管理はAndroidアプリケーションの品質における重要な側面です。主な推奨事項と典型的なエラーを見ていきましょう。

要求する権限を最小限に

アプリケーションの動作に本当に必要な権限のみを要求してください。余分な権限はインストール率を低下させ、拒否数を増やします。Google Play Console は、権限セットが原因でインストールを拒否したユーザー数を表示します。AppBrain(2024) によると、10個以上のdangerous権限を持つアプリケーションはインストール数が35%少なくなっています。

定期的に権限リストを見直してください。特に、一部の権限がオプションになる新しいAndroidバージョンに移行する際は、未使用の権限を削除してください。たとえば、Android 13+のフォトピッカー(ActivityResultContracts.PickVisualMedia)では、dangerousな READ_MEDIA_IMAGES 権限なしでメディアライブラリにアクセスできます。

要求前に説明を表示

dangerous権限を要求する前に、その権限が必要な理由と提供する価値を説明する画面をユーザーに表示してください。Material Design は、アイコン、簡潔なテキスト、「続行」ボタンを備えたボトムシートまたはダイアログの使用を推奨しています。説明を表示することで、直接要求する場合と比較して同意率が20~30%向上します。

launch() を呼び出す前に shouldShowRequestPermissionRationale() を確認してください。true の場合は説明を表示します。false の場合は、権限が既に付与されているか、ユーザーが永続的に拒否しています(今後は確認しない)。後者の場合は、要求を繰り返す代わりに「設定を開く」ボタンを表示してください。

すべての権限シナリオのテスト

すべての可能なシナリオをテストしてください:権限の付与、拒否、永続的な拒否、設定での権限取り消し、権限のリセット(Android 11+の自動リセット)。各シナリオはクラッシュやデータ損失なしで処理される必要があります。Android Testing Guide は、テストを自動化するために TestPermission ライブラリの使用を推奨しています。

アプリケーションの実行中にユーザーが権限を取り消すシナリオ(アプリを最小化 → 設定 → 取り消し)には特に注意してください。アプリケーションに戻ったら、onResume() ですべての権限を再確認してください。権限ステータスのキャッシュに依存しないでください。ユーザーはいつでも変更できます。

よくあるエラー

  • checkSelfPermission を最初に確認せずに権限を要求する — 不要なダイアログを表示
  • shouldShowRequestPermissionRationale を無視する — 最初の拒否後のUXを悪化
  • コンテキストなしで権限を要求する(単に「アクセスを許可しますか?」)— 同意率が低下
  • Android 10+で maxSdkVersion なしで WRITE_EXTERNAL_STORAGE を使用 — 不要な要求
  • onResume での権限確認の欠如 — 設定での権限取り消しを見逃す

よくある質問

SDKが要求する場合でも権限を宣言する必要がありますか?

はい。SDKがそのマニフェストに権限を含める場合、ビルド時にアプリケーションのマニフェストとマージされます。AndroidManifest.xml で tools:node="remove" を使用して、不要なSDK権限を削除できます。

権限の拒否を処理しないとどうなりますか?

権限なしでAPIを呼び出すと SecurityException が発生し、アプリケーションがクラッシュします。対応するAPIを使用する前に常に権限ステータスを確認し、拒否を適切に処理してください。

開発中に権限をリセットするには?

デバイスの設定:設定 → アプリ → [アプリ名] → 権限。すべての権限をリセットするには、adbコマンドを使用します:adb shell pm reset-permissions

Activityなしで権限を要求できますか?

はい。FragmentやServiceで ActivityResultLauncher を使用して可能です。ただし、要求ダイアログには常にActivityのUIコンテキストが必要です。Serviceの場合は、要求Activityを開くIntentを含むNotificationを表示できます。

権限に maxSdkVersion が必要な理由は?

たとえば、WRITE_EXTERNAL_STORAGE は Android 10+(Scoped Storage)では不要です。android:maxSdkVersion="28" を指定することで、新しいバージョンでの権限宣言を除外し、互換性を向上させ、要求する権限リストを削減できます。

まとめ

  • AndroidManifest Permissions — Androidでシステムリソースにアクセスするための必須宣言
  • 4つの保護レベル — normal、dangerous、signature、special。それぞれ異なる付与メカニズム
  • Runtime Permissions — dangerous権限は実行時の要求が必要(Android 6+)
  • 権限グループ — グループ内の1つの権限への同意でグループ全体へのアクセスが許可
  • 説明 — 要求前に説明を表示することで同意率が20~30%向上
  • 最小化 — 必要な権限のみを要求し、maxSdkVersion を使用
  • APIを呼び出す前に常に権限ステータスを確認し、すべての拒否シナリオを処理

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください