[Android Study] 퍼미션 설정하기

728x90
반응형

* 퍼미션(permission)이란 앱의 특정 기능에 부여하는 접근 권한을 의미한다. 개발하는 앱이 다른 앱이나 안드로이드 시스템에서 보호하는 특정 기능을 이용할 때 퍼미션 사용을 설정해야 한다. 

  - 예를 들어, A앱의 개발자가 manifest 파일에 <permission> 태그로 퍼미션을 설정하면 이를 이용하는 B 앱의 코드를 아무리 잘 구현하더라도 실행되지 않는다. 해당 퍼미션을 사용하려면 B앱의 manifest에 <uses-permission> 태그로 해당 퍼미션을 사용하겠다고 설정해 줘야 한다.

 

* manifest 파일에 퍼미션을 설정할 때는 <permission> 태그와 다음 속성을 이용한다.

  • name: 퍼미션 이름, 퍼미션을 구별하는 식별자 역할을 한다.
  • label, description: 퍼미션 설명, 퍼미션을 이용하는 외부 앱에서 권한 인증 화면에 출력할 퍼미션의 정보이다.
  • protectionLevel: 보호 수준
    • normal: 낮은 수준의 보호, 사용자에게 권한 허용 요청을 하지 않아도 됨.
    • dangerous: 높은 수준의 보호, 사용자에게 권한 허용을 요청해야 함.
    • signature: 같은 키로 인증한 앱만 실행.
    • signatureOrSystem: 안드로이드 시스템 앱이거나 같은 키로 인증한 앱만 실행.

* manifest 파일에 <permission>을 설정했다고 해서 바로 컴포넌트가 보호되지는 않는다. <permission>을 설정한 다음 이 퍼미션으로 보호하려는 컴포넌트에 적용해야 한다. 이 때는 android:permission 속성을 이용한다.

<activity android:name=".OneActivity" android:permission="com.example.TEST_PERMISSION">
    <intent-filter>
    	<action android:name= ~~~~ />
    </intent-filter>
</activity>

 - 이제 이 컴포넌트는 com.example.TEST_PERMISSION에 의해 보호되며 이 컴포넌트를 이용하는 곳에서는 manifest 파일에 다음과 같이 선언해 줘야 정상으로 실행된다.

<uses-permission android:name="com.example.TEST_PERMISSION" />

 

 

* 퍼미션 허용 확인

- API 레벨 23 이전에는 개발자가 manifest파일에 <uses-permission>으로 선언만 하면 보호받는 기능을 앱에서 이용할 수 있었다. 즉, 선언만 하면 되는 일종의 신고제였다. 하지만 23버전부터 허가제로 변경되었다. 이제는 개발자가 <uses-permission>으로 선언했더라도 사용자가 권한 화면에서 이를 거부할 수 있게 되었다. 따라서 앱을 실행할 때 사용자가 퍼미션을 거부했는지 확인하고 다시 퍼미션을 허용해달라고 요청을 해야 한다. 사용자가 퍼미션을 허용했는지 확인하려면 checkSelfPermission() 함수를 이용한다.

open static fun checkSelfPermission(
    @NonNull context: Context,
    @NonNull permission: String
): Int

 - 여기서 두번째 매개변수가 퍼미션을 구분하는 이름이며 결과값은 다음 중 하나의 상수로 전달된다.

  • PackageManager.PERMISSION_GRANTED: 권한을 허용한 경우
  • PackageManager.PERMISSION_DENIED: 권한을 거부한 경우
val status = ContextCompat.checkSelfPermission(this, "android.permission.ACCESS_FINE_LOCATION")

if (status == PackageManager.PERMISSION_GRANTED) {
	Log.d("permission 승인")
} else {
	Log.d("permission 거부")
}

 

- 사용자에게 퍼미션 허용을 요청할 때는 ActivityResultLauncher를 이용한다. 이 클래스는 액티비티에서 결과를 돌려받아야 할 때 사용하며 대표적으로 퍼미션 허용 요청과 다른 액티비티를 실행하고 결과를 돌려받을 때이다. ActivityResultLauncher 객체는 registerForActivityResult() 함수를 호출해서 만든다.

// registerForActivityResult() 함수
public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
    @NonNull ActivityResultContract<I, O> contract,
    @NonNull ActivityResultCallback<O> callback
)

- registerForActivityResult() 함수는 매개변수가 2개이다. 첫 번째는 어떤 요청인지를 나타내는 ActivityResultContract 타입 객체이며 다양한 요청에 대응하는 서브 클래스들이 있다. 대표적으로 다른 액티비티를 실행하고 결과를 돌려받을 떄는 StartActivityForResult, 퍼미션 허용을 요청할 때는 RequestPermission을 이용한다.

- 그리고 두 번째 매개변수는 결과를 받았을 때 호출되는 콜백이다. 

 

* 최종적으로 registerForActivityResult() 함수로 ActivityResultLauncher 객체를 만들었다면 필요한 곳에서 ActivityResultLauncher 객체의 launch() 함수를 호출하여 요청을 실행한다.

requestPermissionLauncher.launch("android.permission.ACCESS_FINE_LOCATION")

- 요청 결과는 registerForActivityResult() 함수의 두 번째 매개변수로 등록한 콜백으로 전달된다.

728x90
반응형
TAGS.

Comments