IT 업계가 발전함에 따라 함께 주목 받고 민감하게 다루어지는 것이 개인 정보, 데이터 등인데요. 안드로이드 뿐만 아니라 iOS도 마찬가지로, 스마트폰 유저의 프라이버시를 보호하기 위해 권한에 대한 정책을 강화하고 있습니다.
안드로이드 앱은 유저의 민감한 정보에 접근하거나 카메라나 인터넷 등 시스템 기능을 다루기 위해서는 반드시 권한을 요청해야 합니다.
안드로이드에서는 보안을 위해 앱마다 권한을 별도로 관리하고 있기 때문에 어떤 한 유저가 A 라는 앱에 대해 카메라 사용 권한을 허용했더라도, B 앱에서 권한을 거부한다면 B 앱에서는 카메라 기능을 사용할 수 없게 됩니다.
이번 포스팅에서는 권한에 대해 개념만 잡고, 실질적인 권한 요청 코드(런타임 요청)에 대해서는 별도 포스팅으로 소개하도록 하겠습니다.
Manifest 에서 권한 설정
권한 설정에 대하여 가장 기본적인 방법은 매니페스트 파일에 선언하는 것입니다. (이전 글 - 매니페스트 개념 잡기)
예를 들어, 앱에서 인터넷에 대해 사용하는 것을 허용하기 위해서는 매니페스트 파일 내에 <uses-permission> 을 통해 다음과 같이 선언하면 됩니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.snazzyapp">
<uses-permission android:name="android.permission.INTERNET"/>
<application ...>
...
</application>
</manifest>
만약 유저의 프라이버시나 디바이스 기능 중 민감하지 않은 normal 권한이라면 매니페스트에 선언하는 것만으로도 시스템이 자동으로 권한을 승인합니다.
하지만 유저의 민감 정보나 SMS 전송 등과 같이 민감한 디바이스 기능에 대한 권한에 대해서는 시스템이 자동으로 권한을 부여해주지 않고 명시적으로 유저의 승인을 받아야만 권한이 부여됩니다.
안드로이드는 권한을 이렇게 권한에 대해 normal permission 과 dangerous permission 으로 구분한다는 것을 기억하시면 좋을 것 같습니다.
위험 권한(Dangerous Permission) 요청하기
앞서 위험 권한은 시스템에서 자동으로 승인해주지 않고, 유저의 승인이 있어야만 권한을 받을 수 있다고 말씀 드렸습니다. 여기서 주의할 부분이 있는데요. 안드로이드 6.0 (API 23 버전) 이전/이후로 그 방식이 나뉩니다. (안드로이드 파편화 문제가 어서 해결 되었으면 하는 간절함이...)
앱 설치시에 권한 요청(Install-time request) - API 23 버전 미만
예전부터 안드로이드 폰을 사용해오신 유저분이라면 아마 기억하실 수도 있는데요. 안드로이드 롤리팝 버전까지만 해도 앱 실행 단계가 아닌 설치 단계에서 앱에서 사용되는 권한을 미리 고지 받아 승인할 수 있었습니다.
이러한 방식은 각 권한에 대해 개별적으로 승인을 하는 것이 아니라 일괄적으로 요청되고 승인 되었기 때문에, 일부 권한은 승인하되 일부 권한에 대해 거절하고 싶더라도 그것이 불가능 했었습니다. 심지어 권한 승인을 거절할 경우 앱 설치조차 할 수 없었습니다.
앱 실행 단계에서 권한 요청(Runtime request) - API 23 버전 이상
스마트폰 기기가 API Level 23 버전 이상이고, 앱의 targetSdkVersion 이 23 버전 이상일 경우 유저는 앱 설치 단계에서 권한에 대한 고지를 받지 않습니다. 앱을 설치한 후에서야 권한에 대해 승인 요청을 받게 되는데요. 이때 앞서 23 버전 미만과는 다르게, 권한에 대해 일괄 승인 받지 않고 개별 승인을 받으며 권한을 거부하더라도 해당 기능만 사용하지 않는 기능에 대해서는 앱을 사용할 수 있습니다.
그렇기 때문에 개발자는 권한을 거절 당했더라도 앱이 크래쉬가 발생하지 않도록 신경 써서 앱을 개발해야 합니다.
요청하는 권한이 앱에 필수적인 기능일 경우(예를 들어 카메라 필터 앱이 카메라 권한을 요청하는 경우)에는 해당 권한이 없으면 정상적인 기능 제공이 불가능하니, 해당 권한의 중요성에 대해 권한 요청 전에 별도의 화면이나 다이얼로그를 통해 유저에게 권한의 중요성과 해당 권한이 거절 당했을 경우에 앱을 정상적으로 사용할 수 없다는 것을 고지하는 것이 좋습니다.
하드웨어 기능에 대한 권한
앞서 말씀드린 것과 같이 권한은 유저의 프라이버시 뿐만 아니라 하드웨어의 특정 기능을 사용하기 위해서도 승인 받을 필요가 있는데요. 세상에는 많은 안드로이드 기반의 기기가 존재하고, 그중에는 앱이 필요로 하는 하드웨어 기능이 없는 기기가 있을 수 있습니다. 예를 들어 블루투스 기반의 앱을 만들었는데, 블루투스를 지원하지 않는 스마트폰이 있을 수 있는거죠.
이 경우에는 매니페스트 파일에서 <uses-feature> 속성을 통해 어느정도 해소할 수 있습니다.
<uses-feature android:name="android.hardware.camera" android:required="false" />
매니페스트 파일에서 위와 같이 선언할 수 있는데요. 만약 android:required="true" 로 설정할 경우 camera 가 없는 기기에서는 플레이 스토어를 통해 해당 앱을 설치할 수 없게 됩니다.
그리고 예시와 같이 android:required="false" 로 설정할 경우 카메라가 없더라도 설치는 할 수 있는데요. 이 경우에는 권한 요청 전에 PackageManager.hasSystemFeature() 함수를 통해 시스템 기능을 지원하는지 확인 후에 권한을 요청할 수 있습니다.
권한 자동 조정
안드로이드는 1년에 최소 1개 이상의 버전을 출시하면서 많은 변화가 누적되어 왔는데요. 만약에 이전 버전에 없던 권한이 새로운 버전에서 추가된다면 어떻게 대응해야 할까요? 다행스럽게도 이 경우에는 시스템이 자동으로 권한을 조정해줍니다.
예를 들어, 외부 저장소 접근에 대해서 안드로이드 API 18 버전까지는 별도로 권한이 필요 없다가 19버전부터는 READ_EXTERNAL_STORAGE 권한이 생겨 해당 권한이 있어야만 저장소에 대한 접근이 가능해졌습니다.
Android 는 targetSdkVersion 에 따라 앱에 권한이 필요한지 확인하기 때문에, 앱의 targetSdkVersion 이 권한이 추가된 sdk version 보다 낮을 경우 시스템이 자동으로 앱에 권한을 추가해줍니다.
'Android > Basic' 카테고리의 다른 글
[Android] 사용자의 활동 상태(걷기, 자전거, 자동차 등)를 알려주는 Activity Recognition Transition API (1) | 2021.03.26 |
---|---|
[Android] MVVM 패턴에서 이벤트 처리하기 (0) | 2020.09.21 |
[Android] Manifest 개념 잡기 (0) | 2020.08.05 |
[Android] Fragment에서 Back Press 처리하기(with. OnBackPressedDispatcher) (3) | 2020.05.13 |
[Android] 안드로이드의 Touch Event 는 어떻게 전달 될까? (with. Touch Intercept) (3) | 2020.05.09 |