https://developer.android.com/training/permissions/requesting?hl=ko
안드로이드의 외부 저장소에 접근하기 위해서는 별도로 권한을 허용해 주어야 합니다. 안드로이드 자체에서 권한을 요청하는 함수를 지원하기 때문에 다음과 같은 절차로 권한 요청을 할 수 있습니다.
내부 저장소
내부저장소는 모든 스마트폰에서 제공됩니다. 앱을 설치하게 되면 해당 앱을 위한 저장공간이 할당되며 해당 앱에 대한 캐싱 데이터, 로컬 데이터 등이 저장되는 공간입니다.
외부 저장소
대부분 안드로이드 기기는 내부저장소 뿐만 아니라 외부저장소도 갖고있습니다. SD카드와 같이 이동식 저장장치로 제공되기도 하고 내부, 외부 파티션을 나눠 저장공간을 제공하는 경우도 있습니다. 어플리케이션 외의 사진, 음성파일, 문서 같은 데이터들이 저장되는 공간입니다.
먼저 manifest.xml 파일에 다음과 같이 외부 저장소에 대한 uses-permission 태그를 적어주어야 합니다.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"/>
이후에 다음의 requestPermission 함수를 통해 권한을 코드에서 요청할 수 있습니다.
private fun requestPermission() {
val shouldProviceRationale = ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.READ_EXTERNAL_STORAGE
) //사용자가 이전에 거절한적이 있어도 true 반환
if (shouldProviceRationale) {
Log.d("reqreq", "true")
//앱에 필요한 권한이 없어서 권한 요청
ActivityCompat.requestPermissions(
this@ProfileEditActivity,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
PERMISSIONS_REQUEST_CODE
)
} else {
Log.d("reqreq", "false")
ActivityCompat.requestPermissions(
this@ProfileEditActivity,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
PERMISSIONS_REQUEST_CODE
)
//권한있을때 수행할 로직 작성
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>, grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
PERMISSIONS_REQUEST_CODE -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.size > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
) {
//권한 허용 선택시 수행할 로직
} else {
//사용자가 권한 거절시 수행할 로직
denialDialog()
}
return
}
}
}
requestCode에 해당하는 권한의 허용여부를 체크하는 함수입니다.
권한이 허용되지 않았다면 grantResult에 아무값이 들어있지 않으며 권한이 허용되었다면 grantResult[0]에 PERMISSION_GRANTED 값이 들어있게 되므로 적절한 조건문을 통해 권한이 허용됐을 때와 허용되지 않았을 때의 로직을 실행시켜주면 됩니다.
이미 권한이 허용된 상태라면 자동으로 grantResult[0]이 세팅되어있는 상태로 onRequestPermissionResult함수가 실행됩니다.
fun denialDialog() {
AlertDialog.Builder(this)
.setTitle("알림")
.setMessage("저장소 권한이 필요합니다. 환경 설정에서 저장소 권한을 허가해주세요.")
.setPositiveButton("확인", DialogInterface.OnClickListener { dialog, which ->
val intent = Intent()
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
val uri = Uri.fromParts(
"package",
BuildConfig.APPLICATION_ID, null
)
intent.data = uri
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent) //확인버튼누르면 바로 어플리케이션 권한 설정 창으로 이동하도록
})
.create()
.show()
}
만약 권한요청을 거절한다면 denialDialog 함수를 통해 직접 권한설정을 할 수 있도록 설정화면으로 전환시킬 수 있습니다.