개발자의 끄적끄적

[android] 권한(Permission) 부여 [펌] 본문

개발/android & ios

[android] 권한(Permission) 부여 [펌]

효벨 2019. 11. 14. 01:00
728x90
반응형

[android] 권한(Permission) 부여 [펌]

 

안드로이드 문자 송수신 관련 앱을 개발하던중,

 

특정버전 이상 부터는 권한을 주어도 동작하지 않음을 확인했습니다.

 

그래서 아래글처럼 하니 한방에 해결되었네요!!

 

감사합니다.

 

참고 및 소장용으로 퍼왔습니다! 

 

출처는 맨~아래 명시했습니다!! 도움들 되시길 바래요!

 

 

 

안드로이드 마시멜로(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에 찍히게 된다.



출처: https://satisfactoryplace.tistory.com/5 [만족]

반응형
Comments