본문 바로가기
Android

[Android] 카메라 앱으로 사진 촬영

by LoseyKim 2024. 3. 22.

기기의 기본 카메라 애플리케이션을 사용하여 사진이나 동영상 촬영과 같은 기본적인 카메라 작업을 실행하기 위해서는 Intent를 활용하면 되는데요.

안드로이드 개발자 문서에서는 startActivityForResult()를 사용한 예제로 안내하고 있어요.

저는 registerForActivityResult()을 이용해서 구현해 봤어요.


1. AndroidManifest.xmlFileProvider설정

FileProvider설정은 AndroidManifest.xmlfile_paths.xml에서 정의해야 합니다. 이미지 파일 저장을 위한 FileProvider구성은 다음과 같아요.

AndroidManifest.xml

<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>

res/xml/file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-cache-path name="my_images" path="." />
</paths>

2. createImageFile()함수 구현

해당 함수를 캐시 디렉토리에 저장할 파일을 생성 후 반환해요.

여기서 생성한 FileuriregisterForActivityResultp호출 시 전달하여 카메라 촬영 후 해당 uri에 저장해요.

생성된 파일의 uri예시 : content://패키지명.provider/cache/저장할 이미지명7004922257178701742.png

private fun createImageFile(): File? {
    return try {
        File.createTempFile(
            "저장할 이미지명",
            ".png", cacheDir
        )
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

3. registerForActivityResult()구현

ActivityResultContracts.TakePicture()를 사용하면 startActivityForResultonActivityResult콜백 메서드를 사용하지 않고도, 사진 촬영 작업의 결과를 처리할 수 있어요.

//카메라 앱을 통해 사진을 촬영한 후의 결과를 처리
private val takePictureLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
    if (success) {
        //성공했을 때
        //currentPhotoUri를 이용하여 이미지를 나타내는 등의 처리
    } else {
        //실패했을 때
    }
}

4. registerForActivityResult()호출

해당 코드를 실행하면 카메라 실행을 하게 되는데, 이전에 권한을 받는 과정이 필요해요.

앱에서 필요한 권한을 받는 과정은 다음에 작성해 볼게요.

resolveActivity를 통해서 takePictureIntent를 처리할 수 있는지, 즉 카메라 앱이 있는지 확인을 하고 실행해요.

createImageFile()함수를 통해 이미지가 저장될 uri를 받아서 takePictureLauncher호출 시 넘겨요.

//카메라에서 생성한 사진 uri
private var currentPhotoUri: Uri? = null
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
// 카메라 앱이 설치되어 있는지 확인
if (takePictureIntent.resolveActivity(packageManager) != null) {
    try {
        // 이미지 파일 생성
        createImageFile()?.let { photoFile ->
            // FileProvider를 통해 안전하게 Uri 공유
            currentPhotoUri = FileProvider.getUriForFile(
                this,
                "${applicationContext.packageName}.provider",
                photoFile
            )
            //Activity Launcher
            takePictureLauncher.launch(currentPhotoUri)
        }
    } catch (e: ActivityNotFoundException) {
        // 카메라 앱이 설치되어 있지 않은 경우의 예외 처리
    }
}

참고문서

https://developer.android.com/media/camera/camera-intents?hl=ko

카메라 인텐트 | Android media | Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 카메라 인텐트 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 기기의 기본 카메라 애플리케이션을 사

developer.android.com

https://developer.android.com/reference/androidx/activity/result/contract/ActivityResultContracts.TakePicture

ActivityResultContracts.TakePicture | Android Developers

androidx.appsearch.builtintypes.properties

developer.android.com