背景
プロジェクトにPermissionsDispatcherが導入されていたので色々触ってみる
PermissionsDispatcherとは
Android 6.0(M) 以降から導入されたruntime permissionの実装を楽にしてくれるライブラリ。
https://github.com/permissions-dispatcher/PermissionsDispatcher
runtime permissionについて
https://developer.android.com/training/permissions/requesting
導入方法
build.gradleに以下を記載。
apply plugin: 'kotlin-kapt'
dependencies {
  implementation "org.permissionsdispatcher:permissionsdispatcher:${latest.version}"
  kapt "org.permissionsdispatcher:permissionsdispatcher-processor:${latest.version}"
}
自動生成なのでkotlin-kaptプラグインを忘れないように。
使い方
順番に使い方を記載してく。
1. Activity / FragmentにRuntimePermissionsアノテーションをつける
以下のような形。
@RuntimePermissions
class MainActivity : AppCompatActivity() {
@RuntimePermissions
class MainFragment : DaggerFragment() {
2. 欲しいパーミッションの取得に成功している or 失敗した後に実行される関数を実装
    fun readDeviceData() {
       getIMEI()
    }
3. 2.で作成した関数にNeedPermissionアノテーションをつける
NeedPermissionの中には欲しい権限情報を記載する
    @NeedsPermission(Manifest.permission.READ_PHONE_STATE)
    fun readDeviceData() {
       getIMEI()
    }
4. ビルドする
自動的にコードが生成される
5. 関数名 + WithPermissionCheck()という名で拡張関数ができているので呼ぶ。
   override fun onCreate(savedInstanceState: Bundle?) {
       readDeviceDataWithPermissionCheck()
   }
6. onRequestPermissionsResultをoverrideし、生成された拡張関数onRequestPermissionsResultを呼ぶ
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        onRequestPermissionsResult(requestCode, grantResults)
    }
以上。
自動生成されたコード
こんな感じ。ほぼほぼルーチン作業だったパーミッションコードが自動生成されている。
すでにパーミッションが設定されている場合でも呼び出してくれる形なので便利。
private const val REQUEST_READDEVICEDATA: Int = 2
private val PERMISSION_READDEVICEDATA: Array<String> =
    arrayOf("android.permission.READ_PHONE_STATE")
fun MainActivity.readDeviceDataWithPermissionCheck() {
  if (PermissionUtils.hasSelfPermissions(this, *PERMISSION_READDEVICEDATA)) {
    readDeviceData()
  } else {
    ActivityCompat.requestPermissions(this, PERMISSION_READDEVICEDATA,
        REQUEST_READDEVICEDATA)
  }
}
fun MainActivity.onRequestPermissionsResult(requestCode: Int, grantResults: IntArray) {
  when (requestCode) {
    REQUEST_STARTLOCATIONSAMPLING ->
     {
      if (PermissionUtils.verifyPermissions(*grantResults)) {
        readDeviceData()
      }
    }
  }
}
二つ同時にパーミッションを取得したい場合
連続してパーミッションを取得したい場合は@NeedPermissionに二つ設定する。
@NeedsPermission(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE)
まとめ
他にもユーザーがアクセス許可を付与しない場合に呼び出されるメソッドやなぜ許可が必要なのかを表示するためのメソッドなども指定できるので、ちょっとだけ楽になる。