앱에서 어떤 퍼미션을 사용하려면 AndroidManifest.xml
에서 <use-permission ../>
으로 정의할 수 있습니다.
<uses-permission android:name="android.permission.INTERNET"/>
여기서 사용되는 "android.permission.INTERNET"
와 같은 퍼미션은 안드로이드에서 정의한 것입니다.
만약 내가 만든 앱들만 사용할 수 있는 퍼미션을 만들고 싶다면 어떻게해야할까요?
누구나 커스텀 퍼미션을 정의할 수 있고 내 앱만 사용할 수 있도록 만들 수 있습니다. 물론 이렇게 제한을 두지 않고, 퍼미션 이름만 알면 누구나 사용할 수 있도록 만들수도 있습니다.
이 글에서는 커스텀 퍼미션(Custom permission)을 정의하는 방법을 소개하고, 각각의 설정이 무엇을 의미하는지 알아보겠습니다.
커스텀 퍼미션 정의
커스텀 퍼미션은 앱의 AndroidManifest.xml
에 정의할 수 있습니다.
다음과 같이 manifest
속성 아래에 <permission />
을 정의하면 됩니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codechacha.custompermission">
<permission
android:name="com.codechacha.YOU_CAN_DO_SOMETHING"
android:label="@string/perm_label"
android:description="@string/perm_description"
android:permissionGroup="android.permission-group.SMS"
android:protectionLevel="normal" />
...
</manifest>
문자열은 /res/values/strings.xml
에 추가하시면 됩니다.
<resources>
<string name="perm_label">Do Something</string>
<string name="perm_description">You can do what you need to do</string>
</resources>
위의 코드에서 사용된 속성은 다음과 같은 역할을 합니다.
android:name
: 퍼미션의 이름입니다. 다른 앱에서으로 내 퍼미션을 선언할 때, 이 이름을 사용해야 합니다. android:label
: 퍼미션 이름으로, Settings 앱에서 Label을 화면에 보여줄 수 있습니다.android:description
: 퍼미션에 대한 설명이며, Settings 앱에서 description 정보를 사용하여 화면에 보여줄 수 있습니다.android:permissionGroup
: 퍼미션의 그룹입니다. 그룹도 만들 수 있지만 보통 안드로이드에서 정의한 그룹을 사용합니다. (Android 10에서 일부 퍼미션은 그룹을 정의하지 않도록 변경되었습니다.)android:protectionLevel
: 퍼미션을 부여하는 정책입니다. 정책에 따라서 일부 앱만 퍼미션을 얻을 수도 있습니다. 또한 설치할 때 퍼미션을 획득할 지, 런타임에 획득할지 정할 수 있습니다.
protectionLevel에 사용되는 값은 다음과 같습니다.
normal
: use-permission에 내 퍼미션을 정의하면, 이 앱이 설치될 때 자동으로 퍼미션이 부여됩니다.dangerous
: 앱이 설치될 때 퍼미션이 부여되지 않습니다. 사용자에게 권한을 요청하고, 허락하면 권한이 부여됩니다.signature
: 퍼미션이 정의된 앱과 동일한 key로 서명된 앱에게만 퍼미션이 부여됩니다.
이름이 동일한 퍼미션을 여러 앱에서 선언할 수 있습니다. 하지만 디바이스에 먼저 설치되는 앱이 퍼미션의 owner가 됩니다.
그렇기 때문에 다른 앱들과 충돌을 피하려면 특별한 퍼미션 이름을 지정하는 것이 좋습니다.
만약 내 앱들이 모두 동일한 인증서로 서명이 되었다면, 각각의 앱에서 동일한 이름의 퍼미션을 선언해도 문제 없습니다.
디바이스에서 내 퍼미션 확인
위와 같이 퍼미션을 정의했다면 앱을 설치해보세요.
설치 후 터미널에 다음과 같은 명령어를 입력하면 내 앱의 정보가 출력됩니다.
$ adb shell dumpsys package [package name]
출력되는 정보 중에, 다음과 같이 com.codechacha.YOU_CAN_DO_SOMETHING
퍼미션은 내 앱에서 선언했다고(sourcePackage) 나옵니다.
sourcePackage는 퍼미션의 Owner를 의미합니다.
$ adb shell dumpsys package com.codechacha.custompermission
....
Permissions:
Permission [com.codechacha.YOU_CAN_DO_SOMETHING] (4449a84):
sourcePackage=com.codechacha.custompermission
uid=10149 gids=null type=0 prot=normal
perm=Permission{e62326d com.codechacha.YOU_CAN_DO_SOMETHING}
packageSetting=PackageSetting{87adea2 com.codechacha.custompermission/10149}
Packages:
Package [com.codechacha.custompermission] (87adea2):
userId=10149
pkg=Package{f725733 com.codechacha.custompermission}
codePath=/data/app/com.codechacha.custompermission-ehtFwFZRAWvVEW-o6kecbg==
...
adb의 dumpsys
명령어는 익숙하지 않지만, 퍼미션의 Owner가 누구인지 확인하는데 도움이 됩니다.
다른 앱에서 퍼미션 등록
지금까지 커스텀 퍼미션을 만들어보았습니다. 이제 다른 앱을 만들고 이 퍼미션을 사용하도록 manifest를 설정해보겠습니다.
다음과 같이 다른 앱의 AndroidManifest.xml
에 uses-permission
으로 내 퍼미션을 추가해주세요.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codechacha.myapplication">
<uses-permission android:name="com.codechacha.YOU_CAN_DO_SOMETHING" />
...
</manifest>
그리고 앱을 설치해보세요.
위에서 사용한 명령어로, 새로운 앱에 대한 정보를 보면 install permissions:
아래에 퍼미션이 추가된 것을 볼 수 있습니다.
granted=true
라면 내 앱이 이 권한을 얻었다는 것을 의미입니다. granted=false
는 권한이 부여되지 않았다는 의미입니다.
$ adb shell dumpsys package com.codechacha.myapplication
....
Packages:
Package [com.codechacha.myapplication] (acce3eb):
userId=10150
pkg=Package{970d548 com.codechacha.myapplication}
codePath=/data/app/com.codechacha.myapplication-3WkQtOk9G9Y1uRgiirMopw==
....
requested permissions:
com.codechacha.YOU_CAN_DO_SOMETHING
install permissions:
com.codechacha.YOU_CAN_DO_SOMETHING: granted=true
User 0: ceDataInode=-4294930485 installed=true hidden=false suspended=false stopped=false notLaunched=false enabled=0 instant=false virtual=false
overlay paths:
/product/overlay/DisplayCutoutEmulationEmu01/DisplayCutoutEmulationEmu01Overlay.apk
runtime permissions:
퍼미션 com.codechacha.YOU_CAN_DO_SOMETHING
는 protectionLevel이 normal이기 때문에 설치와 동시에 권한이 부여되었습니다.
만약 protectionLevel이 signature라면 퍼미션을 제공하는 앱과 동일한 key로 서명된 앱만 권한을 받을 수 있습니다.
com.codechacha.YOU_CAN_DO_SOMETHING 퍼미션의 protectionLevel은 normal입니다. 그렇기 때문에 install permission으로 분류가 됩니다.
만약 dangerous라면 runtime permission으로 분류가 됩니다.
SDK API로 앱이 어떤 퍼미션을 갖고 있는지 확인할 수 있습니다. 하지만 위에서 소개한 adb 명령어를 사용하면 쉽게 디버깅할 수 있습니다.
정리
지금까지 커스텀 퍼미션을 정의하는 방법에 대해서 알아보았습니다. protectionLevel의 설정에 대해서만 알고 계시면 자신이 원하는 퍼미션을 만드는데 어려움은 없을 것입니다.
사실 안드로이드에서 제공하는 퍼미션은 더 많은 옵션이 있고, 더 복잡합니다. 하지만 커스텀 퍼미션은 안드로이드처럼 복잡하게 사용할 필요는 없기 때문에 이정도만 알아두시면 될 것 같습니다.
참고
Related Posts
- Android 14 - 사진/동영상 파일, 일부 접근 권한 소개
- Android - adb push, pull로 파일 복사, 다운로드
- Android 14 - 암시적 인텐트 변경사항 및 문제 해결
- Jetpack Compose - Row와 Column
- Android 13, AOSP 오픈소스 다운로드 및 빌드
- Android 13 - 세분화된 미디어 파일 권한
- Android 13에서 Notification 권한 요청, 알림 띄우기
- Android 13에서 'Access blocked: ComponentInfo' 에러 해결
- 에러 해결: android gradle plugin requires java 11 to run. you are currently using java 1.8.
- 안드로이드 - 코루틴과 Retrofit으로 비동기 통신 예제
- 안드로이드 - 코루틴으로 URL 이미지 불러오기
- Android - 진동, Vibrator, VibrationEffect 예제
- Some problems were found with the configuration of task 에러 수정
- Query method parameters should either be a type that can be converted into a database column or a List
- 우분투에서 Android 12 오픈소스 다운로드 및 빌드
- Android - ViewModel을 생성하는 방법
- Android - Transformations.map(), switchMap() 차이점
- Android - Transformations.distinctUntilChanged() 소개
- Android - TabLayout 구현 방법 (+ ViewPager2)
- Android - 휴대폰 전화번호 가져오는 방법
- Android 12 - Splash Screens 알아보기
- Android 12 - Incremental Install (Play as you Download) 소개
- Android - adb 명령어로 bugreport 로그 파일 추출
- Android - adb 명령어로 App 데이터 삭제
- Android - adb 명령어로 앱 비활성화, 활성화
- Android - adb 명령어로 특정 패키지의 PID 찾기
- Android - adb 명령어로 퍼미션 Grant 또는 Revoke
- Android - adb 명령어로 apk 설치, 삭제
- Android - adb 명령어로 특정 패키지의 프로세스 종료
- Android - adb 명령어로 screen capture 저장
- Android - adb 명령어로 System 앱 삭제, 설치
- Android - adb 명령어로 settings value 확인, 변경
- Android 12 - IntentFilter의 exported 명시적 선언
- Android - adb 명령어로 공장초기화(Factory reset)
- Android - adb logcat 명령어로 로그 출력