📌 Intro
전해들은 바로 요즘은 Activity를 여닫으면서 작업하는 것보다 하나의 Activity에서 Fragment를 이용한다고 한다. 그래서 작성하던 코드를 Fragment로 옮기는 과정에서 Activity에서는 잘 동작하던 requestPermissions() 메서드가 Fragment로 옮기니 deprecated 되었다고 한다.
📌 Fragment에서 권한 요청하기
Activity Result를 받아오는 API가 변경되면서 Fragment.requestPermissions도 deprecated 되었다고 한다. 그래서 registerForActivityResult를 호출하고 ActivityResultContracts.RequestPermission을 인자로 전달해야 한다.
공식 문서에 따르면 다음과 같다.
1. In your activity or fragment's initialization logic, pass in an implementation of ActivityResultCallback into a call to registerForActivityResult(). The ActivityResultCallback defines how your app handles the user's response to the permission request.
Keep a reference to the return value of registerForActivityResult(), which is of type ActivityResultLauncher.
activity나 fragment를 초기화 하는 과정에서 ActivityResultCallback의 구현을 registerForActivityResult 호출에 전달한다. ActivityResultCallback은 권한 요청에 대한 사용자의 응답을 어떻게 처리하는지 정의한다.
ActivityResultLauncher 타입의 registerForActivityResult()의 반환 값을 유지해라.
2. To display the system permissions dialog when necessary, call the launch() method on the instance of ActivityResultLauncher that you saved in the previous step.
After launch() is called, the system permissions dialog appears. When the user makes a choice, the system asynchronously invokes your implementation of ActivityResultCallback, which you defined in the previous step.
시스템 권한 대화상자가 필요하다면 이전 단계에서 저장해둔 ActivityResultLauncher의 launch() 메서드를 호출해라.
launch() 메서드가 호출되면 시스템 권한 대화상자가 나타날 것이다. 사용자가 선택하면, 이전 단계에서 직접 정의한 ActivityResultCallback의 구현을 비동기적으로 실행한다.
📌 코드
필요한 권한이 1개인 경우
private val activityResultLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){ isGranted ->
if(isGranted){
Log.d(TAG, "권한 모두 부여 완료")
}
else{
Log.d(TAG, "권한 모두 부여 실패")
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activityResultLauncher.launch(Manifest.permission.CAMERA) // 권한 요청
}
필요한 권한이 2개 이상인 경우 ActivityResultContracts.RequestMultiplePermissions()을 사용하여 한번에 권한을 요청할 수 있다.
private val permissions = arrayOf(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE) // 허용받을 권한
private val activityResultLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){ resultMap ->
val isAllGranted = permissions.all{e -> resultMap[e] == true}
if(isAllGranted){
Log.d(TAG, "모든 권한 모두 부여 완료")
}
if(resultMap[Manifest.permission.CAMERA] == true){
Log.d(TAG, "카메라 권한 부여 완료 완료")
}
if(resultMap[Manifest.permission.READ_EXTERNAL_STORAGE] == true){
Log.d(TAG, "저장소 권한 부여 완료")
}
else{
Log.d(TAG, "모든 권한 부여 실패")
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activityResultLauncher.launch(permissions) // 권한 요청
}
📌 결과 화면
Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE 권한을 요청한 경우 아래와 같이 시스템 대화 상자가 나타나게 된다.
📌 참고
[1] https://pancake.coffee/2022/03/28/fragment에서-퍼미션-요청하기-2021/
[2] https://developer.android.com/training/permissions/requesting#allow-system-manage-request-code