3가지 메소드로 끝내는 안드로이드 마시멜로 권한 획득

2016-03-21
 

안드로이드 마시멜로부터 권한획득이 변경되었다. 기존의 안드로이드 Manifest에 권한을 선언 해두기만 하면 되었다. 사용자 입장에서는 설치시 해당 권한을 확인 할뿐 설치 후 앱을 사용하면서 해당 권한을 언제 사용하는지 알 수 없다. 구글은 이러한 보안적인 문제점을 해결 하기 위해 권한획득의 시점을 변경 하였다. 관련된 API를 사용하기전 권한을 획득 하는 방식으로 변경하여 사용자는 언제 어느시점에 권한이 필요한지 인지 할 수 있으며 보안적인 문제점을 좀 더 보완할 수 있다는 점이다. 마시멜로 권한 획득 어떻게 대응하는지 알아보자.

권한 획득은 3가지의 지원되는 메소드만 이용하면 간단하게 대응 할 수 있다.


ContextCompat.checkSelfPermission(Context context, String permission)

해당 퍼미션의 상태를 체크한다. 메소드를 이용하여 퍼미션이 허용되었는지 거부된 퍼미션인지 체크 할 수 있다. 단, 마시멜로 이전 버전으로 빌드된 앱이 마시멜로를 타겟으로 빌드된 앱으로 업데이트 설치된 사용자의경우 기존의 모든 퍼미션은 허용되어 있다.

Manifest.permission.*에 모든 퍼미션이 정의되어 있으며, PERMISSION_GRANTED(허용된 퍼미션), PERMISSION_DENIED(거부된 퍼미션)으로 결과값이 리턴된다.


ActivityCompat.shouldShowRequestPermissionRationale(Context context, String permission)

사용자가 권한 요청을 한번이라도 거부한 경우를 알 수 있다. 사용자가 권한에 대한 의심으로 인해 거부하는 경우 좀더 상세한 안내를 표시 해줄 수 있다. 최초 퍼미션 요청시에는 false를 리턴한다.


ActivityCompat.requestPermissions(Activity activity, Stringp[] permission, int requestCode)

Callback
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)

퍼미션을 요청한다. 퍼미션을 퍼미션 그룹을 통해 한번에 간소화된 다이얼로그로 창이 뜬다. onRequestPermissionsResult()를 통해 결과값이 Callback된다.


정리

1) ContextCompat.checkSelfPermission()

  • 해당권한이 허용되 있는지 체크한다.

2) ActivityCompat.shouldShowRequestPermissionRationale()
– 이미 한번 이라도 거부한 경우 좀 더 상세한 안내페이지를 표시해준다.
– 다시 묻지 않기를 선택 후 거부한 사용자를 위해 안내페이지에 설정으로 바로가는 액션을 준비 해둔다.

3) ActivityCompat.requestPermissions()
– 퍼미션을 요청한 후 Callback되었을때 결과값 또는 checkSelfPermission()을 통해 해당 퍼미션 권한을 획득하면 다음 단계를 실행 한다.


TIP!

퍼미션 권한 획득 후 획득된 퍼미션 그룹과 동일한 퍼미션이 추가 되는 경우 퍼미션이 추가 된 경우 해당 그룹에서 이미 권한을 획득한 사항이라면 requestPermissions()을 호출 하면 아무런 UI없이 nRequestPermissionsResult()를 통해 자동으로 권한이 획득된다.

다시 묻지않기 선택 후 거부시 requestPermissions()을 요청하는 경우 더 이상 다이얼로그를 통해 해당 퍼미션의 권한을 요청 할수 없는 상태임으로 안내페이지를 통해 앱 정보->권한에서 해당 권한을 받도록 유도한다. 권한으로 바로가는 링크는 없으며, ACTION_APPLICATION_DETAILS_SETTINGS 액션을 통해 앱 정보페이지로 연결 해주는 정도가 최선이다.

Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + context.getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivityForResult(i, REQUEST_CODE_SETTING_ACTIVITY);

권한 안내 가이드는 아래 구글 머티리얼 디자인 사이트를 참조하자.
https://www.google.com/design/spec/patterns/permissions.html#permissions-request-patterns


추가 참고
http://googledevkr.blogspot.kr/2015/09/android60runtimepermission.html
http://developer.android.com/intl/ko/guide/topics/security/permissions.html#normal-dangerous