런타임 권한 요청
Android 6.0 마시멜로(API Level 33)부터 런타임 권한 처리가 추가되었습니다.
API Level 33 이전까지는 AndroidManifest에 사용할 permission만 추가하면 되었습니다.
그 이후 버전부터는 앱 사용 중 실제로 접근하는 시점에 권한을 허용했는지 체크하여 처리를 해야합니다.
런타임 권한 요청 | Android 개발자 | Android Developers
런타임 권한 요청 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 모든 Android 앱은 액세스가 제한된 샌드박스에서 실행됩니다. 앱이 자체 샌드박스 밖에 있
developer.android.com
권한 요청 워크플로
앱에서 런타임 권한을 선언하고 요청하기 위해서는 다음 단계들을 완료해야 합니다.
- 앱의 매니페스트 파일에서 앱이 요청할 필요가 있을 권한을 선언합니다.
- 앱의 특정 작업이 알맞은 런타임 권한과 연결되도록 앱의 UX를 설계합니다. 앱이 비공개 사용자 데이터에 액세스하도록 권한을 부여해야 할 수 있는 작업을 사용자에게 알립니다.
- 특정 비공개 사용자 데이터에 액세스해야 하는 앱의 작업을 사용자가 호출할 때까지 기다립니다. 이때 앱은 데이터에 액세스하는 데 필요한 런타임 권한을 요청할 수 있습니다.
- 사용자가 이미 앱에 필요한 런타임 권한을 부여했는지 확인합니다. 부여했다면 앱에서 비공개 사용자 데이터에 액세스할 수 있습니다. 부여하지 않았다면 다음 단계로 이동합니다.
- 런타임 권한이 필요한 작업을 실행할 때마다 권한이 있는지 확인해야 합니다.
- 사용자에게 앱에서 근거를 표시해야 하는지 확인합니다. 여기서 앱이 사용자에게 특정 런타임 권한을 요청하는 이유를 설명합니다. 시스템에서 앱이 근거를 표시하지 않아야 한다고 판단하면 UI 요소를 표시하지 않고 다음 단계로 바로 진행합니다.
- 그러나 시스템에서 앱이 근거를 표시해야 한다고 판단하면 사용자에게 근거를 UI 요소로 표시합니다. 이러한 근거를 통해 앱이 액세스하려는 데이터가 무엇인지, 런타임 권한을 부여하면 앱이 사용자에게 제공할 수 있는 이점이 무엇인지 명확하게 설명해야 합니다. 사용자가 근거를 확인한 후 다음 단계를 진행합니다.
- 앱에서 비공개 사용자 데이터에 액세스하는 데 필요한 런타임 권한을 요청합니다. 권한 개요 페이지에 표시된 것과 같은 런타임 권한 메시지가 시스템에 표시됩니다.
- 런타임 권한 부여를 선택했는지 또는 거부를 선택했는지 사용자의 응답을 확인합니다.
- 사용자가 앱에 권한을 부여하면 비공개 사용자 데이터에 액세스할 수 있습니다. 사용자가 권한을 거부하면 권한으로 보호되는 정보 없이도 사용자에게 기능을 제공하도록 앱 환경의 성능을 단계적으로 저하합니다.
Manifest에 권한 선언
다음은 외부 저장소에서 미디어 파일을 읽을 수 있도록 AndroidManifest에 권한을 선언하는 방법입니다.
<!-- API Level 33 이전 -->
<!-- 미디어 파일 액세스 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- API Level 33 이후 -->
<!-- 이미지 파일 액세스 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- 비디오 파일 액세스 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- 오디오 파일 액세스 -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
권한을 부여받았는지 확인 / 근거를 표시해야 하는지 확인 / 권한 요청
- ContextCompat.checkSelfPermission() : 앱이 이미 해당 권한을 부여받았는지 확인
- shouldShowRequestPermissionRationale() : 앱에서 해당 권한의 근거를 표시해야 하는지 확인
- ActivityCompat.requestPermissions() : 앱을 사용하기 위해 필요한 권한 요청
// API Level 33 이상
when {
// 권한을 부여받았는지 확인
ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_MEDIA_IMAGES
) == PackageManager.PERMISSION_GRANTED -> {
// 바로 작업 수행
loadImage()
}
// 사용자에게 근거를 표시해야 하는지 확인
shouldShowRequestPermissionRationale(
Manifest.permission.READ_MEDIA_IMAGES
) -> {
// 다이얼로그 띄워서 해당 권한이 필요한 이유 설명
AlertDialog.Builder(this).apply {
setMessage("이미지를 가져오기 위해서 외부 저장소 읽기 권한이 필요합니다.")
setNegativeButton("취소", null)
setPositiveButton("동의") { _, _ ->
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
REQUEST_READ_EXTERNAL_STORAGE
)
}
}.show()
}
// 권한 요청
else -> {
// 작업에 필요한 권한 요청
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
REQUEST_READ_EXTERNAL_STORAGE
)
}
}
권한 요청 응답 처리
onRequestPermissionsResult()을 통해 권한 요청의 응답을 확인할 수 있고 허가된 경우와 거절된 경우에 따라 작업을 다르게 처리할 수 있습니다.
// API Level 33 이상
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_READ_MEDIA_IMAGES -> {
val resultCode = grantResults.firstOrNull() ?: PackageManager.PERMISSION_GRANTED
// 권한 허가되었는지 확인
if (resultCode == PackageManager.PERMISSION_GRANTED) {
loadImage()
}
}
}
}
728x90
반응형
'안드로이드 > 개념' 카테고리의 다른 글
[Android] Service (0) | 2023.08.01 |
---|---|
[Android] sealed class (0) | 2023.07.30 |
[Android] registerForActivityResult 사용하기 (0) | 2023.07.26 |
[Android] Serializable vs Parcelable (0) | 2023.07.21 |
[Android] Timer와 Thread (0) | 2023.07.18 |