Permission Request Process(Storage Access Framework)
앱 권한 요청 프로세스
권한 요청 프로세스는 여기를 통해 자세히 확인하기
예제 코드
- 권한 요청 코드 작성
//권한 요청하기 코드
when{
// 1. 권한이 허용되어있는 경우
ActivityCompat.checkSelfPermission(
this,
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED ->{
TODO()
}
// 2. 해당 권한이 거부 된 경우
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE) ->{
// 교육용 팝업을 띄운 후 권한 요청
//showPermissionContextPopup() // 직접 팝업을 생성
}
// 3. 앱을 처음 실행한 경우
else ->{
// 권한 요청하기
ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),1000) // 1000 코드 기억
}
}
- 권한 거부시 교육용 팝업 설정
// 위 when 절의 2번에서 사용된 교육용 팝업 함수
private fun showPermissionContextPopup(){
AlertDialog.Builder(this:Context)
.setTitle("권한 요청")
.setMessage("권한이 필요합니다.")
.setPositiveButton("동의하기") { _, _ ->
// 동의 -> 권한 요청
ActivityCompat.requestPermissions(this,arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE), 1000)
}
.setNegativeButton("취소하기"){ _, _ -> }
.create()
.show()
}
- 권한 요청 후 자동으로 호출되는 콜백 함수
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray){
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when(requestCode){
// 위 권한요청에 사용된 요청코드(SAF권한 요청 코드)
1000 -> {
if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
// 권한이 부여되었음, 기능 동작
TODO()
}
}
else -> {
// 다른 권한 요청의 경우
}
}
}
- Manifest에 권한 선언하기
<uses-permission android:name="android.Manifest.permission.READ_EXTERNAL_STORAGE"/>
<application
...
- SAF(Storage Access Framework) 사용, 엑티비티 시작
startActivityForResult(intent, code) 함수를 사용해 엑티비티 실행의 후 콜백 함수(onActivityResult) 호출
private fun todo(){
val intent = Intent(Intent.Action_GET_CONTENT) // 컨텐트 가져오기
intent.type = "image/*"
// 결과 받아오는데 사용
// startActivityForResult(intent, 2000) // 예전 방식입니다.
// A->B 로 인텐트를 시도 할 때 B 인텐트에서 실행할 코드
// 그대로 사용 가능( 앞으로 실행될 intent의 결과를 입력하는 함수)
// val resultIntent Intent(this,AActibity::class.java)
// setResult(Activity.RESULT_OK,resultIntent)
// setResult(Activity.RESULT_OK, resultIntent)
// 최신화, activityResultLauncher 객체 생성은 아래에서 나옴
activityResultLauncher.launch(intent)
}
intent activity 결과(사진) 받아오기, 엑티비티 실행 후 자동 호출 콜백 함수예전 방식입니다. 아래 최신화 있음
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?){
super.onActivityResult(requestCode, resultCode, data)
if(resultCode != Activity.RESULT_OK){ // 비정상 종료의 경우
return
}
when(requestCode){
2000 -> {
val selectedImageUri: Uri? = data?.data
if(selectedImageUri != null){
// ImageView
imageView.set.setImageUri(selectedImageUri)
}else{
// 사진 가져오기 실패
}
}
else -> { }
}
}
- Activity 결과 받아오기
activityResultLauncher 객체 생성 후 startActivityForResult() 대신 launcher() 사용!
private val activityResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
){
if(it.resultCode == RESULT_OK){ //it:ActivityResult! ->
val selectedImageUri:Uri? = it.data?data
if(selectedImageUri != null){
// ImageView
imageView.set.setImageUri(selectedImageUri)
}else{
// 사진 가져오기 실패
}
}
else -> { }
}