LoginSignup
1
0

More than 3 years have passed since last update.

PermissionsDispatcherをはずして、PermissionsDispatcher風に実装しよう。

Last updated at Posted at 2020-11-10

はじめに

  • Androidのパーミッション処理を便利に実装してくれるPermissionsDispatcherってなかなか便利ですよね。
  • 使っている方もいるかと思いますが、PermissionsDispatcherを外して、PermissionsDispatcher風に実装する方法を書いていこうと思います。

  • ここではPermissionsDispatcherの使い方についてはふれませんので、気になる方はQiitaの他の記事を読んでみると良いかと:neutral_face:

PermissionsDispatcher風とは?

  • PermissionsDispatcherでは、メソッドにAnnotationを付与し、kapt(kotlin-annotation-processing tools)を利用しコード生成を行います。

  • PermissionsDispatcherには以下のAnnotationが用意されています。

スクリーンショット 2020-11-10 21.31.14.png
annotations

実装イメージ

  • Permissionの判定処理は、androidx.activity:activity-ktxandroidx.fragment:fragment-ktxを利用します。
  • Permission判定は以下の処理をハンドリング出来るようにします。
処理名 タイミング
onGranted ユーザーが処理を許可した場合に呼び出されます。
onShowRationale ユーザーが処理を一度拒否した後に、リクエストされた際に呼び出されます。
onDenied ユーザーが処理を拒否した場合際に呼び出されます。

OSS

androidx.activity:activity-ktxを利用します。

build.gradle
dependencies {
    implementation 'androidx.activity:activity-ktx:1.2.0-beta01'
}

Permission判定処理

  • 判定処理はActivityResultContracts.RequestPermission()を元に、判定処理を実装します。
  • ActivityResultContracts.RequestPermission()はActivity間パーミッション判定を実装してくれています。

Permissionの状態管理

  • パーミッション判定と、処理のハンドリングを以下のクラスで制御します。
PermissionChecker.kt

class PermissionChecker(
        private val activity: ComponentActivity,
        private val permission: String,
        private val onDenied: () -> Unit = {},
        private val onShowRationale: (onRequest: () -> Unit) -> Unit = {}
) {
    private var onGranted: () -> Unit = {}

    private val launcher =
            activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
                when {
                    isGranted -> onGranted()
                    else -> onDenied()
                }
            }

    fun runWithPermission(onGranted: () -> Unit) {
        this.onGranted = onGranted
        when {
            activity.shouldShowRequestPermissionRationale(permission) -> onShowRationale {
                launcher.launch(permission)
            }
            else -> {
                launcher.launch(permission)
            }
        }
    }
}
  • activity.registerForActivityResult(ActivityResultContracts.RequestPermission())は、パーミッションの判定処理を実施しています。
    • Boolean でパーミッションの状態を返却してくれます。
  • shouldShowRequestPermissionRationale()ユーザーがパーミッション判定に回答したかを返却します。

利用ケース

SampleActivity.kt

class SampleActivity : AppCompatActivity(){
    ・・・省略

    // ファイルストレージのPermission判定
    private val externalStrageAccessPermissionChecker = PermissionChecker(this, WRITE_EXTERNAL_STORAGE,
            onDenied = {
                // 拒否した際の、通知処理
                Toast.makeText(this, "アクセス拒否しているから、処理できませんでした。", Toast.LENGTH_LONG).show()
            },
            onShowRationale = { onRequest ->
                // 一度拒否した後の、処理実施時の処理の説明を実施
                AlertDialog.Builder(this)
                        .setPositiveButton("次へ")
                        { _, _ -> onRequest() }
                        .setCancelable(false)
                        .setMessage("ファイルアクセス許可が必要なんです。")
                        .show()
            }
    )
    // ファイルダウンロード処理
    fun downloadFile(url: String, name: String) {
        externalStrageAccessPermissionChecker.runWithPermission(
                onGranted = {
                    // ダウンロード処理を実施
                }
        )
    }
}

  • PermissionCheckerは、registerForActivityResult()の処理を実装しています。この処理はonCreate()前に呼び出す必要があります。
  • runWithPermission()onGranted()はユーザーが許可した際に呼び出されます。
  • onShowRationale()は一度処理を拒否した後に呼び出されます。onRequest()を呼び出すことで、中断した処理を実施します。
  • onDenied()は拒否された際に通知されます。

まとめ

  • registerForActivityResult(ActivityResultContracts.RequestPermission())を利用する事で、いままで実装が大変だった、処理が大幅に楽になります。
  • PermissionsDispatcherも便利ですが、Android 11 対応時には、利用箇所でワーニングが多く表示されるケースがあります。
  • ワーニングをなくす為には処理の置き換えが必要かな:expressionless:

追記(2020/11/11)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0