1. 환영합니다
소개
앱 권한을 사용하면 앱의 샌드박스에서 제공하는 것 이상의 데이터와 기능에 액세스할 수 있습니다. 앱 권한은 인터넷과 기기 위치, 카메라 등에 액세스하도록 허용하여 앱의 기능을 개선할 수 있습니다.
이러한 기능을 사용하려면 사용자에게 권한을 요청해야 합니다. 이 Codelab에서는 런타임 권한을 추가하고 권한이 부여되었는지 확인하는 데 필요한 단계를 설명합니다.
필요한 항목
- 최신 버전의 Android 스튜디오
기본 요건
- Kotlin 부트캠프에서 알아본 Kotlin 지식
- Kotlin을 사용하여 Android 앱 개발에서 알아본 기본 Android 개발 기술
학습할 내용
- Android 매니페스트에 권한을 추가하는 방법
- 권한 요청 방법
- 권한이 허용될 때와 거부될 때 처리하는 방법
- 권한이 부여되었는지 확인하는 방법
빌드할 항목
카메라 권한을 요청하는 앱을 만듭니다. 앱의 권한 부분은 구현하지만, 카메라 부분은 구현하지 않습니다.
2. Android 스튜디오 프로젝트 만들기
- 새 Android 스튜디오 프로젝트를 시작합니다.
- Empty Activity를 선택합니다.
- 프로젝트 이름을 Permissions Codelab으로 지정하고 언어를 Kotlin으로 설정합니다.
3. 코드 설정
- 다음 종속 항목의 최신 버전을 앱 수준의
build.gradle
파일에 추가합니다. 이렇게 하면 Codelab의 뒷부분에서 다루는Activity
라이브러리를 사용할 수 있습니다.
implementation "androidx.activity:activity-ktx:1.2.2"
implementation "androidx.fragment:fragment-ktx:1.3.2"
- Android 블록에서
viewBinding
빌드 옵션을 true로 설정하여 ViewBinding을 사용 설정합니다.
android {
...
buildFeatures {
viewBinding true
}
}
- 그런 다음, 녹색 망치 모양 버튼을 눌러 빌드합니다. 이렇게 하면 나중에
ViewBinding
에 사용할ActivityMainBinding
이라는 결합 클래스가 생성됩니다.
activity_main.xml
파일로 이동하여 코드를 아래 코드로 대체합니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Request Permissions"
android:onClick="onClickRequestPermission"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 다음 문자열을
strings.xml
파일에 추가합니다.
<string name="app_name">Permissions Codelab</string>
<string name="permission_required">Camera access is required to display the camera preview.</string>
<string name="ok">OK</string>
<string name="permission_granted">Permission is granted. You can use the camera now.</string>
MainActivity.kt
에서onCreate()
메서드 위에 레이아웃 및ViewBinding
을 위한 변수를 정의합니다.
private lateinit var layout: View
private lateinit var binding: ActivityMainBinding
onCreate()
메서드의 코드를 아래 코드로 교체합니다. 이 코드는 결합을 초기화하고 뷰를 나타내는val
을 만들어서 바인딩의 루트로 설정하고 레이아웃을 바인딩의mainLayout
으로 설정합니다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
layout = binding.mainLayout
setContentView(view)
}
- 파일 하단의
MainActivity
클래스 아래에 Codelab 전체에 스낵바를 표시하는 확장 함수를 추가합니다.
fun View.showSnackbar(
view: View,
msg: String,
length: Int,
actionMessage: CharSequence?,
action: (View) -> Unit
) {
val snackbar = Snackbar.make(view, msg, length)
if (actionMessage != null) {
snackbar.setAction(actionMessage) {
action(this)
}.show()
} else {
snackbar.show()
}
}
4. 매니페스트에 권한 추가
가장 먼저 해야 할 일은 <uses-permission>
태그를 사용하여 Android manifest
에서 권한이 사용된다고 선언하는 것입니다.
요청하는 권한에는 다른 요구사항이 있는 경우도 있습니다. 이 경우 기기에 카메라가 있어야 카메라 앱을 사용할 수 있습니다. 따라서 <uses-feature>
태그도 매니페스트에 추가합니다.
AndroidManifest.xml
파일의<application>
태그 위에 카메라 권한을 추가합니다.
<uses-permission android:name="android.permission.CAMERA" />
5. 권한 런처 만들기
requestPermissionLauncher
라는 val
을 만들고 이 코드를 MainActivity.kt
에 복사합니다. 다음 글머리 기호 몇 개는 여기에 있는 내용을 분석합니다.
private val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
Log.i("Permission: ", "Granted")
} else {
Log.i("Permission: ", "Denied")
}
}
requestPermissionLauncher
를registerForActivityResult
와 같게 설정하고ActivityResultContracts.RequestPermission()
을 전달합니다.
private val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission())
- 부여 여부를 처리하는 콜백을 추가합니다. 여기에서는 결과를 기록합니다.
{ isGranted: Boolean ->
if (isGranted) {
Log.i("Permission: ", "Granted")
} else {
Log.i("Permission: ", "Denied")
}
}
6. 권한 요청
onClickRequestPermission(view: View)
라는 함수를 만들고 이 코드를 함수에 복사합니다. 다음 글머리 기호 몇 개에서 안에 담긴 내용을 분석합니다.
fun onClickRequestPermission(view: View) {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
layout.showSnackbar(
view,
getString(R.string.permission_granted),
Snackbar.LENGTH_INDEFINITE,
null
) {}
}
ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.CAMERA
) -> {
layout.showSnackbar(
view,
getString(R.string.permission_required),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
else -> {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
}
when
문을 설정하여 다음 세 가지 경우를 다룹니다. 권한이 이미 부여된 경우, 앱에서 요청 권한 근거를 표시해야 한다고 판단하는 경우, 아직 요청하지 않은 경우
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
}
ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.CAMERA
) -> {
}
else -> {
}
}
- 권한이 부여된 경우 이를 알리는 스낵바를 표시합니다.
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
layout.showSnackbar(
view,
getString(R.string.permission_granted),
Snackbar.LENGTH_INDEFINITE,
null
) {}
}
shouldShowRequestPermissionRationale()
이 true를 반환하면 기능에 특정 권한이 필요한 이유를 자세히 설명하고 사용자에게 UI에서 권한을 수락/거부하는 방법을 제공하는 UI를 표시합니다.
ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.CAMERA
) -> {
layout.showSnackbar(
view,
getString(R.string.permission_required),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
- 그 외의 경우에는 권한을 요청합니다.
else -> {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
7. 요약
모든 작업이 완료되었습니다. 이 Codelab은 런타임 권한을 추가하는 방법을 보여주며 위치, 네트워크, 미디어 등과 관련된 권한에 사용할 수 있습니다.