2024년 5월 20일 월요일

[Kotlin] 권한 처리

권한 처리 방법 정리


예시 화면



권한 처리 과정


권한 처리를 위하여 AndroidManifest.xml 에 작성할 부분과 코드 상 작성할 부분을 구분하여 정리

권한 요청은 두 가지 방법
  1. requestPermission() 함수를 이용하는 방식
  2. ActivityResultApi 를 사용하는 방식

전체 샘플 코드

  • Github
    • 주요코드 위치: android/PermissionSample/app/src/main/java/com/example/permissionsample/CheckPermission.kt


목차

  1. AndroidManifest.xml 에 필요 권한 작성
    1. uses-permission 설명
    2. uses-feature 설명
  2. [코드] 권한 확인하기
  3. [코드] 권한 요청하기 (2가지 방식)
    1. requestPermissions() & onRequestPermissionsResult() 방식
    2. ActivityResultApi 방식


1. AndroidManifest.xml 에 필요 권한 작성


예제) Camera 와 audio 녹음 권한 필요시

<!-- A camera with burst capability is required to use this application -->
<uses-feature android:name="android.hardware.camera.any" />

<!-- Permission declarations -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

안드로이드 권한 목록

1.1. uses-permission 설명


설명


앱이 필요로 하는 권한들 선언


예제) AndroidManifest.xml


<!-- Permission declarations -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />



1.2. uses-feature 설명


설명


마켓플레이스 (Google Play 스토어) 에 필터링 적용


예제) AndroidManifest.xml

<!-- A camera with burst capability is required to use this application -->
<uses-feature android:name="android.hardware.camera.any" />



2. [코드] 권한 확인하기

https://developer.android.com/training/permissions/requesting#already-granted


예제) 권한 목록과 모든 권한 확인


import android.Manifest
import androidx.core.content.ContextCompat

...

private val PERMISSIONS_REQUIRED = arrayOf(
        Manifest.permission.CAMERA,
        Manifest.permission.RECORD_AUDIO)

...

fun hasPermissions(context: Context) = PERMISSIONS_REQUIRED.all {
    ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}

코드 설명


shouldShowRequestPermissionRationale

예)


ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)


설명

사용자 UI, 예를 들어 권한이 필요한 이유를 설명하는 화면를 보여줘야할 필요가 있다고 안드로이드 운영체제가 판단하는지 여부를 확인하는 함수

문제는 언제 true/false 값을 주는지 앱 개발자 측면에서 명확하지는 않다.

다만 안드로이드 공식 예제를 통해 처리 시점을 가늠해 본다



3. [코드] 권한 요청


권한 요청하는 방식은 2가지

3.1. requestPermissions() & onRequestPermissionsResult() 방식





requestPermissions() -> override fun onRequestPermissionsResult()


3.2. ActivityResultApi 방식 (공식 문서 추천)


requestPermissions 와 차이점
  • 주요 차이점: request code 필요 없음
  • 코드 스타일: 권한 핸들러를 따로 독립적으로 구현하여 Activity flow 와 섞임 방지

단일 권한


예제)

class MainActivity : AppCompatActivity() {
    private val requestPermission = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        // returns boolean representind whether the 
        // permission is granted or not
        if (isGranted) {
            Log.i("DEBUG", "permission granted")
        } else {
            Log.i("DEBUG", "permission denied")
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<Button>(R.id.button).setOnClickListener {
            // call launch with string containing permission to be 
            // requested to show the system permission dialog
            requestPermission.launch(Manifest.permission.CAMERA)
        }
    }
}

복수 권한


예제)

class MainActivity : AppCompatActivity() {
    private val requestPermission = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->

        permissions.forEach { actionMap ->
            when (actionMap.key) {
                Manifest.permission.CAMERA -> {
                    if (actionMap.value) {
                        
                        Log.i("DEBUG", "permission granted")
                    } else {

                        Log.i("DEBUG", "permission denied")
                    }
                }
            }
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<Button>(R.id.button).setOnClickListener {

            requestMultiplePermissions.launch(
                arrayOf(
                    Manifest.permission.CAMERA,
                    Manifest.permission.ACCESS_FINE_LOCATION
                )
            )
        }
    }
}


댓글 없음:

댓글 쓰기