개발/Android

안드로이드 권한 요청하기

나는아니다 2021. 8. 19. 15:55

안드로이드 앱 개발시 카메라나 저장소 등 권한이 필요한 경우가 있다.

옛날에는 그냥 퍼미션만 작성하고 넘어갔지만 스토어 정책으로 권한을 요청하도록 변경된지 오래다.

 

아래와 같이 권한 설정을 한다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.hybriddev">

    <!-- 권한요청 -->
    <uses-permission android:name="android.permission.CAMERA" /> <!-- 카메라 권한 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 외부 저장소 쓰기 권한 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  <!-- 외부 저장소 읽기 권한 -->

    <!-- 하드웨어 요구사항 필터링 -->
    <uses-feature android:name="android.hardware.camera" />     <!-- 카메라가 없는 경우 필터링 -->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.HybridDev"
        android:networkSecurityConfig="@xml/network_security_config"
        android:usesCleartextTraffic="true"
        >
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

<uses-permission> 은 앱에서 필요한 권한이다.

<uses-feature> 는 앱에서 필요한 하드웨어 요구사항이다. 

 

위와 같이 선언했다면 카메라가 없으면 앱이 동작하지 않는다.

 

AnroidManifest.xml 에 선언을 완료 했다면 실제 사용자에게 권한을 요청하는 다이얼로그가 표시되어 사용자 승인을 받아야한다.

 

권한을 체크하기 위해서는 checkSelfPermission()을 사용하여 체크하면 0 또는 -1리턴하고 PackageManager.PERMISSION_GRANTED 와 비교하여 사용한다.

//권한 체크 (권한 체크가 필요한경우 AndroidManifest.xml에 권한을 선언하고  else if 문에 추가하여 체크한다.)
    public void OnCheckPermission() {
        //권한 여부 확인 ==> 권한을 설정하지 않은 경우 체크한다. 이미 권한을 획득했다면 요청하지 않는다.    권한이 없으면 -1 권한이 있으면 0 으로 표시된다.
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {

            //권한 필요에 대한 내용을 다이얼로그로 알리고 승인을 받기 위해서 shouldShowRequestPermissionRationale() 호출하여 사용한다.
            //카메라 권한
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
                Toast.makeText(this, "앱 실행을 위해서는 해당 권한을 설정해야 합니다." , Toast.LENGTH_LONG).show();
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.CAMERA
                                , Manifest.permission.WRITE_EXTERNAL_STORAGE } , PERMISSION_REQUEST);
            //추가... 권한
            } else {
                Toast.makeText(this, "앱 실행을 위해서는 해당 권한을 설정해야 합니다." , Toast.LENGTH_LONG).show();
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.CAMERA
                                , Manifest.permission.WRITE_EXTERNAL_STORAGE } , PERMISSION_REQUEST);
            }
        }
    }

 

checkSelfPermission으로 해당 권한여부를 체크하고 각 권한별로 획득여부를 비교하여 확인한다.

권한이 없을 경우 권한이 필요한 이유를 다이얼로그로 표시하고 해당 권한에 대한 요청을 한다.

 

shouldShowRequestPermissionRationale()를 사용하면 구글에서 제공하는 권한에 대한 설명 문구가 허용, 거부 버튼이 있는 다이얼로그로 출력되며 requestPermissions()을 사용하여 권한에 대한 응답 결과를 리턴 받을 수 있다.

 

requestPermissions()을 사용시에는 요청하는 권한 전부와 해당 요청이 이 앱인지 알 수 있도록 응답코드를 함께 전달하며 처리된 결과는 onRequestPermissionsResult() 메소드를 통하여 처리가 가능하다.

 

팁 : PERMISSION_REQUEST 는 변수로 선언하여 사용한다.

static final int PERMISSION_REQUEST = 0x0000001; //권한관련 응답문자

 

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    //권한을 허용한 경우 grantResults가 0  거부한경우 -1 로 표시된다.
    switch (requestCode) {
        case PERMISSION_REQUEST:        //이 앱의 요청인지 확인하는 코드 선언한 코드와 일치하는 응답이 온다.
            int grantCheck = 0;
            for(int i=0; i<grantResults.length; i++){
                grantCheck += grantResults[i];
            }
            if (grantResults.length > 0 && grantCheck == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "권한이 설정 되었습니다.", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this, "권한 요청을 취소하였습니다.", Toast.LENGTH_LONG).show();
                //앱을 종료하고 태스크 리스트에 남기기
                moveTaskToBack(true);
                finish();
                android.os.Process.killProcess(android.os.Process.myPid());
            }
            break;
    }
}

 

onRequestPermissionsResult()requestPermissions()으로 처리된 결과를 표시하며 요청된 권한은 permissions 배열에 입력되어있고 grantResults 배열에 권한 획득 여부가 입력되어있다.

 

ex) permissions ["카메라권한","외부저장소권한"]

     grantResults [ 0(허용) , -1 (거부) ]

 

 

앱 실행을 위하여 모든 권한이 필수로 필요한 경우에는 위 예제와 같이 배열의 합으로 비교할 수 있고 단일 권한 별로 허용 여부를 나눌 경우 permissions grantResults에서 각각의 권한 정보를 획득하여 if 문으로 비교한 후 처리한다.

 

참고 문서 : https://developer.android.com/training/permissions/requesting?hl=ko

 

그렇다고 한다...

'개발 > Android' 카테고리의 다른 글

안드로이드 FCM RemoteMessage 값 가져오기  (0) 2021.08.11
다른 Activity에 변수 값 가져오기  (0) 2021.08.10