본문 바로가기
안드로이드/자바

안드로이드 권한 체크 액티비티의 구성(구버전)

by 나이아카 2020. 6. 9.

 안드로이드 스튜디오를 통한 애플리케이션 제작을 위해서는 여러 가지 기능을 이용해야 합니다.

 

 그중, 권한 설정과 관련된 내용을 일반화해볼까 합니다.

 제일 먼저 해야 할 일은 Manifests에 권한들을 추가해주어야 하는 것인데, 그것은 맨 마지막으로 떼고 먼저 자바 코드 먼저 작성해보겠습니다.

 


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //퍼미션 상태 확인
            if (!hasPermissions(PERMISSIONS)) {
                //퍼미션 허가 안되어있다면 사용자에게 요청
                requestPermissions(PERMISSIONS, PERMISSIONS_REQUEST_CODE);
            }else{
                Intent intent = new Intent(this, RunningActivity.class); //실행 화면
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                finish();
            }
        }

 

 제일 먼저 해야 할 일은 현재 어플을 사용할 안드로이드 폰의 버전이 마시멜로우 버전 이상인지 확인해야 합니다. 만약 그것보다 낮은 api(23)라면 Manifests에 설정해주는 것 만으로 권한 설정을 해 줄 수가 있습니다.

 

 하지만 현재 사용하는 스마트폰은 아마 대부분이 api 업데이트가 최신에 가까울 테니, 그에 대한 고려 역시 필수적입니다. 그 문제는 코드의 첫 줄의 if 안의 문장으로 해결이 가능합니다.

 

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 

 

이 조건은 스마트폰의 SDK 버전이 마시멜로우의 버전보다 높거나 같은지를 확인하는 부분입니다.

 

if (!hasPermissions(PERMISSIONS)) 
{
    //퍼미션 허가 안되어있다면 사용자에게 요청
    requestPermissions(PERMISSIONS, PERMISSIONS_REQUEST_CODE);
}
else
{
    Intent intent = new Intent(this, RunningActivity.class); //실행 화면
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    finish();
}

 

 그 다음은 권한 설정을 사용자에게 이미 받은 상태인지 확인하는 부분입니다. 사실 권한 요청은 필수적이지만 한 번 하고 나면 사용자가 다시 일부러 해제하기 전까지는 유지되는 부분입니다.

 

 그리고 여기서 대문자로 된 PERMISSIONS에는 자신이 넣어줄 퍼미션을 배열에다가 넣어주면 됩니다. 쉽게 이해할 수 있도록 가장 자주 쓰는 권한들을 넣어두었습니다.

PERMISSIONS_REQUEST_CODE는 onRequestPermissionsResult()가 콜백되었을 때, 파라미터로 사용됩니다. 이를 이용하면 각 권한마다 다른 메시지를 포함할 수도 있고 다른 행동을 취할 수도 있습니다. 현재 작성한 코드는 간편하게 보여주기 위해 모두 동일한 작업을 시행하게 됩니다.

 

static final int PERMISSIONS_REQUEST_CODE = 1000;
String[] PERMISSIONS  = {Manifest.permission.CAMERA,
                         Manifest.permission.WRITE_EXTERNAL_STORAGE,
                         Manifest.permission.INTERNET};

 

 

 hasePermissions의 경우는 아래에 서술할 메소드로, 자체로 만든 코드입니다.

 

private boolean hasPermissions(String[] permissions) 
{
    int result;

    //스트링 배열에 있는 퍼미션들의 허가 상태 여부 확인
    for (String perms : permissions)
    {
	result = ContextCompat.checkSelfPermission(this, perms);
	if (result == PackageManager.PERMISSION_DENIED){
	//허가 안된 퍼미션 발견
	return false;
    }
}
    //모든 퍼미션이 허가되었음
    return true;
}

 

 permissions라는 변수에 필요한 퍼미션을 넣어두고, 반복문을 통해 여러개의 퍼미션의 권한 체크 여부를 확인하는 코드입니다. ContextCompat.checkSelfPermission은 파라미터로 받은 퍼미션을 확인해 결과값을 리턴해주는데, 이는 PackagerManager.~을 통해 확인할 수 있습니다. 여기서 권한 확인이 되는 경우에 else문으로 들어가 실제 애플리케이션의 메인이 되는 액티비티를 불러오게 할 수 있습니다.

 

 물론  ContextCompat.checkSelfPermission을 실행시키면 shouldShowRequestPermissionrationale()을 콜백해줍니다. 이 메소드를 오버라이딩해서 팝업창을 커스텀하거나 요청 창에서 메시지를 커스텀할 수도 있습니다.

 

 이후, 권한이 없다면 당연히 권한을 요청해줘야 할 것이고, 그것이 조건문 안에 나오는 requestPermissions 메소드 입니다. 이 메소드는 onRequestPermissionsResult()를 콜백해줍니다. 이 메소드를 오버라이딩해야 원하는 권한들을 줄 수 있습니다.

 

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults)
{
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch(requestCode)
    {
        case PERMISSIONS_REQUEST_CODE:
            if (grantResults.length > 0)
            {
                boolean cameraPermissionAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean diskPermissionAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                boolean internetPermissionAccepted = grantResults[2] == PackageManager.PERMISSION_GRANTED;
                if (!cameraPermissionAccepted || !diskPermissionAccepted || !internetPermissionAccepted)
                    permissionDialog("앱을 실행하려면 퍼미션을 허가하셔야합니다.");
                else
                {
                    Intent intent = new Intent(this, RunningActivity.class);
                    startActivity(intent);
                    finish();
                }
            }
            break;
    }
}

 

이 메소드가 콜백되었다면 권한의 GRANTED인지 DENIED인지 확인할 수 있는 grantResults라는 정수형 배열이 파라미터로 들어오게 됩니다. 이를 boolean 타입을 통해 저장합니다. 이를 조건문에서 확인해 하나라도 디나이된 것이 있다면 permissionDialog 이라는 메소드를 통해 다이얼로그를 띄워주게 됩니다.

 

@TargetApi(Build.VERSION_CODES.M)
private void permissionDialog(String msg)
{
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("권한 설정");
    builder.setMessage(msg);
    builder.setCancelable(false);
    builder.setPositiveButton("예", new DialogInterface.OnClickListener()
    {
        public void onClick(DialogInterface dialog, int id)
        {
            requestPermissions(PERMISSIONS, PERMISSIONS_REQUEST_CODE);
        }
    });
    builder.setNegativeButton("아니오", new DialogInterface.OnClickListener()
    {
        public void onClick(DialogInterface arg0, int arg1)
        {
            finish();
        }
    });
    builder.create().show();
}

 

 이 메소드는 메시지를 파라미터로 받아서 타이틀과 메시지를 설정하고 예를 누를 경우 requestPermissions를 재실행함으로서 권한 설정을 위한 팝업창을 다시 띄워 권한을 주고 아니요를 누를 경우 그대로 액티비티가 종료되게 선언해두었습니다. 이는 이 창을 맨 처음 실행할 경우에는 애플리케이션이 종료가 되는 형태로 이루어집니다.

 

 

 

 이렇게 설정을 했다면 액티비티에서 권한을 주는 기능이 완료되었습니다.

 

 이제 마지막으로 Manifests에 권한을 추가할 차례입니다.

 

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>

 

이와 같이 Manifests 내부에 권한을 주고 싶은 것들을 작성해주시면 됩니다.

 


이로서 권한 설정이 완료되었습니다. 이 아래로는 권한의 종류에 대해서 적어놓았습니다.

 

 

ACCESS_CHECKIN_PROPERTIES      체크인데이터베이스의_속성테이블로_액세스
ACCESS_COARSE_LOCATION         코스_로케이션_액세스_(Cell-ID/WiFi)
ACCESS_FINE_LOCATION           파인로케이션_액세스(GPS)          
ACCESS_LOCATION_EXTRA_COMMANDS 로케이션_옵션_커맨드_액세스       
ACCESS_MOCK_LOCATION           목_로케이션_프로바이더_생성_(테스트용)
ACCESS_NETWORK_STATE           네트워크_상태_접근                
ACCESS_SURFACE_FLINGER         서피스_플링거_접근                
ACCESS_WIFI_STATE              WiFi상태_접근                     
ADD_SYSTEM_SERVICE             시스템서비스_추가                 
BATTERY_STATS                  배터리_상태                       
BLUETOOTH                      블루투스                          
BLUETOOTH_ADMIN                블루투스_어드민                   
BRICK                          디바이스_실효성_지정              
BROADCAST_PACKAGE_REMOVED      제거된_패키지에_대한_notification_브로드캐스트
BROADCAST_SMS                  SMS에_대한_브로드캐스트           
BROADCAST_STICKY               인텐트_브로드캐스트               
CALL_PHONE                     통화                              
CALL_PRIVILEGED                통화(긴급전화_포함)               
CAMERA                         카메라                            
CHANGE_COMPONENT_ENABLED_STATE 컴포넌트의_실효성_변경            
CHANGE_CONFIGURATION           컨피그_변경                       
CHANGE_NETWORK_STATE           통신상태_변경                     
CHANGE_WIFI_STATE              WiFi상태_변경                     
CLEAR_APP_CACHE                어플리케이션_캐시_클리어          
CLEAR_APP_USER_DATA            어플리케이션의_유저데이터_클리어  
CONTROL_LOCATION_UPDATES       위치정보_갱신                     
DELETE_CACHE_FILES             캐시파일_제거                     
DELETE_PACKAGES                패키지_제거                       
DEVICE_POWER                   전원상태에_대한_로우레벨_접근     
DIAGNOSTIC                     진단리소스_읽고쓰기               
DISABLE_KEYGUARD               키_가드_끄기_DUMP_덤?            
EXPAND_STATUS_BAR              상태표시줄_확장                   
FACTORY_TEST                   팩토리_테스트                     
FLASHLIGHT                     플래시라이트                      
FORCE_BACK                     포스백                            
GET_ACCOUNTS                   어카운트_획득                     
GET_PACKAGE_SIZE               패키지_획득                       
GET_TASKS                      태스크_획득                       
HARDWARE_TEST                  하드웨어테스트                    
INJECT_EVENTS                  유저이벤트_키/트랙볼              
INSTALL_PACKAGES               패키지_인스톨                     
INTERNAL_SYSTEM_WINDOW         내부_시스템윈도_활용              
INTERNET                       인터넷                            
MANAGE_APP_TOKENS              어플리케이션_토큰관리             
MASTER_CLEAR                   마스터_클리어                     
MODIFY_AUDIO_SETTINGS          오디오설정_편집                   
MODIFY_PHONE_STATE             전화상태_편집                     
MOUNT_UNMOUNT_FILESYSTEMS      파일시스템_편집                   
PERSISTENT_ACTIVITY            액티비티_지속                     
PROCESS_OUTGOING_CALLS         전화_발신처리_접근                
READ_CALENDAR                  캘린더_읽어오기                   
READ_CONTACTS                  주소록_읽어오기                   
READ_FRAME_BUFFER              프레임버퍼_읽어오기               
READ_INPUT_STATE               입력상태_읽어오기                 
READ_LOGS                      로그_읽어오기                     
READ_OWNER_DATA                owner_data읽어오기                
READ_PHONE_STATE               통화상태_읽어오기_READ_SMS_SMS읽어오기
READ_SYNC_SETTINGS             동기설정_읽어오기                 
READ_SYNC_STATS                동기상태_읽어오기                 
REBOOT                         reboot                            
RECEIVE_BOOT_COMPLETED         boot완료                          
RECEIVE_MMS                    MMS수신                           
RECEIVE_SMS                    SMS수신                           
RECEIVE_WAP_PUSH               WAP수신                           
RECORD_AUDIO                   오디오_수신                       
REORDER_TASKS                  태스크_Z오더                      
RESTART_PACKAGES               패키지_리스타트                   
SEND_SMS                       SMS송신                           
SET_ACTIVITY_WATCHER           액티비티_왓쳐지정                 
SET_ALWAYS_FINISH              액티비티_전체_종료                
SET_ANIMATION_SCALE            스케일_애니메이션_지정            
SET_DEBUG_APP                  디버그어플리케이션_지정           
SET_ORIENTATION                스크린_로테이션지정               
SET_PREFERRED_APPLICATIONS     자주_사용하는_어플리케이션_지정   
SET_PROCESS_FOREGROUND         포어그라운드_처리지정             
SET_PROCESS_LIMIT              제한처리_지정                     
SET_TIME_ZONE                  타임존_지정                       
SET_WALLPAPER                  배경화면_지정                     
SET_WALLPAPER_HINTS            배경화면_힌트_지정                
SIGNAL_PERSISTENT_PROCESSES    지속처리_시그널_지정              
STATUS_BAR                     상태표시줄_지정                   
SUBSCRIBED_FEEDS_READ          서브스트립드_피즈_읽어오기        
SUBSCRIBED_FEEDS_WRITE         서브스트립드_피즈_쓰기            
SYSTEM_ALERT_WINDOW            알림_윈도우                       
VIBRATE                        진동                              
WAKE_LOCK                      알람                              
WRITE_APN_SETTINGS             APN설정_쓰기                      
WRITE_CALENDAR                 캘린더_쓰기                       
WRITE_CONTACTS                 주소록_쓰기                       
WRITE_GSERVICES                G서비스_쓰기                      
WRITE_OWNER_DATA               owner_data쓰기                    
WRITE_SETTINGS                 설정_쓰기
WRITE_SMS                      SMS쓰기 
WRITE_SYNC_SETTINGS            동기설정_쓰기

댓글