以前記載した地図アプリケーションの作成において、取得するパーミッションは''ACCESS_FINE_LOCATION"の一つだけでした。
地図ダウンロードで別のパーミッションが複数必要になった場合に、パーミッションをどう取得するか疑問に思ったところもあったので改めてパーミッションの取得コードを検討します。
2つ以上のパーミッションの取得
一つのパーミッションを取得する場合と同様に、複数のパーミッションをループで取得すれば問題ないはずです。
パーミッションのチェック
private fun permissionCheck() { val deniedList = mutableListOf<String>() for(permission in permissions) { if(ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { deniedList.add(permission) } } if(deniedList.size > 0) { // 不許可有 ActivityCompat.requestPermissions(this, deniedList.toTypedArray(), PERMISSION_REQUEST_CODE) return } mainFunction() }
"never ask again"チェックボックスの対応
確認ダイアログで「今後は確認しない」のチェックボックがチェックされ「許可しない」を選択された場合、アプリで対応する術はないようなのでメッセージを出した後設定画面に遷移させます。
設定画面を呼び出すための関数です。
private fun openSetting() { val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) val uri = Uri.fromParts("package", packageName, null) intent.data = uri startActivityForResult(intent, PERMISSION_REQUEST_CODE) }
設定画面からの戻り処理
設定画面に遷移後、戻るボタンで戻った時になにも変更されていない場合に備えて、再度パーミションをチェックするようオーバーライドします。
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when(requestCode) { PERMISSION_REQUEST_CODE -> permissionCheck() else -> super.onActivityResult(requestCode, resultCode, data) } }
パーミッション確認ダイアログの結果処理
パーミッション確認で「許可」、「許可しない」が押下された時の処理をオーバーライドします。
override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { when(requestCode) { PERMISSION_REQUEST_CODE -> { for(i in grantResults.indices) { if(grantResults[i] != PackageManager.PERMISSION_GRANTED) { if (!ActivityCompat.shouldShowRequestPermissionRationale(this,permissions[i])) { AlertDialog.Builder(this) .setMessage("need permission\n\n" + permissions[i]) .setPositiveButton("OK", ({ _, _ -> openSetting() })) .setNegativeButton("Cancel", ({ _, _ -> finish() })) .show() } else { ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE) } return } } // パーミッション全て許可 mainFunction() } else -> { super.onRequestPermissionsResult(requestCode, permissions, grantResults) } } }
コード全体
android studionのプロジェクト選択で"Empty Activity"を選択した場合に初期画面に、"Hello World"のtextviewが設置されています。
このプロジェクトに
- ACCESS_FINE_LOCATION
- WRITE_EXTERNAL_STORAGE
の2つのパーミションを追加し、取得に成功した場合にはtextviewの文字列をpermissionのリストに変更するサンプルです。
import android.Manifest import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.provider.Settings import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import java.lang.StringBuilder class MainActivity : AppCompatActivity() { private val PERMISSION_REQUEST_CODE = 1000 // 必要な権限 private val permissions = arrayOf( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) permissionCheck() } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { when(requestCode) { PERMISSION_REQUEST_CODE -> { for(i in grantResults.indices) { if(grantResults[i] != PackageManager.PERMISSION_GRANTED) { if (!ActivityCompat.shouldShowRequestPermissionRationale( this, permissions[i] )) { AlertDialog.Builder(this) .setMessage("need permission\n\n" + permissions[i]) .setPositiveButton("OK", ({ _, _ -> openSetting() })) .setNegativeButton("Cancel", ({ _, _ -> finish() })) .show() } else { ActivityCompat.requestPermissions( this, permissions, PERMISSION_REQUEST_CODE ) } return } } // パーミッション全て許可 mainFunction() } else -> { super.onRequestPermissionsResult(requestCode, permissions, grantResults) } } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when(requestCode) { PERMISSION_REQUEST_CODE -> { permissionCheck() } else -> super.onActivityResult(requestCode, resultCode, data) } } private fun permissionCheck() { val deniedList = mutableListOf<String>() for(permission in permissions) { if(ContextCompat.checkSelfPermission( this, permission) != PackageManager.PERMISSION_GRANTED) { deniedList.add(permission) } } if(deniedList.size > 0) { // 不許可有 ActivityCompat.requestPermissions( this, deniedList.toTypedArray(), PERMISSION_REQUEST_CODE) return } mainFunction() } private fun mainFunction() { val textView = findViewById<TextView>(R.id.textResult) val ans = StringBuilder() for(permission in permissions) { val check = ActivityCompat.checkSelfPermission(this, permission) ans.append(permission).append(": ").append(check).append("\n") } textView.text = ans } private fun openSetting() { val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) val uri = Uri.fromParts("package", packageName, null) intent.data = uri startActivityForResult(intent, PERMISSION_REQUEST_CODE) } }