티스토리 뷰

728x90

 

 

권한 요청 방법 - 기존 방식

먼저 기존에 안드로이드에서 권한을 요청하기 위해 사용한 방법을 알아보자.

 

 

1. manifest

    <uses-permission android:name="android.permission.CAMERA" />

manifest 파일의 <application> 바깥에 <user-permission>을 넣어준다.

 

 

2. 권한 요청

fun requestPermissions() {
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            return
        }
        
        ActivityCompat.requestPermissions(this, 
            arrayOf(Manifest.permission.CAMERA), 
            REQUEST_CODE)
}

checkSelfPermission()을 통해 현재 권한이 허용되었는지 거부되었는지 확인한다.

만약 이미 허용된 상태라면 권한을 요청하지 않고 함수를 빠져나온다. (PackageManager.PERMISSION_GRANTED)

허용되지 않은 상태라면 (PackageManager.PERMISSION_DENIED) requestPermissions()로 사용자에게 권한을 요청한다.

requestPermissions()의 인자로는 Activity / 권한 종류를 담은 배열 / 권한 요청을 구분할 RequestCode가 들어간다.

 

 

3. 권한 요청 결과

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        REQUEST_CODE -> {
            if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // 사용자가 권한을 허용함
                // 허용 처리 로직 작성
            } else {
            	// 사용자가 권한을 거부함
                // 거부 처리 로직 작성
            }
            return
        }
    }
}

사용자가 권한 요청 창에서 허용이나 거부를 누르면, onRequestPermissionsResult()가 호출된다.

이 함수의 인자로는 사용자의 권한 요청 결과가 전달된다. grantResults 배열을 통해 확인할 수 있다.

또한 requestPermissions()에 전달한 requestCode가 여기에서도 사용된다. 

즉, 개발자가 따로 권한 요청을 구분하기 위한 requestCode를 관리해주어야 한다는 단점이 있다.

 

중요한 건, 이 onRequestPermissionsResult()가 deprecated 되었다는 것이다.

그럼 어떤 방식으로 권한을 요청하면 좋을지 지금부터 알아보자.

 

 

 

권한 요청 방법 - registerForActivityResult() 사용

1. manifest

manifest는 기존 방식과 동일하게 사용하고자 하는 권한의 <user-permission>을 넣어주면 된다.

 

 

2. 권한 요청 결과 받아오는 launcher 생성

    private val cameraPermLauncher = 
    	registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        	if (isGranted) {
                // 권한 허가 처리 로직
            }
            else {
                // 권한 거부 처리 로직
            }
        }

deprecated된 onRequestPermissionsResult()를 대체하는 함수가 바로 registerForActivityResult()다.

이 함수를 통해 액티비티 간의 결과를 받아올 수도 있는데, 이 다음에 다시 포스팅하도록 하겠다.

 

위 코드는 권한을 요청하고 결과를 받아오는 launcher를 전역 변수로 선언한 것이다.

registerForResult() 함수 안에는 ActivityResultContact, ActivityResultCallback이 인자로 들어간다.

 

이 코드에서 첫번째 인자로 ActivityResultContracts.RequestPermission()가 들어갔다.

이는 단일 권한을 요청한 결과를 받아온다는 의미다.

만약 여러 권한을 한번에 요청하고 싶다면 RequestPermission을 RequestMultiplePermissions 바꿔주면 된다.

 

그리고 뒤에는 Callback 람다가 인자로 들어갔다.

여기서 isGranted가 true면 사용자가 권한을 허용한 것이고, false면 사용자가 권한을 거부한 것이다.

isGranted가 어떤 값이냐에 따라 로직을 나눠주면 된다.

 

* launcher는 onResume() 이전에 생성해야 한다. 즉, onStart()나 onCreate(), 함수 외부에서 생성한다.

 

 

3. launcher 실행하기

이전에 launcher를 생성했는데, 전역 변수로 선언만 하고 실행은 하지 않았다.

선언만 하면 아무런 권한 요청을 하지 않을 것이다.

따라서 launcher를 실행해주어야 한다.

 

    private fun checkPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            // 이미 권한이 허용된 경우
            return
        }
		
        notiPermLauncher.launch(Manifest.permission.CAMERA)
    }

이전 방식과 동일하게 checkSelfPermission()으로 권한이 허용된 상태인지 체크한다. 

권한이 허용되어 있다면 launcher를 실행하지 않고 함수를 빠져나온다.

권한이 허용되어 있지 않다면 launcher를 실행한다. 이때 인자로 요청할 권한의 종류를 넘겨준다.

 

이 방식은 권한 요청을 구분하기 위해 사용한 requestCode가 필요하지 않다.

권한 요청과 권한 결과 콜백을 하나의 변수(launcher)로 선언하고, 그 launcher를 실행하기만 하면 되기 때문이다.

launcher를 실행하면 기기에 권한 요청 창이 뜨고, 사용자가 허용/거부 버튼을 누르면 launcher의 콜백이 실행된다.

 

 

 

* 참고로 권한이 허용되었는지, 거부되었는지에 따라 달라지는 처리 로직을 적기 위해서는

보통 launcher의 콜백보다 checkPermission() 함수 내에 구현한다.

checkPermission()이 onResume() 후에 호출되더라도,

checkPermission()을 통해서 권한을 요청하고, 사용자가 권한을 허용하면 프로세스가 다시 생성되어 onResume()을 호출하기 때문이다.

 

만약 onResume()에서 카메라를 초기셋팅하고, launcher의 콜백에서 isGranted가 true인 경우(권한 허용) 카메라를 시작한다고 치자.

콜백에서 카메라를 시작하더라도 다시 onResume()을 새로 호출해서 카메라를 초기셋팅하기 때문에 카메라를 시작한게 의미가 없어진다.

이 경우 checkSelfPermission()에서 GRANTED인 경우에 카메라를 시작하도록 하면 해결된다.

인턴 당시 이걸 몰라서 애먹었던 기억이 있어서, 아직도 기억에 남는다..ㅎㅎ

 

 

 

+ 추가적으로 registerForActivityResult를 통해 액티비티 간 데이터를 전송하는 방법을 포스팅했다.

https://thdbs523.tistory.com/372

 

[안드로이드/코틀린] registerForActivityResult() - activity간 데이터 전달

기존 방식 - startActivityForResult 먼저 activity간 데이터를 전달하는 기존 방식을 알아보자. 자세히 말하면 새로운 activity로 이동하고, 그 activity가 닫힐 때 결과를 받아오는 것이다. 1. 데이터를 받을 a

thdbs523.tistory.com

 

728x90
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함