만족
[Android Studio] 권한(Permission) 부여 본문
[Android Studio] 권한(Permission) 부여
FrontEnd/Android Satisfaction 2017. 6. 30. 03:48이 글은 아래 링크에서 새로 작성되었습니다
satisfactoryplace.tistory.com/203
안드로이드 마시멜로(6.0) OS 이전에는, 앱을 설치하기 전에 모든 앱 권한을 한번에 요구하고, 거절할 경우 설치 자체가 되지 않았으나
업데이트 이후에는, 기본 권한(Normal Permission)만 설치 전에 물어보고
위험 권한(Dangerous Permission)의 경우는 설치 후에 필요에 따라 권한을 줄지 말지 사용자가 선택할 수 있게 되었다.
위험 권한의 종류
(위험 권한의 일부)
(참조: https://developer.android.com/guide/topics/security/permissions.html?hl=ko)
위험 권한 취득
먼저, Manifast에 어떤 권한을 얻을 것인지 명시해야 한다.
SMS수신 권한은 위험 권한이므로, SMS수신 권한을 얻을 것이라고 가정하면
<uses-permission android:name="android.permission.RECEIVE_SMS">
</uses-permission>
을 Manifast에 적어준다.
Actirivity 클래스에서 다음 코드를 추가한다.
static final int SMS_RECEIVE_PERMISSON=1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//권한이 부여되어 있는지 확인
int permissonCheck= ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS);
if(permissonCheck == PackageManager.PERMISSION_GRANTED){
Toast.makeText(getApplicationContext(), "SMS 수신권한 있음", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "SMS 수신권한 없음", Toast.LENGTH_SHORT).show();
//권한설정 dialog에서 거부를 누르면
//ActivityCompat.shouldShowRequestPermissionRationale 메소드의 반환값이 true가 된다.
//단, 사용자가 "Don't ask again"을 체크한 경우
//거부하더라도 false를 반환하여, 직접 사용자가 권한을 부여하지 않는 이상, 권한을 요청할 수 없게 된다.
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECEIVE_SMS)){
//이곳에 권한이 왜 필요한지 설명하는 Toast나 dialog를 띄워준 후, 다시 권한을 요청한다.
Toast.makeText(getApplicationContext(), "SMS권한이 필요합니다", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.RECEIVE_SMS}, SMS_RECEIVE_PERMISSON);
}else{
ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.RECEIVE_SMS}, SMS_RECEIVE_PERMISSON);
}
}
}
다소 복잡해 보이는 코드이지만, 한줄한줄 분석해보면 간단하다.
ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS);
는 SMS 수신 권한을 가지고 있는지 없는지를 반환하는 메소드이다.
다음 if문에서 이 반환값(permissionCheck)이 Pakage.PERMISSION_GRANTED과 같은지를 비교한다.
이렇게 비교하는 이유는, checkSelfPermission(..)메소드가 반환하는 상수의 종류는
Pakage.PERMISSION_GRANTED -> 권한 있음
Pakage.PERMISSION_DENIED -> 권한 없음
이 두가지 이기 때문이다.
권한이 없다면 else문에서 다시한번 if문을 사용하는데, 조건을 보면
ActivirtyCompat.shouldShowRequestPermissionRationale(...) 메소드가 삽입되어 있는 것을 볼 수 있다.
메소드 이름에서 유추할 수 있듯이, 요청하는 권한이 왜 필요한지 이유를 설명할 때 if문과 동시에 사용한다.
이 메소드는 권한 요청 시에 '다시 묻지 않음'을 체크하지 않고 '거부'를 눌렀을 때만 true를 반환한다.
따라서 else부분에 ActivityCompat.requestPermission(...)을 통해 권한을 요청하고
조건이 참일 경우에도 "왜 이 권한이 필요한가?" 를 설명한 후, 예제처럼 권한을 요청하거나 필요하지 않다면 요청하지 않아도 된다.
ActivityCompat.requestPermission(...)의 매개변수에는
첫 번째에는 thisActivity를 전달하고
두 번째에는 요청할 권한이 여러개일 수 있으므로, String 타입 배열로 전달한다.
배열의 요소는 Manifast에 상수로 정의되어 있는 상수를 사용한다.
세 번째에는 requestCode를 전달하는데,
이를 이용하여 onRequestPermissionsResult()메소드에서 해당 권한이 승인되었는지 확인 가능하다.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int grantResults[]){
switch(requestCode){
case SMS_RECEIVE_PERMISSON:
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(getApplicationContext(), "SMS권한 승인함", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "SMS권한 거부함", Toast.LENGTH_SHORT).show();
}
break;
}
}
grantResults[]는 권한 요청을 한 권한들에 대해서, 그 권한을 허용했는지 거부했는지의 여부를 알 수 있다.
위의 코드에서는 한 가지 권한만을 요청했으므로, 배열의 길이는 1이 된다.
권한 거부
권한을 얻지 못한 상태에서 해당 권한이 필요한 작업을 시도하려 한다면
SecurityException이 발생하게 된다.
단 모든 경우에 그런 것은 아니며, 대부분의 경우 Log에 찍히게 된다.
'FrontEnd > Android' 카테고리의 다른 글
[Android Studio] java.lang.IllegalStateException: commit already called java.lang.IllegalStateException: commit already called (0) | 2017.06.30 |
---|---|
[Android Studio] 프래그먼트(Fragment) (0) | 2017.06.30 |
[Android Studio] 브로드캐스트 수신자(BroadCast Receiver) (0) | 2017.06.30 |
[Android Studio] 서비스(Service) (0) | 2017.06.30 |
[Android Studio] 뒤로가기 버튼을 두번 눌러 액티비티 종료하기 (0) | 2017.06.30 |