728x90
안녕하세요. 이번시간에는 코틀린으로 카메라로 이미지를 받아와 이미지 뷰에 띄워주는 기능을 구현해보도록 하겠습니다.
개발 순서는 다음과 같습니다.
1. XML 파일 만들기
2. 권한 승인 요청하기
3. 권한 승인 시 카메라 실행
4. 카메라 실행후 결과 값을 받아 이미지뷰에 띄워주기.
1. XML 파일 만들기 (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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/buttonCamera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:text="카메라"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="@+id/imagePreview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/buttonCamera"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>
2. 권한 승인 요청하기
권한을 요청하기 전에 필요한 권한을 Manifest에 추가해주도록 합시다.
<uses-permission android:name="android.permission.CAMERA" />
카메라 버튼을 클릭했을 때 권한 요청을 하도록 아래와 같이 작성해줍시다.
// 카메라 버튼 클릭 리스너 구현
val cameraBtn = findViewById<Button>(R.id.buttonCamera) as Button
cameraBtn.setOnClickListener(View.OnClickListener {
requirePermissions(arrayOf(Manifest.permission.CAMERA), PERMISSION_CAMERA)
})
아래는 권한을 요청하는 코드입니다.
/**자식 액티비티에서 권한 요청 시 직접 호출하는 메서드
* @param permissions 권한 처리를 할 권한 목록
* @param requestCode 권한을 요청한 주체가 어떤 것인지 구분하기 위함.
* */
fun requirePermissions(permissions: Array<String>, requestCode: Int) {
Logger.d("권한 요청")
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
permissionGranted(requestCode)
} else {
// isAllPermissionsGranted : 권한이 모두 승인 되었는지 여부 저장
// all 메서드를 사용하면 배열 속에 들어 있는 모든 값을 체크할 수 있다.
val isAllPermissionsGranted =
permissions.all { checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED }
if (isAllPermissionsGranted) {
permissionGranted(requestCode)
} else {
// 사용자에 권한 승인 요청
ActivityCompat.requestPermissions(this, permissions, requestCode)
}
}
}
권한을 요청하고 나서 사용자 반응에 따라 처리해야하는 로직을 아래와 같이 작성해줍시다.
그리고 권한이 승인 되었을 때 카메라가 켜지도록 합시다.
/** 사용자가 권한을 승인하거나 거부한 다음에 호출되는 메서드
* @param requestCode 요청한 주체를 확인하는 코드
* @param permissions 요청한 권한 목록
* @param grantResults 권한 목록에 대한 승인/미승인 값, 권한 목록의 개수와 같은 수의 결괏값이 전달된다.
* */
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
permissionGranted(requestCode)
} else {
permissionDenied(requestCode)
}
}
private fun permissionGranted(requestCode: Int) {
when (requestCode) {
PERMISSION_CAMERA -> openCamera()
}
}
private fun permissionDenied(requestCode: Int) {
when (requestCode) {
PERMISSION_CAMERA -> Toast.makeText(
this,
"카메라 권한을 승인해야 카메라를 사용할 수 있습니다.",
Toast.LENGTH_LONG
).show()
}
}
카메라를 찍은 값을 Uri로 받기 위해 아래 와 같이 작성해줍니다.
private fun openCamera() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
createImageUri(newFileName(), "image/jpg")?.let { uri ->
realUri = uri
// MediaStore.EXTRA_OUTPUT을 Key로 하여 Uri를 넘겨주면
// 일반적인 Camera App은 이를 받아 내가 지정한 경로에 사진을 찍어서 저장시킨다.
intent.putExtra(MediaStore.EXTRA_OUTPUT, realUri)
startActivityForResult(intent, REQUEST_CAMERA)
}
}
private fun newFileName(): String {
val sdf = SimpleDateFormat("yyyyMMdd_HHmmss")
val filename = sdf.format(System.currentTimeMillis())
return "$filename.jpg"
}
private fun createImageUri(filename: String, mimeType: String): Uri? {
var values = ContentValues()
values.put(MediaStore.Images.Media.DISPLAY_NAME, filename)
values.put(MediaStore.Images.Media.MIME_TYPE, mimeType)
return this.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
}
카메라를 찍으면 다음과 같이 이미지를 Uri에 넣어주도록 합니다.
/** 카메라 및 앨범 Intent 결과
* */
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode) {
REQUEST_CAMERA -> {
realUri?.let { uri ->
imageView.setImageURI(uri)
}
}
}
}
}
그러면 결과는 다음과 같이 나오게 됩니다.
코드 중간에 나오는 Logger 라이브러리는 스틱코드를 참고하시면 가져다 쓸 수 있습니다.
https://stickode.tistory.com/275
https://stickode.tistory.com/275
'안드로이드 코틀린' 카테고리의 다른 글
[Kotlin][Android] 입력값의 태그 추출하기 (0) | 2021.12.14 |
---|---|
[Kotlin][Android] 앨범 사진 이미지 뷰에 띄워주기 (0) | 2021.12.13 |
[Kotlin][Android] 네트워크 모니터링 기능 (0) | 2021.11.27 |
[Kotlin][Android] 초대 메세지 공유하는 기능 만들기 (0) | 2021.11.24 |
[Kotlin][Android] ViewModel을 이용한 타이머 만들기. (0) | 2021.11.16 |