Android 6.0で導入されたランタイムパーミッションですが、定型文が多い上に結果の受け取りがonRequestPermissionsResult
のオーバーライドによる非同期処理となるため非常に使いづらく、ややこしくなりがちでした。昔記事を書いていたのがこちら。
https://qiita.com/niusounds/items/f8852534bd3135d89dcc
そんなランタイムパーミッションのAPIが、androidx.activity 1.2.0
でより使いやすくシンプルなAPIになりました!
たとえばstartRecordButton
というボタンを押すと端末のマイクから音声入力を録音する処理startRecording()
が実行されるアプリを作っているとしたら、以下のような感じのコードになります。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 最初にregisterForActivityResultしておく(onStartまでにやっておく必要があるらしい)
val requestPermission = registerForActivityResult(ActivityResultContracts.RequestPermission()) { result ->
// パーミッションリクエストの結果を処理する
// パーミッションが許可されたらresult=true
if (result) {
startRecording()
}
}
startRecordButton.setOnClickListener {
checkPermission(requestPermission)
}
}
// 引数でrequestPermissionを渡してみたが、フィールドに保持するでも良いと思う
private fun checkPermission(requestPermission: ActivityResultLauncher<String>) {
// パーミッション許可済みかどうかの判定。これは今まで通り変わらず。
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
startRecording()
} else {
// ランタイムパーミッションのダイアログを出す
requestPermission.launch(Manifest.permission.RECORD_AUDIO)
}
}
}
※丁寧にやるならランタイムパーミッションのダイアログを出す前にActivityCompat.shouldShowRequestPermissionRationale
を問い合わせて以前に拒否したことがあるかどうかを調べた方が良いと思います。
requestCode
を自分で定義したりonRequestPermissionsResult
をオーバーライドして定型文的なコードを書いたりしなくて良くなったので、だいぶスッキリしました。
なんでもっと早く導入されなかったんですかね〜!