[Android] 6(2). 위험한 권한 처리하기

3 minute read


위험한 권한 처리하기

위험한 권한에 대해서는 AndroidManifest.xml 파일을 수정한 다음 소스 코드에도 추가로 처리해야 합니다.

여기서는 카메라 권한을 사용하는 앱을 만들면서 설명합니다.


권한 요청 처리 흐름도


앱을 개발할 때 권한 요청을 하면 다음과 같은 과정을 거칩니다.

image-20210809175810370



위험 권한 명세하기


뷰 바인딩을 설정하고 시작합니다.


1. AndroidManifest.xml 파일에서 사용할 권한 작성

< uses-permission /> 태그를 사용하여 카메라 권한을 추가합니다. 태그는 < manifest > 밑에, < applicaiton > 위에 작성합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="kr.co.hanbit.permission">
		<!-- 카메라 권한 명세 -->
    <uses-permission android:name="android.permission.CAMERA"/>

    <application
        ...
    </application>

</manifest>


2. 권한 요청 버튼 만들기

버튼을 누르면 권한을 요청하기 위해 버튼 하나를 만듭니다.

image-20210809184233032



소스코드에서 위험 권한 처리하기


이제 소스 코드를 수정합니다. 위험 권한을 처리하려면 보통 다음 3단계를 거칩니다.

  • 1단계: 권한에 대한 사용자 승인 확인 (이전에 승인하였는지)
  • 2단계: 사용자에게 승인 요청
  • 3단계: 사용자 승인 후 처리


1 단계: 권한에 대한 사용자 승인 확인

1. 권한을 확인하는 checkPermission 메서드 정의

onCreate() 메서드 아래에 checkPermission() 메서드를 정의합니다.

권한의 승인 상태를 먼저 확인하고 승인이면 프로그램 진행, 미승인이면 권한을 요청하도록 합니다.

권한은 모두 Manifest (android) 클래스에 문자열 상수로 정의되어 있습니다.

    // 1단계: 권한에 대한 사용자 승인 확인
    fun checkPermission(){
        // 카메라의 권한의 승인 상태 가져오기
        // 권한은 모두 Manifest(android) 클래스에 문자열 상수로 정의되어 있음
        val cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
        // 승인 상태인지 아닌 지에 따라 분기
        if (cameraPermission == PackageManager.PERMISSION_GRANTED){
            // 승인이면 프로그램 진행
            startProcess()      // 사용자 정의 함수
        }
        else{
            // 미승인이면 권한 요청
            requestPermission() // 사용자 정의 함수
        }
    }


2. 승인 시 프로그램을 진행하는 startProcess 메서드 정의

위에서 확인한 승인 상태가 ‘PERMISSION_GRANTED’ 라면 카메라 프로그램을 실행합니다.

하지만 여기서는 간단히 토스트 메시지만 띄우고 카메라 프로그램 실행은 다른 포스팅에서 다룹니다.

    // 승인 상태일 때 호출.
    fun startProcess(){
        Toast.makeText(this, "카메라를 실행합니다.", Toast.LENGTH_LONG).show()
    }


2 단계: 사용자에게 승인 요청

3. 미승인 시 사용자에게 권한을 요청하는 requestPermission 메서드 정의

사용자에게 미승인된 권한을 요청하고 싶을 때는 ActivityCompat.requestPermission( ) 메서드를 호출합니다. 이 함수를 호출하면 팝업창이 뜨면서 사용자에게 권한을 요청합니다.

    // 2단계: 사용자에게 승인 요청
    // 미승인 시 권한 요청
    fun requestPermission(){
        // 미승인 권한을 사용자에게 요청 -> 팝업창 표시
        // 파라미터: 액티비티, 요청권한 배열, 리퀘스트 코드
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 99)
    }

3개의 파라미터는 각각 액티비티, 요청권한 배열, 리퀘스트 코드입니다.


3 단계: 사용자 승인 후 처리

권한 승인을 묻는 창에 DENY 혹은 ALLOW 을 클릭하면 액티비티의 onRequestPermissionResult( ) 메서드가 호출됩니다.


4. 사용자 승인/미승인 선택 시 호출되는 onRequestPermissionResult 메서드 오버라이드

    // 3단계: 사용자 승인 후 처리
    override fun onRequestPermissionsResult(
        requestCode: Int,               // 요청한 주체를 확인(requestPermission()의 세번째 파라미터)
        permissions: Array<out String>, // 요청한 권한 목록(requestPermission()의 두번째 파라미터)
        grantResults: IntArray          // 권한 목록에 대한 승인/미승인 값.
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }


리퀘스트 코드를 확인하고, 권한 결괏값(grantResults)를 확인하여 승인/미승인 선택 시에 알맞은 메서드를 호출(코드를 작성)합니다.

    override fun onRequestPermissionsResult(
        requestCode: Int,               
        permissions: Array<out String>, 
        grantResults: IntArray          
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        // requestCode 확인
        when(requestCode){
            99 -> {
                // 권한 결괏값을 체크해서 승인 여부를 체크하고, 승인이면 startProcess() 메서드를 호출하고 미승인이면 앱을 종료
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    startProcess()
                }
                else{
                    finish()
                }
            }
        }
    }


5. 버튼 리스너에서 checkPermission 메서드 호출

마지막으로 버튼 클릭 시 사용자에게 권한을 요청하는 checkPermission 메서드를 호출하도록 합니다.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        // 버튼 리스너 -> 권한 확인
        binding.btnCamera.setOnClickListener {
            checkPermission()
        }

    }


이제 에뮬레이터를 실행하고 버튼을 클릭하면 권한 요청을 하는 팝업창이 나타납니다.

image-20210809190534860


일회성 권한

ALLOW 또는 DENY를 선택하면 앱을 지우기 전까지 그 권한이 유지됩니다.

하지만 안드로이드 버전 11(R)부터 실행 시 승인을 요청하는 위험 권한은 종류에 따라 3개의 옵션이 보여지는 것과 2개의 옵션이 보여지는 것으로 나뉩니다.

11부터는 카메라, 위치, 마이크에 대한 권한 요청을 경우 앱 사용 중에만 허용(While using the app), 이번만 허용(Only this time), 거부(Deny) 의 세가지로 세분화되었습니다. 이 중 ‘이번만 허용’을 선택하면 임시로 일회성 권한이 부여되고, 앱을 껐다 키면 다시 한번 승인 요청 팝업창이 나타납니다.

정리


  • 위험 권한이 부여되면 민감한 개인정보 및 기능에 접근할 수 있으며 안드로이드 6.0 버전부터는 앱 매니페스트에 공개하고 코틀린 코드에 권한 요청 및 처리로 액세스가 가능합니다.
  • 소스코드에서의 위험 권한 처리는 권한에 대한 사용자 승인 확인 ➡ 사용자 승인 요청 ➡ 사용자 승인 후 처리 과정을 거칩니다.
  • ActivityCompat.requestPermission( ) 메서드는 사용자에게 권한을 요청하는 팝업을 표시합니다.
  • onRequestPermissionResult( ) 메서드는 사용자에게 권한을 요청한 결과를 알려줍니다.
  • 이번만 허용 권한은 안드로이드 11 버전 이후부터 카메라, 위치, 마이크에 대한 권한 요청 시 승인 후 한 번만 사용할 수 있고 앱을 껐다 켜면 다시 승인 요청을 받아야 합니다.

Categories:

Updated:

Leave a comment