728x90
이번 포스팅에서는 코틀린을 사용한 권한 요청 기능 사용법에 대해 정리하겠습니다.
코드는 아래의 스틱코드 포스팅을 참고해 주세요.
https://stickode.com/detail.html?no=2309
먼저 앱 수준 gradle 파일에 아래의 의존성들을 추가해줍니다.
implementation 'androidx.activity:activity-ktx:1.2.0-rc01'
implementation 'androidx.fragment:fragment-ktx:1.3.0-rc01'
둘 중 하나라도 빠뜨리게 되면 Can only use lower 16 bits for requestCode 런타임 에러가 나오게 됩니다.
그 다음 메인 액티비티의 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="선택해 주세요"
android:textSize="20sp"
app:layout_constraintVertical_bias="0.4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/launch_button_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="성인"
app:layout_constraintTop_toBottomOf="@id/text_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/launch_button_right"/>
<Button
android:id="@+id/launch_button_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="어린이"
app:layout_constraintTop_toBottomOf="@id/text_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/launch_button_left"/>
<Button
android:id="@+id/request_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="권한 요청"
app:layout_constraintTop_toBottomOf="@id/launch_button_left"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
다음으로 메인 액티비티 코틀린 소스입니다.
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity()
{
object Contracts : ActivityResultContract<Int, User?>()
{
override fun createIntent(context: Context, input: Int): Intent
{
val intent = Intent(context, SecondActivity::class.java)
intent.putExtra("select_id", input)
return intent
}
override fun parseResult(resultCode: Int, intent: Intent?): User?
{
if (resultCode == Activity.RESULT_OK)
{
return intent?.getParcelableExtra("result")
}
return null
}
}
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val simpleLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK)
{
val intent = result.data
val user = intent?.getParcelableExtra<User>("result")
?: return@registerForActivityResult
setResultText(user)
}
}
val customLauncher = registerForActivityResult(Contracts) { result ->
result ?: return@registerForActivityResult
setResultText(result)
}
val requestPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (it)
{
Toast.makeText(this, "권한이 허용되었습니다", Toast.LENGTH_SHORT).show()
}
else
{
Toast.makeText(this, "권한이 거부되었습니다", Toast.LENGTH_SHORT).show()
}
}
launch_button_left.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("select_id", User.Attribute.ADULT.id)
simpleLauncher.launch(intent)
}
launch_button_right.setOnClickListener {
customLauncher.launch(User.Attribute.CHILD.id)
}
request_button.setOnClickListener {
requestPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}
}
private fun setResultText(user: User)
{
val attr = User.Attribute.values()[user.attr].value
text_view.text = ("이름 : ${user.name}\n구분 : $attr")
}
}
그리고 User.kt 파일을 만들겠습니다. 이 파일은 권한을 요청한 사람이 성인인지 어린이인지에 따라 다른 문자를 보여줄 때 사용합니다.
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
data class User(val name: String, val attr: Int) : Parcelable
{
enum class Attribute(val id: Int, val res: Int, val value: String)
{
ADULT(0, R.id.adult, "성인"),
CHILD(1, R.id.child, "어린이")
}
}
다음은 메인 액티비티에서 '권한 요청' 버튼을 누르면 이동하는 화면을 만들겠습니다. 먼저 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<RadioGroup
android:id="@+id/which_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.4">
<RadioButton
android:id="@+id/adult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="성인" />
<RadioButton
android:id="@+id/child"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="어린이" />
</RadioGroup>
<EditText
android:id="@+id/edit_text"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="이름"
android:inputType="text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/which_group"
tools:ignore="Autofill" />
<Button
android:id="@+id/ok_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="OK"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/edit_text" />
</androidx.constraintlayout.widget.ConstraintLayout>
다음은 SecondActivity의 코틀린 코드입니다.
import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_second.*
class SecondActivity : AppCompatActivity()
{
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
val selectedId = intent.getIntExtra("select_id", 0)
val resId = User.Attribute.values()[selectedId].res
which_group.check(resId)
ok_button.setOnClickListener {
val user = User(edit_text.text.toString(), selectedId)
intent.putExtra("result", user)
setResult(Activity.RESULT_OK, intent)
finish()
}
}
}
마지막으로 위치 권한을 요청할 것이기 때문에 매니페스트에 아래 문장을 추가해줍니다.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
모든 코드를 입력하고 앱을 빌드하면 아래와 같은 화면을 볼 수 있습니다.
'안드로이드 코틀린' 카테고리의 다른 글
[Kotlin][Android] GIF ImageView에 넣기 (0) | 2021.08.17 |
---|---|
[Kotlin][Android] LiveData 사용 방법 (0) | 2021.08.11 |
[Kotlin][Android] 권한 요청 기능 만들기 (4) | 2021.08.03 |
[Kotlin][Android] 핸드폰 기기 단말 정보 가져오기 (0) | 2021.08.02 |
[Kotlin][Android] Room 으로 DB 저장하기 (0) | 2021.08.01 |