티스토리 뷰

Mobile/Android

[Android] 위험 권한

춘햄 2022. 3. 31. 08:41

직전 안드로이드 포스팅에서 브로드 캐스트 메시지를 다루며 SMS 데이터를 가져오는 위험 권한을 잠깐 다뤘었다. 

 

이번 포스팅은 위험 권한이라는 개념을 좀 더 파고들어보고, 위험 권한을 어떻게 사용자가 허용/거부하게 하는 지 그 방법을 2가지 알아볼 것이다.

 

우선 안드로이드에서 권한은 일반 권한과 위험 권한으로 나눌 수 있는데, 일반 권한은 앱을 설치할 때, 사용자에게 해당 권한이 부여된다는 사실을 알려주고 설치할 것인지를 물어본다.

 

그러나 위험 권한은 앱이 실행 시에 사용자에게 해당 권한을 사용할 것인지를 물어본다.

 

위험 권한으로 분류된 권한들은 대부분 개인정보가 담겨있는 정보에 접근하거나 개인정보를 만들어낼 수 있은 단말의 주요 장치에 접근할 때 부여되며, 다음과 같다.

 

허가 그룹 권한
CALENDAR
CALL_LOG
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE

 

이제, 위험 권한을 어떻게 설정할 것인지를 예제 코드와 함께 알아보자.


1. 외부 라이브러리 사용X 

 

◎MainActivity.java

package com.example.permissionex;

import android.Manifest;
import android.content.pm.PackageManager;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String[] permissions = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA
        };

        checkPermissions(permissions);
    }

    public void checkPermissions(String[] permissions) {
        ArrayList<String> targetList = new ArrayList<>();

        for(int i = 0; i < permissions.length; i++) {
            String curPermission = permissions[i];
            int permissionCheck = ContextCompat.checkSelfPermission(this, curPermission);
            if(permissionCheck == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, curPermission + "권한 있음", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this, curPermission + "권한 없음", Toast.LENGTH_LONG).show();
                if(ActivityCompat.shouldShowRequestPermissionRationale(this, curPermission)) {
                    Toast.makeText(this, curPermission + "권한 설명 필요함", Toast.LENGTH_LONG).show();
                } else {
                    targetList.add(curPermission);
                }
            }
        }

        if(!targetList.isEmpty()) {
            String[] targets = new String[targetList.size()];
            targetList.toArray(targets);

            ActivityCompat.requestPermissions(this, targets, 101);
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch(requestCode) {
            case 101: {
                if(grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "첫번째 권한을 사용자가 승인함" , Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(this, "첫번째 권한을 사용자가 거부함" , Toast.LENGTH_LONG).show();
                }
                return;
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

외부 라이브러리 사용 없이 위험 권한을 사용자가 수락/거절하도록 하려면 위와 같이 권한을 가지고 있는 배열을 하나 생성해서 앱이 해당 권한을 이미 가지고 있는 지 판단 후에, ActivityCompat 객체가 가지고 있는 requestPermissions 메서드를 호출하여 권한을 설정할 수 있도록 해준다.

 


2. 외부 라이브러리 <com.yanzhenjie:permission:2.0.3> 사용

 

com.yanzhenjie:permission:2.0.3 라이브러리를 사용하여 위 코드보다는 훨씬 간결하게 권한 설정에 대한 코드를 작성할 수 있다.

 

우선 build.gradle에 해당 라이브러리 dependency를 추가하자.

 

◎build.gradle

implementation 'com.yanzhenjie:permission:2.0.3'

 

◎MainActivity.java

package com.example.permissionex2;

import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.runtime.Permission;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AndPermission.with(this)
                .runtime()
                .permission(Permission.READ_EXTERNAL_STORAGE,
                            Permission.CAMERA)
                .onGranted(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                        showToast("허용된 권한 갯수 : " + permissions.size());
                    }
                })
                .onDenied(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                        showToast("거부된 권한 갯수 : " + permissions.size());
                    }
                })
                .start();
    }

    public void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }
}

이후에 위와 같이 AndPermission 객체를 호출하고, 내부 메서드를 정의해주기만 하면 권한 설정이 끝이 난다.

 

Comments