Androidの実行時パーミッションチェックを実装する

  • 37
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

カメラや外部ストレージを利用する場合、Android 6.0から実行時にパーミッションチェックを行う必要がある。
support v4ライブラリに含まれるContextCompatActivityCompatを使うことで、旧バージョンとの互換性に関するコードは書かなくてよくなるが、それでもいろいろとめんどくさい。

カメラパーミッションをチェックする例
int permissionCheck = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);

if (permissionCheck != PackageManager.PERMISSION_GRANTED) {

    // Android 6.0 のみ、該当パーミッションが許可されていない場合

    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
        // パーミッションが必要であることを明示するアプリケーション独自のUIを表示
    }

} else {
    // 許可済みの場合、もしくはAndroid 6.0以前
    // パーミッションが必要な処理
}

パーミッションダイアログはシステムが管理しておりテキストなどを調整することはできないので、なぜそのパーミッションが必要なのか等を説明するUIを用意してパーミッションが必要であることを明示するアプリケーション独自のUIを表示のところで表示することが推奨されている。この画面にパーミッションが必要である理由を説明する文や絵と、パーミッションダイアログを表示するためのボタン等を表示する。

パーミッションダイアログを表示するにはActivityCompat.requestPermissionsを呼ぶ。引数にActivityのインスタンスと利用したいパーミッションを文字列配列で渡す。

カメラパーミッションをリクエストする例
static final int REQUEST_CODE = 1;
ActivityCompat.requestPermissions(activity, new String[]{
        Manifest.permission.CAMERA
}, REQUEST_CODE);

すると、こうなる
device-2015-11-06-162256.png

パーミッションダイアログの結果はActivityにActivityCompat.OnRequestPermissionsResultCallbackをimplementしてonRequestPermissionResultをオーバーライドすることで取得する。
support v4のFragmentActivityはこのインターフェースを実装しているので、すでにこれを継承してアプリを作っている場合は単にonRequestPermissionsResultをオーバーライドするだけで良い。

パーミッションダイアログの結果を受け取る例
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // パーミッションが必要な処理
            } else {
                // パーミッションが得られなかった時
                // 処理を中断する・エラーメッセージを出す・アプリケーションを終了する等
            }
        }
    }
}

複数のパーミッションを一度にリクエストする場合は、それぞれについて許可・拒否が行われる可能性がある。その場合、permissions一つ一つをチェックして適切な処理を行う必要がある。

ちなみにどうしてもこのパーミッションを実装できない場合は、とりあえずtargetSdkVersionを23未満にしておくことでAndroid 6.0でも従来のパーミッション方式で動作するので、その場しのぎにはなる。