본 글은 [깡쌤의 안드로이드 프로그래밍 with 자바 - 2022 - 쌤즈] 의 내용을 발췌한 것입니다.if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){ //... }
좀더 자세한 내용은 책 혹은 인강(www.ssamz.com)을 통해 확인해 주세요.
7.1.2. 퍼미션 허용
앞에서 살펴본 퍼미션과 관련된 내용은 API Level 1부터 제공되었던 내용이고 지금도 유효합니다.
<permission>으로 보호된 기능을 이용하는 곳에서는 <uses-permission>을 선언해야 실행할
때 에러가 발생하지 않습니다. 그런데 퍼미션 내용이 안드로이드 6.0 (API Level 23)부터 변화가
생겼습니다. 6.0 이전까지 퍼미션은 일종의 개발자 신고제였습니다. 사용자에게 위험 부담이 큰
퍼미션이라도 개발자가 AndroidManifest.xml 파일에 <uses-permission>으로 등록만 하면
실행하는 데 문제가 없었습니다. 즉, <uses-permission>을 이용하여 사용자에게 이 앱이 어떤 기능을
이용하는지 알려줄 수 있지만, 사용자가 거부할 수 없는 상황이었습니다.
예로 사용자가 간단한 메모장 앱을 설치했다고 가정해 봅시다. 메모장 앱에서 사용자 위치를 추적하고
있습니다. 그런데 사용자 관점에서는 메모장 앱이 왜 내 위치를 추적하는 거지? 이해가 안 될 수도
있습니다. 위치와 관련된 어떤 서비스도 제공하지 않으면서 메모장 앱이 자신의 위치를 추적하는 게
기분 나쁠 수도 있습니다. 그래서 사용자는 메모장 앱에서의 위치 추적을 못 하게 막고 싶습니다.
그런데 6.0 이전 스마트폰에서는 사용자가 이 퍼미션을 거부할 수 없었습니다. 개발자가 자신의 코드에
<uses-permission>으로 부여하면 그냥 실행되는 일종의 신고제였기 때문입니다. 그런데 안드로이드
6.0부터는 사용자가 퍼미션을 거부할 수 있게 변경되었습니다.
그림은 카카오맵의 권한 화면입니다. 사용자가 앱의 퍼미션을 확인하는 것뿐 아니라, 직접 조정할
수도 있습니다. 문제는 사용자가 위 화면에서 퍼미션을 거부해버리면 AndroidManifest.xml 파일에
<uses-permission>이 선언 안 된 것처럼 된다는 점입니다. 아무리 개발자가 <uses-permission>을
추가했더라도 사용자가 거부하면 위치 추적이 안 됩니다. 그러므로 AndroidManifest.xml 파일의
<uses-permission> 선언은 당연하고, 앱 설치 후 사용자가 퍼미션을 거부하는 상황을 고려해야
합니다.
사용자가 퍼미션을 거부하는 상황을 고려해서 프로그램을 작성한다면, 가장 먼저 현시점에 퍼미션
상태를 확인하는 코드가 들어가야 합니다. checkSelfPermission () 함수를 이용하면 퍼미션의 상태를
확인할 수 있습니다.
int checkSelfPermission (Context context, String permission)
두 번째 매개변수가 퍼미션의 이름이며, 이 함수의 반환값은 둘 중 하나입니다.
- PERMISSION_GRANTED: 퍼미션이 부여된 상태
- PERMISSION_DENIED: 퍼미션이 부여되지 않은 상태
checkSelfPermission () 함수가 PERMISSION_GRANTED 값을 반환한다면, 퍼미션이 부여된
것이므로 관련 기능을 실행하면 됩니다.
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
//...
}
만일 퍼미션이 부여되지 않았다면 기능 수행 시 에러가 발생합니다. 그래서 사용자에게 퍼미션
허용을 요청해야 합니다. 그런데 사용자가 퍼미션을 허용하려고 환경설정의 권한 화면으로 가는
건 앱을 벗어나야 해서 상당히 귀찮을 수 있습니다. 따라서 앱 안에서 퍼미션 허용 여부를 묻는
대화상자(Dialog)를 띄워주는 게 좋습니다.
위 그림은 앱에서 위치 정보 액세스 퍼미션을 부여하지 않은 상태에서 실행한 화면입니다. 이처럼
퍼미션이 부여되지 않았다면 앱 내부에서 대화상자를 띄워 퍼미션 허용을 요청해야 합니다. 코드로 직접
퍼미션을 부여할 수는 없습니다. 코드에서는 대화상자를 띄우는 일밖에 못 합니다.
퍼미션 허용 여부를 묻는 대화상자는 시스템 다이얼로그이고, 사용자가 이곳에서 거부 혹은 허용을
선택하게 됩니다. 사용자로부터 결과를 되돌려 받을 때 사용하는 ActivityResultLauncher로 퍼미션
허용을 요청합니다. ActivityResultLauncher는 이후 인텐트를 다룰 때 다시 한번 설명하도록
하겠습니다.
우선, ActivityResultLauncher는 registerForActivityResult () 함수에 의해서 만들어집니다.
public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
@NonNull ActivityResultContract<I, O> contract,
@NonNull ActivityResultCallback<O> callback)
registerForActivityResult ( ) 함수는 2개의 매개변수를 갖습니다. 첫 번째 매개변수는
ActivityResultContract 타입의 객체로, 어떤 요청인지를 표현하기 위해서 사용됩니다. 다양한 요청을
표현하는 서브 클래스가 있으며, 퍼미션을 요청할 때는 RequestPermission을 사용합니다. 두 번째
매개변수는 결과를 받았을 때 호출하는 콜백입니다.
ActivityResultLauncher<String> permissionLauncher
= registerForActivityResult( new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
Log.d("kkang","granted...");
} else {
Log.d("kkang","denied...");
}
});
ActivityResultLauncher 객체를 생성하면, launch () 함수를 호출하여 필요한 요청을 할 수 있습니다
permissionLauncher.launch("android.permission.ACCESS_FINE_LOCATION");
요청의 결과가 registerForActivityResult () 함수의 두 번째 매개변수에 등록된 콜백이 호출되면서
전달됩니다.
'Android' 카테고리의 다른 글
[깡쌤의 안드로이드 프로그래밍 with 자바 - 2022 - 쌤즈] 정리 17 - ViewPager2 (0) | 2022.05.09 |
---|---|
[깡쌤의 안드로이드 프로그래밍 with 자바 - 2022 - 쌤즈] 정리 16 - Notification, Person, Message, RemoteInput (0) | 2022.05.09 |
[깡쌤의 안드로이드 프로그래밍 with 자바 - 2022 - 쌤즈] 정리 14 - 안드로이드 리소스 (0) | 2022.05.09 |
[깡쌤의 안드로이드 프로그래밍 with 자바 - 2022 - 쌤즈] 정리 13 - 뷰 이벤트 (0) | 2022.05.09 |
[깡쌤의 안드로이드 프로그래밍 with 자바 - 2022 - 쌤즈] 정리 12 - LinearLayout (0) | 2022.05.09 |