안드로이드/자바

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

나이아카 2020. 6. 9. 20:29

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

 

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

 제일 먼저 해야 할 일은 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            동기설정_쓰기