PermissionsDispatcherを使ってRuntime Permissionをリクエストする

RxPermissionsを使ってRuntime Permissionを実装していたんですが、Runtime PermissionのためにRxJavaを導入するのはやり過ぎな気がしたり、disposableを管理するのが面倒くさかったり、もっときめ細やかにパーミッションを管理したい気持ちがあったりしたので、PermissionsDispatcherを使うことにしました。

とりあえずAndroidManifest.xmlにパーミッションを追加します。

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

app/build.gradleにPermissionDispatcherとkaptを追加します。

apply plugin: 'kotlin-kapt'

dependencies {
    // PermissionDispatcher
    implementation "org.permissionsdispatcher:permissionsdispatcher:4.5.0"
    kapt "org.permissionsdispatcher:permissionsdispatcher-processor:4.5.0"
}

Fragmentに @RuntimePermissions というアノテーションを付けます。PermissionsDispatcherによって自動生成されるメソッドがあるので、以下、適宜ビルドしながら進めます。

@RuntimePermissions
class StartFragment : Fragment() {
   // do something here
}

READ_EXTERNAL_STORAGE のパーミッションを得て、ギャラリーを表示するみたいな実装を想定して、パーミッション周りの処理を実装していきます。

/** Permission Dispatcher */
@NeedsPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
fun showGallery() {
    findNavController().navigate(R.id.action_start_to_gallery)
}

@OnShowRationale(Manifest.permission.READ_EXTERNAL_STORAGE)
fun onShowRationaleForReadExternalStorage(request: PermissionRequest) {
    showRationaleDialog(
        requireContext(),
        request,
        R.string.start_request_permission_for_read_external_storage
    )
}

@OnPermissionDenied(Manifest.permission.READ_EXTERNAL_STORAGE)
fun onReadExternalStorageDenied() {
    Toast.makeText(requireContext(), "Permission denied!", Toast.LENGTH_LONG).show()
}

@OnNeverAskAgain(Manifest.permission.READ_EXTERNAL_STORAGE)
fun onReadExternalStorageNeverAskAgain() {
    Toast.makeText(requireContext(), "Never ask again!", Toast.LENGTH_LONG).show()
}

onRequestPermissionsResult() をoverrideして、この中でPermissionsDispatcherによって自動生成される onRequestPermissionsResult() を呼び出せば、パーミッションの許可周りを適切にハンドリングしてくれます。

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    onRequestPermissionsResult(requestCode, grantResults)
}

showRationaleDialog() は拡張関数で定義しました。

fun Fragment.showRationaleDialog(
    context: Context,
    request: PermissionRequest,
    @StringRes messageResId: Int
) {
    AlertDialog.Builder(context)
        .setPositiveButton(R.string.ok) { _, _ -> request.proceed() }
        .setNegativeButton(R.string.cancel) { _, _ -> request.cancel() }
        .setMessage(messageResId)
        .show()
}

最後に、PermissionsDispatcherによって自動生成された showGalleryWithPermissionCheck() を呼び出せば、パーミッションのチェックが走ります。

showGalleryWithPermissionCheck()

筆者

茨城県つくば市在住のソフトウェアエンジニアです。得意領域はAndroidとFlutterです。「Jetpack ComposeによるAndroid MVVMアーキテクチャ入門」の著者です。

👉もっと詳しく