Appがどのような権限を持っているかどうかを確認する方法を紹介します。
- 自分のアプリがどのような権限を持っていることを確認
- 他のアプリがどのようなパーミッションを持っていることを確認
Sample App
Sample Appを作成し、このアプリの権限を確認するためのコードを実装することです。
次のようにSample appのManifestに二つのパーミッションを要求しました。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
そしてアプリは INTERNET
パーミッションは持っており、READ_EXTERNAL_STORAGE
パーミッションは持っていない状態です。
Context.checkSelfPermission()で許可を確認
checkSelfPermission()
は引数としてpermisison名前を受け取ります。
public abstract int checkSelfPermission(@NonNull String permission);
ContextのAppが引数として渡されたパーミッションを持っている場合、 PackageManager.PERMISSION_GRANTED
を返します。
そうでなければ PackageManager.PERMISSION_DENIED
を返します。つまり、このAPIは、自分のアプリのパーミッションの状態のみを確認することができます。
PackageManager.PERMISSION_GRANTED = 0;
PackageManager.PERMISSION_DENIED = -1;
Activityから次のように使用することができます。
if (checkSelfPermission(Manifest.permission.INTERNET)
== PackageManager.PERMISSION_GRANTED) {
Log.d("Test", "Has INTERNET permission")
}
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED) {
Log.d("Test", "Doesn't have READ_EXTERNAL_STORAGE permission")
}
Output:
11-14 22:27:15.014 5483 5483 D Test : Has INTERNET permission
11-14 22:27:15.014 5483 5483 D Test : Doesn't have READ_EXTERNAL_STORAGE permission
ActivityCompat API
Compatibility APIを使用したい場合は、 ActivityCompat.checkSelfPermission(Context, Permission)
を使用してください。
戻り値は、上記と同じです。
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.INTERNET)
== PackageManager.PERMISSION_GRANTED) {
Log.d("Test", "Has INTERNET permission")
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED) {
Log.d("Test", "Doesn't have READ_EXTERNAL_STORAGE")
}
PackageManager.checkPermisison()でパーミッションチェック
checkPermisison()
は、次のようにパーミッションの名前とパッケージ名を引数として受け取ります。
public abstract int checkPermission(@NonNull String permName, NonNull String packageName);
引数として受け取ったパッケージに引数として受け取ったパーミッションを持っていることを確認し、その結果を返します。 つまり、このAPIは、他のパッケージのパーミッションの状態を確認することができます。
次のようにAppで使用することができます。
if (packageManager.checkPermission(Manifest.permission.INTERNET, packageName)
== PackageManager.PERMISSION_GRANTED) {
Log.d("Test", "Has INTERNET permission")
}
if (packageManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE, packageName)
== PackageManager.PERMISSION_DENIED) {
Log.d("Test", "Doesn't have READ_EXTERNAL_STORAGE permission")
}
Output:
11-14 22:30:54.999 6407 6407 D Test : Has INTERNET permission
11-14 22:30:55.000 6407 6407 D Test : Doesn't have READ_EXTERNAL_STORAGE permission
他のパッケージのパーミッションを確認
次のように他のアプリが特定のパーミッションを持っているかどうかを確認することができます。次の例では、YoutubeがNFCパーミッションを持っていることを確認する例を示します。
if (packageManager.checkPermission(Manifest.permission.NFC,
"com.google.android.youtube") == PackageManager.PERMISSION_DENIED) {
Log.d("Test", "Youtube has NFC permission")
}
checkSelfPermission()とcheckPermisison()の違い
アンドロイドの権限は大幅にPackageManagerのPermissionとAppOpsの権限に分けることができます。 PackageManagerのPermissionはManifestに宣言するパーミッションで、ユーザーに権限を要求し、受けるパーミッションを指します。 AppOpsはAppliction Operationの意味で、Appの動作を制限または許可するなどの権限を設定することを意味します。
Context.checkSelfPermission()
はAppOpsの権限とPackageManagerのPermissionをすべて確認して戻します。
つまり、PackageManagerのPermissionを持っていてもAppOpsから制限された場合 PERMISSION_DENIED
が返されることがあります。
一方、 PackageManager.checkPermisison()
はAppがPackageManagerのPermissionを持っているかどうかだけを確認します。
AppOpsから許可された制限されたがわかりません。
adb shellでパーミッションの状態を確認する方法
Settingsアプリでマイアプリの情報でパーミッションの状態を確認することができます。
しかし、 adb shell
を使用すると、開発中より簡単にパーミッションの状態を確認することができます。
次のコマンドを入力すると、端末にパッケージ情報が出力されます。
$ adb shell dumpsys package [package name]
たとえば、次のようにyoutubeのパッケージ情報を出力することができます。そして、その情報からパーミッションの状態を確認することができます。
$ adb shell dumpsys package com.google.android.youtube
Packages:
Package [com.google.android.youtube] (79c836a):
userId=10121
pkg=Package{baa705b com.google.android.youtube}
declared permissions:
com.google.android.youtube.permission.C2D_MESSAGE: prot=signature, INSTALLED
requested permissions:
android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.WRITE_EXTERNAL_STORAGE: restricted=true
....
install permissions:
com.google.android.c2dm.permission.RECEIVE: granted=true
android.permission.USE_CREDENTIALS: granted=true
com.google.android.providers.gsf.permission.READ_GSERVICES: granted=true
....
User 0: ceDataInode=122890 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=1 instant=false virtual=false
gids=[3003]
runtime permissions:
android.permission.ACCESS_FINE_LOCATION: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
android.permission.READ_EXTERNAL_STORAGE: granted=false, flags=[ REVOKE_WHEN_REQUESTED|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|RESTRICTION_UPGRADE_EXEMPT]
android.permission.ACCESS_COARSE_LOCATION: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
....
それぞれの項目の意味は次のとおりです。
- declared permissions:アプリから直接定義パーミッションを意味します
- requested permissions:アプリで要求しているパーミッションを意味します。 (Manifestからuses-permissionで宣言したパーミッション
- install permissions:アプリが持っているパーミッションです。 install permissionはインストール時に付与されるパーミッションの種類を意味します
- runtime permissions:アプリが持っているパーミッションです。 rumtime permissionは、インストールされる際に付与されず、アプリがユーザーに権限を要請して与えられるパーミッションを意味します
次のように grep
を利用して、granted状態を簡単に確認することができます。
$ adb shell dumpsys package com.google.android.youtube | grep READ_CONTACTS
android.permission.READ_CONTACTS
android.permission.READ_CONTACTS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
Related Posts
- Android - FusedLocationProviderClientに位置情報を取得する
- Android - GPS、Network位置情報を取得する(LocationManager)
- Android - adbコマンドでActivity実行
- アンドロイド - MediaStoreにメディアファイルを保存する方法
- Android - Runtime permissionリクエスト方法と例(kotlin)
- Android11 - Storage(ストレージ)の変更まとめ
- Jetpack Compose - RowとColumn
- Android 13 - 細かいメディアファイルの権限
- Android 13でNotification権限をリクエスト、通知を表示する
- エラー解決:android gradle plugin requires java 11 to run. you are currently using java 1.8.
- Query method parameters should either be a type that can be converted into a database column or a List
- Android - TabLayoutの実装方法(+ ViewPager2)
- Android - adbコマンドで特定のパッケージのプロセスの終了
- Android - adb push、pullでファイルのコピー、ダウンロード
- Android - adbコマンドでsettings value確認、変更、
- Android 12 - IntentFilterのexported明示的な宣言
- Android - adb logcatコマンドでログ出力
- Android - ACTION_BOOT_COMPLETEDイベント受信
- Android - Foreground Service実行
- Android - ファイル入出力の例(Read、Write、内部、外部ストレージ)
- Android - アプリの権限を確認(Permission check)
- Android - adbで実行中のプロセス、スレッドリスト及びメモリ情報の確認
- Android - Broadcast Receiver登録およびイベントの受信方法
- Android - Cleartext HTTP ... not permitted例外解決方法
- Androidのビルドエラー - Calls to Java default methods are prohibited in JVM target 1.6
- アンドロイド - Assetsでファイルを読み取る方法
- アンドロイドのさまざまなNotification種類と実装方法
- アンドロイド - INSTALL_FAILED_TEST_ONLYエラー解決方法
- Android EspressoのCustom Matcher実装方法
- Android Espressoを使用してUIをテストする方法(3)
- アンドロイド - CTS hostsideをgradleで構築する方法
- Androidのアプリのデータフォルダーのパスと内部/外部ストレージ説明
- アンドロイド - 最初のApp作成
- Androidをインストールする方法(Windows)