핀수로그
  • [Android] 권한 요청 워크 플로우
    2023년 12월 28일 22시 58분 39초에 업로드 된 글입니다.
    작성자: 핀수
    728x90
    반응형

    앱을 사용할 때 사용자의 위치에 접근하거나, 미디어 파일에 접근해야하는 경우

    권한을 요청하는 다이얼로그를 본 적이 있을 것이다.

    출처 : https://developer.android.com/guide/topics/permissions/overview?hl=ko#dangerous_permissions

     

    오늘은 권한 요청을 위한 작업 순서에 대해 알아보도록 할 것이다.

    개인 프로젝트인 WW (기온별 옷차림 안내 어플) 을 개발하며 작성해두었던 내용임을 참고하길 바란다.

     

    앱의 매니페스트 파일에서 앱에 요청할 필요가 있을 권한 선언

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

     

    특정 비공개 사용자 데이터에 액세스 해야하는 앱의 작업을 사용자가 호출할 때까지 기다림 → 호출했을 때 런타임 권한을 부여했는지 확인

    WW의 경우 위에서 선언한 것처럼 ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION

    권한이 필요함. -> 위치 권한이다.

     

    ActivityCompat.checkSelfPermission

    권한 확인을 위해서 해당 메서드 실행

    권한을 허용했을 경우 PERMISSION_GRANTED (0)

    허용하지 않은 경우 PERMISSION_DENIED (-1) 반환

    private fun checkPermission(){
        val requirePermissions = arrayOf(
            ACCESS_FINE_LOCATION,
            ACCESS_COARSE_LOCATION
        )
        val rejectPermissionList = ArrayList<String>()
    
        for (permission in requirePermissions) {
            if (ActivityCompat.checkSelfPermission(
                    this,
                    permission
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                rejectPermissionList.add(permission)
            }
        }
        requestPermission(requirePermissions, rejectPermissionList)
    }

     

    권한을 허용하지 않을 경우 허용되지 않은 리스트에 추가

     

    ActivityCompat.requestPermissions

    권한을 요청하는 메소드

    public static void requestPermissions(final @NonNull Activity activity,
                final @NonNull String[] permissions, final @IntRange(from = 0) int requestCode)
    private fun requestPermission(requireArrays: Array<String>, rejectList: ArrayList<String>){
        requestPermissionLauncher.launch(requireArrays)
        if (rejectList.isNotEmpty()) {
            val array = arrayOfNulls<String>(rejectList.size)
            ActivityCompat.requestPermissions(
                this, rejectList.toArray(array), 100
            )
        }
    }

     

    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions())

    시스템이 권한 요청 코드를 관리하도록 허용

    private val requestPermissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { results ->
            val rejectList = mutableListOf<Boolean>()
            for (result in results.values) {
                if (!result) rejectList.add(result)
            }
            if (rejectList.isNotEmpty()) {
                showDialogForGrant()
            } else {
                // granted
                // next step
                val intent = Intent(this, SecondActivity::class.java)
                startActivity(intent)
            }
        }
    public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
                @NonNull ActivityResultContract<I, O> contract,
                @NonNull ActivityResultCallback<O> callback) {
            return registerForActivityResult(contract, mActivityResultRegistry, callback);
        }

     

    ActivityResultCallback 은 앱이 권한 요청에 대한 사용자 응답을 처리하는 방법을 정의함

    시스템 권한 대화상자를 실행시키려면 launch()를 호출해야함

    그러니까 requestPermissionLauncher 를 launch 한 결과를 정의한 것

    권한을 부여하지 않았을 때의 행위를 정의하고 싶다면 여기서 해야함

     

    필요한 작업을 실행할 때 마다 권한을 확인해야함

    권한을 앱 시작시 라던가..한번만 확인을 하게 되면

    (그럴 일은 잘 없겠지만) 앱의 설정 - 권한 부분에서 언제든지 권한 부여를 취소할 수 있다.

    사용자가 중간에 권한을 취소한 상태에서 권한을 요구하는 API를 사용하려고 하면

    높은 확률로 비정상적인 동작을 하게 된다.

    그러니까 권한은 앱을 통해서 뿐만 아니라 설정에서 얼마든지 권한을 허용하고 이를 취소하는 것이 가능하기 때문에

    필요한 기능을 실행할 때마다 권한이 부여되어 있는지 확인을 해주어야 한다는 의미다.


    공부하며 작성된 글이라 잘못된 정보가 있을 수 있습니다.

    말씀해주시면 수정하겠습니다. 감사합니다.

    References

    아래 글을 참고하여 작성 되었습니다.

     

    런타임 권한 요청  |  Android 개발자  |  Android Developers

    런타임 권한 요청 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 모든 Android 앱은 액세스가 제한된 샌드박스에서 실행됩니다. 앱이 자체 샌드박스 밖에 있

    developer.android.com

     

    728x90
    반응형
    댓글