Android 6.0 Marshmallow(API 23) 이전에는 `` AndroidManifest.xml``에 필요한 위험 권한을 선언해놓고, 앱을 설치할 때 한 번에 권한을 획득하는 방식이었다.

그러나 6.0부터는 런타임에 위험 권한을 요청해야 한다.

  • 기기에서 Android 5.1 이하를 실행 중이거나, 또는 앱의 `` targetSdkVersion``이 22 이하인 경우:
     여러분이 매니페스트에 위험 권한을 나열하는 경우, 사용자는 앱을 설치할 때 권한을 부여해야 하며, 권한을 부여하지 않을 경우 시스템이 앱을 설치하지 않습니다.
  • 기기에서 Android 6.0 이상이 실행 중이고, 그리고 앱의 `` targetSdkVersion``이 23 이상인 경우:
    앱이 매니페스트에 권한을 나열해야 하며, 그리고 앱이 실행되는 중에 필요한 각 위험 권한을 요청해야 합니다. 사용자는 각 권한을 부여하거나 거부할 수 있으며, 사용자가 권한 요청을 거부하더라도 제한된 성능으로 앱이 계속 실행될 수 있습니다.

따라서 어떤 OS에서든 런타임 처리를 원하지 않는다면 `` targetSdkVersion < 23``으로 설정하면 된다.

단, 이런 경우 유저가 스마트폰 설정에서 권한을 해제했을 경우 이를 알 수 없으므로 권한이 필요한 API를 사용하지 못한다는 단점이 있다.


그룹으로 관리

Android에서 권한은 permission groups로 구성되며 그룹에 속하는 한 가지 항목에 대해 권한을 승인 받으면, 같은 그룹에 속한 다른 권한은 시스템이 자동으로 권한을 부여한다.


권한 요청 시 유의할 점

`` AndroidManifest.xml``에 명시해야 하는 ELEMENT는 ``xml <uses-permission/>``이다... xml이라 오타 안잡아주니까 주의.

#1

manifest에 명시하지 않은 권한을 ``kt ActivityCompat.requestPermissions()``으로 요청하는 경우 다이얼로그가 뜨지 않는다.

#2

```kt
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
        (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED)) {
```
누군가가 이거 6.0 이하에서는 그냥 0(`` PERMISSION_GRANTED``)을 반환한다고 써놨던데, 아님 ㅅㅂ. 
항상 -1(`` PERMISSION_DENIED``)를 반환하니까 버전 체크해서 6.0 이상만 수행하도록 해야한다.


#3

```kt

ActivityCompat.shouldShowRequestPermissionRationale()

```

위 함수는 사용자에게 권한에 대한 설명이 필요한 경우인지를 체크하는 함수로, 권한 요청 다이얼로그에서 한 번 이상 거부하고, 다시 보지 않기를 체크하지 않은 경우에만 ``kt true``를 반환한다.

Note ) 다시 보지 않기를 체크하고 거부하였을 경우에는 ``kt ActivityCompat.requestPermissions()``를 요청해도 자동으로 사용자가 거절을 누른 것으로 처리하기 때문에 권한 요청 다이얼로그를 띄우지 않고 바로 ``kt onRequestPermissionsResult()``로 넘어간다.


#4

앱에 꼭 필요한 권한이고, 이 권한이 필요함이 자명한 경우에는 그냥 앱을 시작하면서 권한을 요청하는 것이 좋다.

예를 들어 사진 앱인 경우 아예 시작하면서 카메라 액세스를 요청할 수 있다. 그러나 공유 기능에 필요한 `` READ_CONTACTS`` 등의 권한은 시작하면서 요청하는게 아니라 "공유" 기능을 사용하려 할 때 요청하는 것이 권장된다.


adb로 퍼미션 확인