본문 바로가기

개발

[Android] 런타임에 권한 요청

반응형

런타임에 권한 요청 


Anrdoid 6.0(API 레벨 23)부터 사용자는 앱이 설치될 때가 아니라 앱이 실행되는 도중 앱에 권한을 부여한다. 

그래서 앱 설치 과정이 간소화 되고, 사용자는 앱의 기능을 더 세부적으로 제어할 수 있게 되었다. 

예를 들어, 사용자는 앱에 카메라 제어 권한만 부여할 수도 있고 위치 권한을 주지 않을 수도 있다. 

또한, 앱 설정 화면에서 언제든지 권한 취소가 가능하다.


시스템 권한은 정상권한, 위험권한 두가지로 구분된다.

 - 정상권한

   사용자 개인정보를 직접 위험에 빠뜨리지는 않는다.

   앱이 매니페스트에 정상 권한을 나열하는 경우, 시스템은 자동으로 권한을 부여한다.

 - 위험 권한

   사용자 기밀 데이터에 대한 액세스를 앱에 부여할 수 있다. 

   앱이 매니페스트에 정상권한을 나열하는 경우, 시스템은 자동으로 권한을 부여하고,

                            위험권한을 나열하는 경우, 사용자는 명시적 앱에 대한 승인을 

                                                                제공해야 한다.


권한 선언은 시스템 버전과 앱의 대상 SDK 레벨에 따라 달라진다. 

   - Android 5.1이하 또는 앱의 대상 SDK가 22 이하인 경우 

     앱을 설치할 때 권한부여, 권한을 부여하지 않을 경우 앱 설치가 되지 않는다.

   - Android 6.0 이상이고, 앱의 대상 SDK가 23 이상인 경우 

     앱이 실행되는 도중에 각 위험 권한 요청. 

      사용자는 각 권한을 부여하거나 거부할 수 있고, 사용자가 권한 요청을 거부할 경우

      제한된 성능으로 앱이 실행 될 수 있다. 

  

** Android 6.0(API 23) 부터는 앱이 더 낮은 API 레벨을 대상으로 하더라도 

   사용자가 언제든지 모든 앱에서 권한을 취소할 수 있다. 

   그래서 권한이 필요 없을 때도 올바로 동작 하는지 테스트가 되어야 한다!


권한 확인 & 권한 요청 

//임의의 정수로

private static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 3000;


...


// thisActivit가 READ_CONTACTS 권한을 가지고 있는지 확인

// 권한이 없으면 PackageManager.PERMISSION_GRANTED 리턴
if (ContextCompat.checkSelfPermission(thisActivity,

Manifest.permission.READ_CONTACTS)
     
!= PackageManager.PERMISSION_GRANTED) {

   
// Should we show an explanation?

// 권한 설명 창

// 이전에 요청 했고, 사용자가 거부한 경우, TRUE 반환

// 사용자가 동의한 경우, FALSE 반환

// ** 과거 사용자가 권한 요청 거부하고,

시스템 태화상자에서 Don't ask again 하면 FALSE 반환
   
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
           
Manifest.permission.READ_CONTACTS)) {

       
// Show an expanation to the user *asynchronously* -- don't block
       
// this thread waiting for the user's response! After the user
       
// sees the explanation, try again to request the permission.

// 사용자가 동의 했을 때
   
} else {

       
// No explanation needed, we can request the permission.
// 권한 요청 창

// 비동기식 동작, 즉각적으로 반환

//

        ActivityCompat.requestPermissions(thisActivity,
               
new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS
);

       
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
       
// app-defined int constant. The callback method gets the
       
// result of the request.
   
}

}

권한 응답 처리 

@Override
public void onRequestPermissionsResult(int requestCode,
       
String permissions[], int[] grantResults) {


// 위에서 선언한 MY_PERMISSIONS_REQUEST_READ_CONTACTS 으로 코드 들어옴
   
switch (requestCode) {
       
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
           
// If request is cancelled, the result arrays are empty.

// 권한 얻을 때
           
if (grantResults.length > 0
               
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {

               
// permission was granted, yay! Do the
               
// contacts-related task you need to do.
            // 권한 못얻었을때
           
} else {

               
// permission denied, boo! Disable the
               
// functionality that depends on this permission.
           
}
           
return;
       
}

       
// other 'case' lines to check for other
       
// permissions this app might request
   
}
}


반응형