본문 바로가기

Android

Permission Check : 권한 체크

728x90

권한(Permission)에 관한 포스팅을 해보겠습니다.

Permission

과거 Android App에선 권한이 필요할 시 App 설치 전 사용자에게 필요 권한 목록을 보여주고, 권한을 요구한 뒤 사용자의 응답에 따라 설치를 하거나, 설치를 제한하는 것이 일반적이었지만

Android 6.0 마시멜로 (SDK 23) 이상의 버전부터는 일반 권한의 경우 앱 설치 시점에서 권한에 대한 승인을 요청하고, 위험 권한의 경우 앱 실행 시점에서 권한이 필요할 시 사용자에게 해당 권한이 필요한 이유를 알리고, 권한에 대한 승인을 선택할 수 있도록 변경되었습니다.

분류 세부
LOCATION ACCESS_COARSE_LOCATION 
ACCESS_FINE_LOCATION 
CAMERA CAMERA
MICROPHONE RECORD_AUDIO 
CONTACTS READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
PHONE READ_PHONE_STATE
CALL_PHONE
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
CALENDAR READ_CALENDAR 
WRITE_CALENDAR 
SMS SEND_SMS
READ_SMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
SENSORS BODY_SENSORS
STORAGE READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

 

 

Manifest.permission  |  Android 개발자  |  Android Developers

 

developer.android.com

이제 사용자에게 권한을 요청하는 방법에 대해 알아보겠습니다.

 

1. SDK 버전 확인

2. 해당 권한이 승인 여부 확인

3. 권한 승인 여부에 따라 분기 처리

 

우선 위 순서를 따르기전에 Manifest에 권한을 등록해야 합니다.

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

코드를 작성하는 것은 정해진 것이 없으니 문제가 되지 않는다면, 자신의 방식대로 작성하면 됩니다.

전체적인 순서는

 

1. 사용자 이벤트 발생

2. permissionCheck() 호출 ( 3. versionCheck() 호출, 4. checkSelfPermission() 호출, 5.requestPermissions() 호출 )

6. onRequestPermissionsResult() 응답

 

사용자의 이벤트 발생

        findViewById<ImageButton>(R.id.Lifehelper_logo)
            .setOnClickListener {
                permissionCheck()
            }

 

 

1. SDK 버전 확인 : versionCheck()

 private fun versionCehck() : Boolean {
        if (android.os.Build.VERSION.SDK_INT >= M) {
            return true
        }else{
            return false
        }
    }

 

 

2. 권한 승인 여부 확인 : checkSelfPermission()

private fun checkSelfPermission(): Boolean {
        Log.d(Constants.TAG, "${this::class.simpleName} 권한 체크를 시작합니다.")

        PERMISSIONS.forEach {
            if (ContextCompat.checkSelfPermission(
                    this@MainActivity, it) != PackageManager.PERMISSION_GRANTED) {

                Log.d(Constants.TAG, "${this::class.simpleName} $it 권한 : 거절")

                return false
            }
        }
        return true
    }

ContextCompat.checkSelfPermission() 메서드를 이용하면 권한 승인에 대한 여부를 확인할 수 있습니다.

권한이 있는 경우, PERMISSION_GRANRTED를 없는 경우 PERMISSION_DINIED를 반환합니다.

 

 

3. 권한 승인 여부에 따른 분기 처리 : permissionCheck()

private fun permissionCheck() {
        if (versionCehck()){
            if (checkSelfPermission()) {

                Log.d(Constants.TAG, "${this::class.simpleName} " + "권한 : 승인 상태")

                ...

            } else {

                Log.d(Constants.TAG, "${this::class.simpleName} " + "권한 : 거절 상태")

                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                        PERMISSIONS.toString())) {
                    // 1. 사용자가 승인 거절을 누른 상태

                    Log.d(Constants.TAG, "${this::class.simpleName} " + "사용자가 승인 거절을 누른 경우")

                    requestPermissions()

                } else {
                    // 2. 사용자가 승인 거절 + 다시 표시하지 않기를 누른 경우
                    // 3. 아직 승인 요청을 한 적이 없는 경우

                    Log.d(Constants.TAG, "${this::class.simpleName} " + "사용자가 승인 거절 + 다시 표시하지 않기를 누른 경우")

                    requestPermissions()
                }
            }
        }
    }

ActivityCompat.shouldShowRequestPermissionRationale() : 사용자가 거부를 누른 경우 true를 반환합니다. 보통 이를 통해 조금 더 다양한 분기 처리를 하기위해 사용합니다.

 

 

4. 권한 요청과 응답 처리 : requestPermissions()

  private fun requestPermissions() {
        Log.d(Constants.TAG, "${this::class.simpleName} 권한 요청을 시작합니다.")
        ActivityCompat.requestPermissions(
            this,
            PERMISSIONS,
            Constants.REQUEST_CODE)
    }

ActivityCompat.requestPermissions() : 사용자에게 권한을 요청합니다.

 

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

        when(requestCode){
            Constants.REQUEST_CODE -> {
                grantResults.forEach {
                    if (it == PackageManager.PERMISSION_GRANTED){Log.d(Constants.TAG, "${this::class.simpleName} " +
                            "권한 체크 결과 : $it 승인")
                    }
                    else {
                        Log.d(Constants.TAG, "${this::class.simpleName} " +
                                "권한 체크 결과 : $it 거절")
                        CustomSnackBar.make(findViewById<ImageButton>(R.id.Lifehelper_logo), getString(R.string.request_permission)).show()
                    }
                }
            }
        }
    }

onRequestPermissionResult() : 사용자 응답을 전달합니다. (override method)

'Android' 카테고리의 다른 글

Retrofit2 예제 (feat. HTTP, REST API, OkHttp)  (0) 2021.03.21
RecyclerView : 리사이클러  (0) 2021.03.15
Application Class란 (context 접근)  (0) 2021.03.09
Part.1 - Clean Architecture  (0) 2021.02.26
Localization(지역화)  (0) 2021.02.22