Android M以降のパーミッションチェック実装|Android開発

API Level23からAndroidの権限チェックの方法が変更になりました。
これまでは、インストール時に権限を確認していましたが、これからはその機能を使うタイミングで権限の確認を行うようになります。
その実装サンプルです。

はじめに

app/build.gradleAndroidManifest.xmltargetSdkVersionを23以上にしてください。23未満だと実装してもチェック処理が走りません。
AndroidManifest.xmlへ権限チェックを行う対象をuses-permissionで追加しておきます。

カメラとSDカードへの書き込み権限を与えたい場合

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

処理の流れ

起動時にまとめて権限チェックする方法

下記は機能使用時ではなく、起動時に専用のActivityを用意して、まとめて確認する方法です。

権限チェックActivity(PermissionsCheckActivity)と実際の初期画面(MainActivity)を用意します。
起動Activityとして、PermissionsCheckActivityを指定します。
アプリケーションの動作は、

  1. PermissionsCheckActivityを起動。
  2. 権限がこれまでに全てALLOWになっていなければ、確認処理を実施します。
    既に権限が全てALLOWの場合は、MainActivityを起動します。
  3. ALLOWになっていない権限の確認を行います。(requestPermissions)
    permission-camera permission-wr-st
  4. チェック結果を受け取ります。(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, String permissions[], 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, String permissions[], 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() {
    // 権限がある場合に実行したい処理
}
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

関連コンテンツ

スポンサードリンク

Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です