Android 6.0からリクエストが必要なパーミッション一覧 (Dangerous パーミッション)
Android 6.0 (API レベル 23)からパーミッションの概念が変わり、ユーザーに許可を必要とするパーミッションとそうでないパーミッションの2つに分かれました。
- Normal パーミッションはユーザーがアプリをインストールすれば権限が得られる
- Dangerous パーミッションはインストールとは別にユーザーの許可がないとアプリが権限を得られない。また後から権限を取り消すことができる。
このため、ユーザーがアプリに権限を付与していない状態を考慮する必要があります。
パーミッションの概要は公式の実行時のパーミッションリクエストを参照するとより理解が深まると思います。
本記事では、次のことを説明します。
- Dangerous パーミッションにはどういうものがあるか
- ユーザーからDangerous パーミッションを許可してもらうために必要なプログラミング方法
スポンサーリンク
もくじ
Normal パーミッション と Dangerous パーミッション
システムパーミッションは、いくつかのカテゴリーで分けられますが、その中で重要なのがNormal パーミッションとDangerous パーミッションの2つです。
Normal パーミッションは、AndroidManifest.xmlで<uses-permission>を記載するだけで、アプリがパーミッションを得ることができます。Dangerous パーミッションAndroidManifest.xmlで<uses-permission>の記載は必要ですが、記載しただけではアプリがパーミッションを得ることができません。
後述するプログラムにより、必要なタイミングでパーミッションの確認・パーミッションの許可などの処理が必要になります。
パーミッションの詳細は、公式のシステムパーミッションを参照してください。
Dangerous パーミッション として扱われる条件
次の3つの条件を満たす場合は、Dangerous パーミッションとして扱われます。
条件 | 説明 |
Anroid 6.0(APIレベル23)以上 | すでにAndroid 9 までリリースされ、6.0 は古いバージョンになりつつあります。 |
アプリの targetSdkVersion 23 以上 | targetSdkVersionの要件は厳しくなるので、ほぼすべてのアプリがこれを満たすことになるでしょう。 |
Dangerous パーミッションに分類されるパーミッション | Dangerous パーミッション一覧は後述します。 |
ほぼすべてのアプリがDangerous パーミッションを意識した実装をしなければならないと考えて良いでしょう。
Dangerous パーミッション / パーミッション グループ の一覧
Dangerous パーミッションはパーミッション グループに所属していて、パーミッション グループ単位で権限が管理されています。
例えば、パーミッション グループ「CALENDAR」のパーミッション「READ_CALENDAR」をアプリがリクエストし、ユーザーが許可したとします。その場合、同一パーミッション グループにあるパーミッション「WRITE_CALENDER」も権限が付与されます。
パーミッション グループ (Manifest.permission_group) |
Dangerous パーミッション (Manifest.permission) |
CALENDAR | READ_CALENDAR |
WRITE_CALENDAR | |
CAMERA | CAMERA |
CONTACTS | READ_CONTACTS |
WRITE_CONTACTS | |
GET_ACCOUNTS | |
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 | |
PROCESS_OUTGOING_CALLS | |
SENSORS | BODY_SENSORS |
SMS | SEND_SMS |
RECEIVE_SMS | |
READ_SMS | |
RECEIVE_WAP_PUSH | |
RECEIVE_MMS | |
STORAGE | READ_EXTERNAL_STORAGE |
WRITE_EXTERNAL_STORAGE |
参照:公式のパーミッション グループ
API レベル23のNormal パーミッション一覧
API レベル 23 (Android 6.0)のNormal パーミッションにはどのようなものがあるかも列挙しておきます。
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
FLASHLIGHT
GET_PACKAGE_SIZE
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
SET_ALARM
INSTALL_SHORTCUT
UNINSTALL_SHORTCUT
Dangerous パーミッションの許可をユーザーから得るプログラム
アプリがDangerous パーミッションを必要とする場合、次のようなことが必要になります。
- AndroidManifest.xmlにDangerous パーミッションを記載
- アプリの実行時に、必要なタイミングでDangerous パーミッションの許可を確認し、許可されていない場合はユーザーに許可を求める画面を表示
- ユーザーの操作が完了したら、再度Dangerous パーミッションの許可を確認し、許可・非許可のケースでアプリを動作
なお、ユーザーが許可しないケースもありますのでその場合のアプリの動作も検討して実現してください。許可しない場合の対応としては次のようなパターンを考えると良いでしょう。
- 許可されなかった内容が一部の機能でしか使わない場合は、その機能のみを制限し、他の機能を使える状態でアプリを利用してもらいます。
- その機能を使えなくても、アプリとして成り立つようなケースです。ほとんどのユーザーにとって必要に応じて使用すれば良いので、このような振る舞いが良いのではないでしょうか。
- 許可されなかった内容がアプリの重要な機能の一部である場合は、アプリを終了します。
- アプリを使用する根幹になる機能が使えないケースです。パーミッションを制限された状態でアプリを実現するには実装コストが高すぎたり、ユーザー体験が悪すぎるような場合には、アプリを使用できない方が良いでしょう。また、必要であれば、このパーミッションを許可してくれないと使えないという情報を別途表示すると良いかもしれません。
AndroidManifest.xmlにDangerous パーミッションを記載
AndroidManifest.xmlでパーミッションを宣言するには次のように記載します。
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="sample.pkg"> <!-- Normal パーミッション --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- Dangerous パーミッション --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> ・・・ </manifest> |
Normal パーミッションもDangerous パーミッションも宣言方法は同じです。
アプリ実行時にDangerous パーミッションを確認
Dangerous パーミッションの確認は次のようになります。
1 2 3 4 5 6 |
int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE); if (permissionCheck == PackageManager.PERMISSION_GRANTED) { // すでにユーザーがパーミッションを許可 } else { // ユーザーはパーミッションを許可していない } |
常にユーザーがDangerous パーミッションを許可しない場合は、ユーザーが煩わしく感じるケースがあるので「すでにパーミッションのリクエストを行い、ユーザーが拒否したことを確認」しましょう。
すでにDangerous パーミッションのリクエストをユーザーが拒否したことを確認
次のメソッドを実行してください。
1 2 3 4 5 |
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.READ_PHONE_STATE)) { // すでにパーミッションのリクエストを行い、ユーザーが拒否した } else { // そうではないケース } |
このメソッドを使用する場合は、公式のアプリにパーミッションが必要な理由の説明をよく読むと良いでしょう。
Dangerous パーミッションをリクエストする流れ
リクエストは次のような流れになります。
- Dangerous パーミッションをリクエスト(このプログラムを実装する)
- ユーザーにパーミッションの許可または拒否を求めるダイアログを表示
- ユーザーが操作を完了
- Dangerous パーミッションのリクエスト結果を処理(このプログラムを実装する)
Dangerous パーミッションをリクエスト
パーミッションをユーザーにリクエストする場合、次のようにActivity(thisActivity)のインスタンスの参照が必要です。
1 2 3 4 |
ActivityCompat.requestPermissions( thisActivity, new String[] { Manifest.permission.READ_PHONE_STATE }, PERMISSIONS_REQUEST_READ_PHONE_STATE); |
ユーザーにDangerous パーミッションのリクエストダイアログ
ActivityCompat.requestPersissions()を実行すると、ユーザーにパーミッションの許可または拒否を求めるダイアログを表示します。

Dangerous パーミッションのリクエスト
ユーザーが許可しない・許可のどちらかを選択するとダイアログが閉じて、プログラムに処理が戻ります。
Dangerous パーミッションのリクエスト結果の処理
リクエスト結果は、リクエストを行ったActivityインスタンスのActivityCompat.OnRequestPermissionsResultCallback.onRequestPermissionsResult()に渡されます。
この関数の中で、リクエストが許可されたかを確認して処理を実行してください。
1 2 3 4 5 6 7 8 9 10 |
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { if (requestCode == PERMISSIONS_REQUEST_READ_PHONE_STATE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Dangerous パーミッションのリクエストが許可!! } else { // Dangerous パーミッションのリクエストが拒否。 } } } |
これで一通りDangerous パーミッションが処理できるようになりました。
今後も少しずつ個人情報やセキュリティ等でパーミッションは厳しくなることが予想されますので、パーミッションの取り扱いには注意が必要です。
この記事以外にもパーミッションに関連した内容を知りたい場合は公式パーミッションの概要を参照してください。