カメラや外部ストレージを利用する場合、Android 6.0から実行時にパーミッションチェックを行う必要がある。
support v4ライブラリに含まれるContextCompat
とActivityCompat
を使うことで、旧バージョンとの互換性に関するコードは書かなくてよくなるが、それでもいろいろとめんどくさい。
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);
パーミッションダイアログの結果は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でも従来のパーミッション方式で動作するので、その場しのぎにはなる。