안드로이드 퍼미션 체크

너 오늘 코드 짰니?·2022년 8월 25일
0

Android

목록 보기
12/12
post-custom-banner

안드로이드 permission이란?

https://developer.android.com/training/permissions/requesting?hl=ko
안드로이드의 외부 저장소에 접근하기 위해서는 별도로 권한을 허용해 주어야 합니다. 안드로이드 자체에서 권한을 요청하는 함수를 지원하기 때문에 다음과 같은 절차로 권한 요청을 할 수 있습니다.

내부/외부 저장소란?

내부 저장소
내부저장소는 모든 스마트폰에서 제공됩니다. 앱을 설치하게 되면 해당 앱을 위한 저장공간이 할당되며 해당 앱에 대한 캐싱 데이터, 로컬 데이터 등이 저장되는 공간입니다.

외부 저장소
대부분 안드로이드 기기는 내부저장소 뿐만 아니라 외부저장소도 갖고있습니다. SD카드와 같이 이동식 저장장치로 제공되기도 하고 내부, 외부 파티션을 나눠 저장공간을 제공하는 경우도 있습니다. 어플리케이션 외의 사진, 음성파일, 문서 같은 데이터들이 저장되는 공간입니다.

퍼미션 제공을 위한 과정

먼저 manifest.xml 파일에 다음과 같이 외부 저장소에 대한 uses-permission 태그를 적어주어야 합니다.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="28"/>

이후에 다음의 requestPermission 함수를 통해 권한을 코드에서 요청할 수 있습니다.

private fun requestPermission() {
        val shouldProviceRationale = ActivityCompat.shouldShowRequestPermissionRationale(
            this,
            Manifest.permission.READ_EXTERNAL_STORAGE
        ) //사용자가 이전에 거절한적이 있어도 true 반환
        if (shouldProviceRationale) {
            Log.d("reqreq", "true")
            //앱에 필요한 권한이 없어서 권한 요청
            ActivityCompat.requestPermissions(
                this@ProfileEditActivity,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                PERMISSIONS_REQUEST_CODE
            )
        } else {
            Log.d("reqreq", "false")
            ActivityCompat.requestPermissions(
                this@ProfileEditActivity,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                PERMISSIONS_REQUEST_CODE
            )
            
            //권한있을때 수행할 로직 작성
         
        }
    }
  • shoudShowRequestPermissionRotaionale
    권한에 대한 요청이 필요한지 체크하여 Boolean값을 리턴합니다.
    앱이 시작할 때 false로 세팅되며 사용자가 거절을 하게 되면 true가 됩니다. 사용자가 거절을 누른 후 다시 진입했을 때에도 권한요청 알림을 띄워야 하기 때문에 false와 true 모두에 requestPermission 함수를 요청하도록 했습니다.
  • requestPermission
    시스템 알림창을 통해 권한을 요청하는 dialog를 띄웁니다. requestCode에 해당하는 PERMISSIONS_REQUEST_CODE는 임의로 정해준 Int형 변수이며 여러가지 권한을 요청할 때 이 requestCode를 각각 설정하여 요청하여 다음 onRequestPermissionResult가 호출될 때 사용할 수 있습니다.
    승인이나 거절 버튼을 누르게 되면 onRequestPermissionResult 함수가 실행됩니다.
override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>, grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            PERMISSIONS_REQUEST_CODE -> {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.size > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED
                ) {
                    //권한 허용 선택시 수행할 로직
                    
                } else {
                    //사용자가 권한 거절시 수행할 로직
                    denialDialog()
                }
                return
            }
        }
    }

requestCode에 해당하는 권한의 허용여부를 체크하는 함수입니다.
권한이 허용되지 않았다면 grantResult에 아무값이 들어있지 않으며 권한이 허용되었다면 grantResult[0]에 PERMISSION_GRANTED 값이 들어있게 되므로 적절한 조건문을 통해 권한이 허용됐을 때와 허용되지 않았을 때의 로직을 실행시켜주면 됩니다.
이미 권한이 허용된 상태라면 자동으로 grantResult[0]이 세팅되어있는 상태로 onRequestPermissionResult함수가 실행됩니다.

fun denialDialog() {
        AlertDialog.Builder(this)
            .setTitle("알림")
            .setMessage("저장소 권한이 필요합니다. 환경 설정에서 저장소 권한을 허가해주세요.")
            .setPositiveButton("확인", DialogInterface.OnClickListener { dialog, which ->
                val intent = Intent()
                intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                val uri = Uri.fromParts(
                    "package",
                    BuildConfig.APPLICATION_ID, null
                )
                intent.data = uri
                intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
                startActivity(intent) //확인버튼누르면 바로 어플리케이션 권한 설정 창으로 이동하도록
            })
            .create()
            .show()
    }

만약 권한요청을 거절한다면 denialDialog 함수를 통해 직접 권한설정을 할 수 있도록 설정화면으로 전환시킬 수 있습니다.

profile
안했으면 빨리 백준하나 풀고자.
post-custom-banner

0개의 댓글