Android M以降のパーミッションチェック実装|Android開発
API Level23からAndroidの権限チェックの方法が変更になりました。
これまでは、インストール時に権限を確認していましたが、これからはその機能を使うタイミングで権限の確認を行うようになります。
その実装サンプルです。
はじめに
app/build.gradleとAndroidManifest.xmlでtargetSdkVersionを23以上にしてください。23未満だと実装してもチェック処理が走りません。
AndroidManifest.xmlへ権限チェックを行う対象をuses-permission
で追加しておきます。
例:カメラとSDカードへの書き込み権限を与えたい場合
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxxxxxx">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
処理の流れ
起動時にまとめて権限チェックする方法
下記は機能使用時ではなく、起動時に専用のActivityを用意して、まとめて確認する方法です。
権限チェックActivity(PermissionsCheckActivity
)と実際の初期画面(MainActivity
)を用意します。
起動Activityとして、PermissionsCheckActivity
を指定します。
アプリケーションの動作は、
PermissionsCheckActivity
を起動
- 権限がこれまでに全て
ALLOW
になっていなければ、確認処理を実施します
既に権限が全てALLOW
の場合は、MainActivity
を起動します ALLOW
になっていない権限の確認を行います。(requestPermissions
)
- チェック結果を受け取ります(
onRequestPermissionsResult
)
- チェック結果が全て
ALLOW
ならMainActivity
を起動します - チェック結果に
DENY
があればPermissionsCheckActivity
を終了し、アプリケーションも終了します
- チェック結果が全て
サンプルコード
レイアウトファイル
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/check_permissions"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"/>
権限チェックActivity
今回はカメラの使用(Manifest.permission.CAMERA
)とストレージへの書き込み(Manifest.permission.WRITE_EXTERNAL_STORAGE
)をチェックしています。
public class PermissionsCheckActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.check_permissions);
}
@Override
protected void onResume() {
super.onResume();
checkPermissions();
}
@SuppressLint("NewApi")
private void checkPermissions() {
ArrayList<String> requestPermissions = new ArrayList<>();
if (23 <= Build.VERSION.SDK_INT) {
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions.add(Manifest.permission.CAMERA);
}
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}
if (requestPermissions.isEmpty()) {
handlePermissionsSuccess();
} else {
buildPermissionsRequest(requestPermissions.toArray(new String[0]));
}
}
@SuppressLint("NewApi")
private void buildPermissionsRequest(String[] permissionsToRequest) {
requestPermissions(permissionsToRequest, PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean allSuccess = true;
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
Log.e("PTest", String.format(Locale.US, "%s is permission denied.", permissions[i]));
allSuccess = false;
}
}
if (allSuccess) {
handlePermissionsSuccess();
} else {
finish();
}
}
private void handlePermissionsSuccess() {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
実際は権限チェック表示のところで自身の文言を表示し、何に使うのかユーザに示すのが推奨されていますが、ここでは行っていません。
機能使用時に権限チェックする方法
権限チェックが必要なタイミングで以下のメソッドをコールします。パラメータには権限チェックしたい権限を指定します。
checkPermissions(new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
});
checkPermissions()
以降の処理です。
private static final int PERMISSION_REQUEST_CODE = 100;
@SuppressLint("NewApi")
private void checkPermissions(final String[] permissions) {
ArrayList<String> requestPermissions = new ArrayList<>();
if (Build.VERSION_CODES.M <= Build.VERSION.SDK_INT) {
for (String permission : permissions) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
requestPermissions.add(permission);
}
}
}
if (requestPermissions.isEmpty()) {
handlePermissionsSuccess();
} else {
buildPermissionsRequest(requestPermissions.toArray(new String[0]));
}
}
@SuppressLint("NewApi")
private void buildPermissionsRequest(String[] permissionsToRequest) {
requestPermissions(permissionsToRequest, PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean allSuccess = true;
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
allSuccess = false;
}
}
if (allSuccess) {
handlePermissionsSuccess();
}
}
private void handlePermissionsSuccess() {
// 権限がある場合に実行したい処理
}