안드로이드 10) Permission

Concepts of Permission

1. Concepts of Permission

  • 두 애플리케이션이 있을 때 B App에서 A App의 컴포넌트에 접근하기 위해서는 암시적 인텐트 등의 방법을 사용해야 한다.
  • 이 때 특정 보안을 통과하는 애플리케이션과만 연동을 하고 싶다면 퍼미션 설정을 해주어야 한다.

  • 퍼미션 설정을 하기 위해서는 AndroidManifest 파일에서 permission 태그로 컴포넌트를 보호하면 된다.
  • permission 태그로 감싸져 있는 컴포넌트는 외부 애플리케이션에서 접근하려고 하면 에러가 난다.

  • 그럼 permission 태그로 감싸져 있는 컴포넌트에 접근하려면 어떻게 해야 하나?
  • 외부 애플리케이션의 AndroidManifest 파일에서 uses-permission 태그를 달아주어야 한다.

2. Permission을 적용하는 애플리케이션 코드(위의 예시에서 A App)

<permission android:name="com.example.permission.TEST_PERMISSION"
	android:label="Test Permission"
    android:description="@string/permission_des"
    android:protectionLevel="dangerous"/>
    
<activity
	android:name=".MainActivity"
    android:exported="true"
    android:permission="com.example.permission.TEST_PERMISSION"
</activity>

<activity
	android:name=".MainActivity"
    android:exported="true"
</activity>
  • <permission> : AndroidManifest.xml 파일 설정
    • name : permission의 이름
      • 접근하는 쪽 uses-permission에서 이 이름으로 설정해야 함
      • Manifest 파일에 permission을 등록하고, 해당 애플리케이션의 여러 컴포넌트 중 permission을 줄 컴포넌트에는 컴포넌트의 태그 내에 permission name을 작성해주어야 한다. (위 코드에 activity 코드들 참조)
    • label, description : permission에 대한 설명
    • protectionLevel : 보호 수준
      • normal : 낮은 수준의 보호, 유저에게 권한 부여 요청이 필요 없는 경우
      • dangerous : 높은 수준의 보호, 유저에게 권한 부여 요청이 필요한 경우
      • signature : 동일한 키로 사인된 앱만 실행
      • signatureOrSystem : 안드로이드 시스템 앱이거나 동일키로 사인된 앱만 실행

3. Permission을 이용하는 애플리케이션 코드(위의 예시에서 B App)

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  • <uses-permission> : AndroidManifest.xml 파일 설정
  • B App을 유저의 디바이스에 설치했을 때 B App의 환경설정의 권한 화면에서 B App이 어떤 퍼미션을 이용하는지가 유저에게 보여진다.
    • 이 때 보여지는 내용은 A App의 permission 태그에서 등록한 label이나 description 속성이 보여진다. (protectionLevel이 dangerous인 경우만)

4. 시스템에서 요구되는 퍼미션

  • 시스템에서 퍼미션으로 보호하는 기능들은 유저에게 민감한 기능들
    • ACCESS_FINE_LOCATION : 위치 정보 접근
    • ACCESS_NETWORK_STATE : 네트워크 정보 접근
    • ACCESS_WIFI_STATS : Wi-Fi 네트워크 정보 접근
    • BATTERY_STATS : 배터리 정보 접근
    • BLUETOOTH : 블루투스 장치에 연결
    • BLUETOOTH_ADMIN : 블루투스 장치를 검색하고 페어링
    • CAMERA : 카메라 장치에 접근
    • INTERNET : 네트워크 연결
    • READ_EXTERNAL_STORAGE : 외부 저장소에서 파일 읽기
    • WRITE_EXTERNAL_STORAGE : 외부 저장소에서 파일 쓰기
    • READ_PHONE_STATE : 전화기로서의 각종 정보 접근
    • SEND_SMS : SMS 발신
    • RECEIVE_SMS : SMS 수신
    • RECEIVE_BOOT_COMPLETED : 부팅 완료시 실행
    • VIBRATE : 진동 울리기

Permission Check, Request

1. Permission Check

  • API Level 23 이전 버전에서 퍼미션은 신고제(유저 입장에서 거부 불가)
  • API Level 23 버전부터 퍼미션은 허가제(유저 입장에서 거부 가능)
    • 퍼미션 허가 여부를 체크하는 코드를 작성해야 함
val status = ContextCompat.checkSelfPermission(this, "android.permission.ACCESS_FINE_LOCATION")
if(status == PackageManager.PERMISSION_GRANTED){
	Log.d("permission check", "permission granted")
    // 기능 실행
} else{
	Log.d("permission check", "permission granted")
    // 기능 실행 시키면 에러, 유저에게 퍼미션 부여 요청 → Permission Request
}
  • 퍼미션 체크는 checkSelfPermission() 함수 이용, 매개 변수에 퍼미션 이름(String)
  • 결과 값은 상수로 전달
    • PackageManager.PERMISSION_GRANTED : 퍼미션이 허락된 경우
    • PackageManager.PERMISSION_DENIED : 퍼미션이 거부된 경우

2. Permission Request
(1) requestPermissions() 사용

ActivityCompat.requestPermissions(this, arrayOf<String>("android.permission.ACCESS_FINE_LOCATION"), 100)
  • requestPermissions()를 사용하면 유저에게 퍼미션 부여를 요청하는 다이얼로그가 뜸(시스템에서 자체적으로 제공하는 다이얼로그)
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray){
    super.onRequestPermissionsResult(requestCode, permissions, grantResult)
    if(grantResult[0]==PackageManager.PERMISSION_GRANTED_{
    	Toast.makeText(this, "permission granted", Toast.LENGTH_SHORT).show()
    } else{
    	Toast.makeText(this, "permission granted", Toast.LENGTH_SHORT).show()
    }
}
  • 다이얼로그가 닫혔을 때 onRequestPermissionsResult() 함수가 바로 실행
  • 퍼미션 조정 여부를 확인해서 수락했다면 기능 실행, 거부했다면 다이얼로그로 거부했기 때문에 이 기능을 쓸 수 없다고 안내

(2) registerForActivityResult() 사용

  • Activity Request 결과값을 받기 위한 코드와 퍼미션의 결과값을 받기 위한 코드를 동일한 코드로 작성할 수 있음
requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
  • 유저에게 퍼미션 부여를 요청하는 다이얼로그가 뜸(시스템에서 자체적으로 제공하는 다이얼로그)
val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) {isGranted ->
    if(isGranted) {
    	Toast.makeText(this, "permission granted2", Toast.LENGTH_SHORT).show()
    } else {
    	Toast.makeText(this, "permission granted2", Toast.LENGTH_SHORT).show()
    }
}
  • 퍼미션 여부 확인 후 처리

좋은 웹페이지 즐겨찾기