-
[Android Kotlin] Permission에 대해서 정리해보기Framework/Android 2022. 4. 17. 22:39반응형
Android Permission이란?
안드로이드 마시멜로(Android API23) 이후에 출시된 안드로이드는 스마트폰 보안 정책을 강화하기 위해 핸드폰안에 권한을 설정하여 설정된 권한을
부여한 것만 가져다 사용할 수 있도록 변경 되었다.
Android Permission 워크 플로우
워크 플로우란? 개발자에게UI/UX및 Permission관련 로직을 제공해주기 위해 설계된 플로우이다. 위에 내용을 해석해 보면 아래와 같이 표현 할 수 있다. 이것을 바탕으로 시나리오를 작성해보자.
- 1 - Manifest에 필요한 Permission 내용 선언
- 2~3 - 필요한 Permission에 맞게 앱 디자인 설계(Permission허락 관련)
- 4 - Permission이미 허락 되었는지 아닌지 확인
- 5~6 아니라면 Permission관련 내용 해석하여 알려주고 Permission 허락 요청 아니라면 재요청
- 7~8 이미 Permission허락 된 경우 권한사용하여 내용(저장소, 카메라등) 접근하여 사용
권한과 관련된 시나리오
- 최초로 권한을 요청하는 경우
- 거절당한 권한을 다시 요청하는 경우
- 거절과 동시에 해당 권한요청을 다시 표시하지 않음 옵션을 선택한 경우
Permission 작성 순서
- Manifest에 Permission관련 내용 삽입
- 소스에서 SelfCheckPermission(권한 있는지 파악)하는 로직 구현
- 소스에서 관련 내용 가져와 Permission request(권한 수락 요청) 만들기
- 권한 없으면 재요청 하는 로직 만들기
Manifest에 Permission관련 내용 삽입
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.permissionkt"> <!--추가한 부분--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/> <!-- 28 이상은 쓰기 권한 을 받을 필요가 없다--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-feature android:name="android.hardware.camera" android:required="true"/> <!----> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.PermissionKt"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
소스에서 SelfCheckPermission(권한 있는지 파악)하는 로직 구현
//권한 등록되어있는지 체크 private fun selfCheckPermission() { //위치 기반 권한 체크 isAccessCoarseLocationPermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED isLocationPermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED //저장소 일기 권한 체크 isReadPermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED //저장소 쓰기 권한 체크 val isWritePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED val minSdkLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q //쓰기 권한은 28이후에 나왔으므로 isWritePermissionGranted = isWritePermission || minSdkLevel //오디오 isRecordAudioPermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO ) == PackageManager.PERMISSION_GRANTED }
소스에서 관련 내용 가져와 Permission request(권한 수락 요청) 만들기
//권한 없는것 요청 private fun requestPermission() { val permissionRequest : MutableList<String> = ArrayList() if(!isAccessCoarseLocationPermissionGranted){ permissionRequest.add(Manifest.permission.ACCESS_COARSE_LOCATION) } if(!isLocationPermissionGranted) { permissionRequest.add(Manifest.permission.ACCESS_FINE_LOCATION) } if(!isReadPermissionGranted) { permissionRequest.add(Manifest.permission.READ_EXTERNAL_STORAGE) } if(!isWritePermissionGranted) { permissionRequest.add(Manifest.permission.WRITE_EXTERNAL_STORAGE) } if(!isRecordAudioPermissionGranted) { permissionRequest.add(Manifest.permission.RECORD_AUDIO) } //없는 권한 ArrayList로 만들어 Launch로 MultiPermission열기 if(permissionRequest.isNotEmpty()){permissionLauncher.launch(permissionRequest.toTypedArray())} }
권한 없으면 재요청 하는 로직 만들기
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){ permissions -> isAccessCoarseLocationPermissionGranted = permissions[Manifest.permission.ACCESS_COARSE_LOCATION] ?: isAccessCoarseLocationPermissionGranted isReadPermissionGranted = permissions[Manifest.permission.ACCESS_FINE_LOCATION] ?: isReadPermissionGranted isWritePermissionGranted = permissions[Manifest.permission.READ_EXTERNAL_STORAGE] ?: isWritePermissionGranted isLocationPermissionGranted = permissions[Manifest.permission.WRITE_EXTERNAL_STORAGE] ?: isLocationPermissionGranted isRecordAudioPermissionGranted = permissions[Manifest.permission.RECORD_AUDIO] ?: isRecordAudioPermissionGranted //자리에 맞게 재요청 할 내용 Toast표시 및 requestPermission다시 보내기 등 하면 되는 자리 //if문으로 권한 재요청 할 것 작성하면 됨. } selfCheckPermission() requestPermission() }
전체 소스
package com.example.permissionkt import android.Manifest import android.content.pm.PackageManager import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContract import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat class MainActivity : AppCompatActivity() { private lateinit var permissionLauncher : ActivityResultLauncher<Array<String>> private var isAccessCoarseLocationPermissionGranted = false private var isReadPermissionGranted = false private var isWritePermissionGranted = false private var isLocationPermissionGranted = false private var isRecordAudioPermissionGranted = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){ permissions -> isAccessCoarseLocationPermissionGranted = permissions[Manifest.permission.ACCESS_COARSE_LOCATION] ?: isAccessCoarseLocationPermissionGranted isReadPermissionGranted = permissions[Manifest.permission.ACCESS_FINE_LOCATION] ?: isReadPermissionGranted isWritePermissionGranted = permissions[Manifest.permission.READ_EXTERNAL_STORAGE] ?: isWritePermissionGranted isLocationPermissionGranted = permissions[Manifest.permission.WRITE_EXTERNAL_STORAGE] ?: isLocationPermissionGranted isRecordAudioPermissionGranted = permissions[Manifest.permission.RECORD_AUDIO] ?: isRecordAudioPermissionGranted //자리에 맞게 재요청 할 내용 Toast표시 및 requestPermission다시 보내기 등 하면 되는 자리 } selfCheckPermission() requestPermission() } //권한 없는것 요청 private fun requestPermission() { val permissionRequest : MutableList<String> = ArrayList() if(!isAccessCoarseLocationPermissionGranted){ permissionRequest.add(Manifest.permission.ACCESS_COARSE_LOCATION) } if(!isLocationPermissionGranted) { permissionRequest.add(Manifest.permission.ACCESS_FINE_LOCATION) } if(!isReadPermissionGranted) { permissionRequest.add(Manifest.permission.READ_EXTERNAL_STORAGE) } if(!isWritePermissionGranted) { permissionRequest.add(Manifest.permission.WRITE_EXTERNAL_STORAGE) } if(!isRecordAudioPermissionGranted) { permissionRequest.add(Manifest.permission.RECORD_AUDIO) } //없는 권한 ArrayList로 만들어 Launch로 MultiPermission열기 if(permissionRequest.isNotEmpty()){permissionLauncher.launch(permissionRequest.toTypedArray())} } //권한 등록되어있는지 체크 private fun selfCheckPermission() { //위치 기반 권한 체크 isAccessCoarseLocationPermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED isLocationPermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED //저장소 일기 권한 체크 isReadPermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED //저장소 쓰기 권한 체크 val isWritePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED val minSdkLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q //쓰기 권한은 28이후에 나왔으므로 isWritePermissionGranted = isWritePermission || minSdkLevel //오디오 isRecordAudioPermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO ) == PackageManager.PERMISSION_GRANTED } }
반응형'Framework > Android' 카테고리의 다른 글
[Android Kotlin] MVVM 패턴 이해하기 (0) 2022.04.13 [Android Kotlin] 프로젝트 생성 시 기본 폴더 구조 및 내용 요약 (0) 2022.04.12