パーミッションチェックをシンプルに実装する為のベストプラクティス


はじめに

パーミッション関連の実装、実装頻度が非常に高い上、少々大変だったりしますよね。
最近ではパーミッション確認時の選択肢が増えたり、onRequestPermissionsResultがdeprecatedになったりと、この辺りの文化も変わっている印象です。
そんな中で、とてもシンプルにパーミッションチェックを実装できる、ベストプラクティス的な実装をご紹介したいと思います。

実装方法

まず、PermissionsDispatcherKtxを導入します。

dependencies {
  implementation "com.github.permissions-dispatcher:ktx:${latest.version}"
}

次に、以下を変数として定義します。

private val checkPermissions by lazy {
   constructPermissionsRequest(
   Manifest.permission.CAMERA,
   onPermissionDenied = viewModel::onPermissionDenied,
   onNeverAskAgain = viewModel::onNeverAskAgain,
   requiresPermission = viewModel::requiresPermission)
}

あとは、パーミッションを表示したいタイミングで以下を呼ぶだけです。

checkPermissions.launch()

実装は以上になります。

ここからはconstructPermissionsRequestを簡単に解説します。
上記関数はライブラリ内で以下のように定義されています。

fun Fragment.constructPermissionsRequest(
    vararg permissions: String,
    onShowRationale: ShowRationaleFun? = null,
    onPermissionDenied: Fun? = null,
    onNeverAskAgain: Fun? = null,
    requiresPermission: Fun
): PermissionsRequester = PermissionsRequesterImpl(
    permissions = permissions,
    activity = requireActivity(),
    onShowRationale = onShowRationale,
    onPermissionDenied = onPermissionDenied,
    onNeverAskAgain = onNeverAskAgain,
    requiresPermission = requiresPermission,
    permissionRequestType = PermissionRequestType.Normal
)

まず、第1引数のpermissionsですが、ご覧の通り複数指定が可能になっています。
ここに取得したいパーミッションを指定する必要があります。

次に第2引数のonShowRationaleですが、『今後表示しない』が設定されていない状態で権限のリクエストが発生した直後に呼び出されます。
こちらには引数があり、続行か中断を指示できるPermissionRequestを指定することができます。
これを用いると、独自のダイアログ上で続行か中断の指示を出すようなことが可能になります。

次に第3引数のonPermissionDeniedですが、『今後表示しない』が設定されていない状態で権限付与が拒否された場合に呼び出されます。

次に第4引数のonNeverAskAgainですが、『今後表示しない』が設定された状態で権限付与が拒否された場合に呼び出されます。

最後に第5引数であるrequiresPermissionですが、こちらはパーミッションが許可された場合に呼び出されます。

以上になります。
第2引数から第4引数まで任意の設定になるので、必要に応じて設定してあげたら良いかと思います。
また、Activityにも対応しておりますので、Fragment、Activityどちらでも同じように実装が可能です。

さいごに

ライブラリを導入するというハードルはありますが、これまでにないくらいシンプルに実装する事ができるようになりました。
また、checkPermissionsの定義を見ていただけるとわかるかと思いますが、viewModel内の関数を直接呼ぶ事もでき、最近のアーキテクチャーとも親和性が高いと思います。
拒否された際に何を出すべきかというのは大いに検討の余地があると思いますが、こちらの検討に時間をかける為にも、パーミッションチェックの実装は時間をかけずに終えたいところですね。