Android

Android - 카메라와 갤러리 사용하기

임베디드 친구 2024. 11. 25. 09:02
반응형

안드로이드 애플리케이션 개발을 하다 보면 카메라로 사진을 찍거나, 갤러리에서 사진을 선택해 앱에서 활용해야 하는 경우가 많이 있습니다. 이번 포스팅에서는 간단한 예제를 통해 카메라와 갤러리를 사용하는 방법을 알아보겠습니다. 카메라로 사진을 찍고, 갤러리에서 이미지를 가져오는 기능을 구현해 봅시다.

1. AndroidManifest.xml 설정하기

카메라와 갤러리 기능을 사용하려면 관련 권한을 선언해야 합니다. 다음과 같이 AndroidManifest.xml 파일에 권한을 추가해 주세요.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.camera_gallery">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        ...>
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
        ...
    </application>
</manifest>

위와 같이 카메라와 외부 저장소 사용 권한을 선언하고, FileProvider 설정을 추가합니다.

2. FileProvider 설정하기

res/xml/file_paths.xml 파일을 생성하여 FileProvider 경로를 설정해줍니다. 이 설정은 촬영한 사진 파일을 공유하기 위해 필요합니다.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path
        name="images"
        path="Pictures" />
</paths>

3. 카메라와 갤러리 호출하는 코드 작성하기

카메라와 갤러리를 호출하고, 결과를 처리하는 코드를 작성해 보겠습니다. 이번 예제에서는 ActivityResultLauncher를 사용하여 결과를 비동기적으로 처리합니다.

package com.example.camera_gallery

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class MainActivity : AppCompatActivity() {

    private lateinit var cameraLauncher: ActivityResultLauncher<Uri>
    private lateinit var galleryLauncher: ActivityResultLauncher<Intent>
    private lateinit var photoUri: Uri
    private lateinit var imageView: ImageView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        imageView = findViewById(R.id.imageView)
        val cameraButton: Button = findViewById(R.id.button_camera)
        val galleryButton: Button = findViewById(R.id.button_gallery)

        // 카메라 결과 처리
        cameraLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
            if (success) {
                imageView.setImageURI(photoUri)
            }
        }

        // 갤러리 결과 처리
        galleryLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            if (result.resultCode == Activity.RESULT_OK) {
                val selectedImageUri: Uri? = result.data?.data
                selectedImageUri?.let {
                    imageView.setImageURI(it)
                }
            }
        }

        // 카메라 버튼 클릭 리스너
        cameraButton.setOnClickListener {
            val photoFile = createImageFile()
            photoUri = FileProvider.getUriForFile(
                this,
                "${applicationContext.packageName}.provider",
                photoFile
            )
            cameraLauncher.launch(photoUri)
        }

        // 갤러리 버튼 클릭 리스너
        galleryButton.setOnClickListener {
            val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
            galleryLauncher.launch(intent)
        }
    }

    // 이미지 파일 생성 함수
    private fun createImageFile(): File {
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val storageDir: File? = getExternalFilesDir("Pictures")
        return File.createTempFile(
            "JPEG_${timeStamp}_", ".jpg", storageDir
        )
    }
}

위 코드에서는 카메라와 갤러리의 결과를 처리하기 위해 ActivityResultLauncher를 사용했습니다. cameraLauncher는 카메라로 촬영한 사진을 저장하고, galleryLauncher는 갤러리에서 선택한 이미지를 가져옵니다.

주요 코드 설명

  1. 카메라 결과 처리
    • registerForActivityResult(ActivityResultContracts.TakePicture())를 사용하여 사진을 찍고 결과를 처리합니다. photoUri를 사용하여 이미지를 저장합니다.
  2. 갤러리 결과 처리
    • registerForActivityResult(ActivityResultContracts.StartActivityForResult())를 사용하여 갤러리에서 선택한 이미지를 가져옵니다.
  3. createImageFile() 함수
    • 현재 시간을 기반으로 고유한 파일 이름을 생성하고, 저장할 파일을 반환합니다.

4. 레이아웃 설정하기

카메라와 갤러리를 호출하는 버튼과 이미지를 표시할 ImageView를 설정합니다. res/layout/activity_main.xml 파일에 다음과 같이 작성합니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button_camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="카메라 열기"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp" />

    <Button
        android:id="@+id/button_gallery"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="갤러리 열기"
        android:layout_below="@id/button_camera"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button_gallery"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp" />

</RelativeLayout>

5. 실행 결과

이제 앱을 실행해 보시면, "카메라 열기" 버튼을 클릭하여 카메라를 실행하고 사진을 찍어 이미지를 ImageView에 표시할 수 있습니다. "갤러리 열기" 버튼을 클릭하면 갤러리에서 이미지를 선택하고 앱에 표시할 수 있습니다.

6. 마무리

이번 포스팅에서는 안드로이드 애플리케이션에서 카메라와 갤러리를 사용하는 방법을 살펴보았습니다. 카메라와 갤러리를 연동하는 것은 다양한 앱에서 활용될 수 있는 유용한 기능입니다. 실제 앱 개발 시 권한 요청 및 파일 저장 경로에 대한 보안을 고려하여 더욱 견고한 코드를 작성하는 것이 좋습니다.

반응형