-
안드로이드 기본 앱 연동하기 - 카메라 앱Android 2024. 9. 19. 15:53
카메라 앱을 연동하여 사진을 촬영하고 그 결과를 돌려받는 방법은 2가지가 있다.
1. 사진 데이터 가져오기
카메라 앱으로 사진을 촬영한 후 파일로 저장하지 않고 데이터만 넘겨주는 방식이다. 사진을 파일로 저장하지 않으므로 쉽게 구현할 수 있지만 넘어오는 사진 데이터의 크기가 작다는 단점이 있다.
암시적 인텐트로 카메라 앱의 사진 촬영 액티비티를 실행한다.
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) requestCameraThumbnailLauncher.launch(intent)
액션 문자열을 MediaStore.ACTION_IMAGE_CAPTURE 로 지정하여 인텐트를 시스템에 전달하면 카메라 앱이 실행된다. 카메라 앱에서 넘어온 사진 데이터는 ActivityResultCallback 으로 가져오면 된다.
val requestCameraThumbnailLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult()) { val bitmap = it.data.extras.get("data") as Bitmap }
bitmap 변수에는 넘어온 카메라 데이터가 담겨져있다.
2. 사진 파일 공유하기
카메라 앱에서 촬영한 사진을 파일에 저장한 후 성공인지 실패인지만 넘겨주는 방식이다. 해당 방식은 휴대폰의 카메라 성능만큼 큰 크기의 사진을 촬영하고 앱에서 이용할 수 있지만, 카메라 앱이 파일 정보를 공유하는 것이므로 몇 가지 준비 작업이 필요하다. 다음 절차를 따라야 한다.
① 앱에서 사진을 저장할 파일을 만든다.
② 사진 파일 정보를 포함한 인텐트를 시스템에 전달해 카메라 앱을 실행한다.
③ 카메라 앱으로 사진을 촬영하여 사진을 공유된 파일에 저장한다.
④ 카메라 앱을 종료하면서 성공 또는 실패를 반환한다.
⑤ 카메라 앱이 저장한 사진 파일을 앱에서 이용한다.
먼저 내 앱(카메라앱X)에서 외장 메모리에 파일을 만들어야 한다. 두가지 방법이 있다.
getExternalStoragePublicDirectory()
모든 앱에서 이용할 수 있는 파일을 만든다. 해당 함수를 이용해 외장 메모리에 파일을 만들려면 퍼미션을 설정해야 한다.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
getExternalFilesDir()
이 앱에서만 이용할 수 있는 파일을 만든다. getExternalStoragePublicDirectory() 와 마찬가지로 퍼미션을 설정해야했지만 API 레벨 19 이후부터 해당 작업을 하지 않아도 된다. (단, API 19 하위에서 동작할려면 퍼미션을 설정해줘야 한다.)
API 24 부터는 "file://" 프로토콜로 구성된 URI 를 외부에 노출하지 못하도록 하는 엄격 모드가 적용됐다.
따라서 앱끼리 파일을 공유하려면 "content://" 프로토콜을 이용하고 이 URI 에 임시로 접근할 수 있는 권한을 부여해야 한다. 이때는 FileProvider 클래스를 이용한다. FileProvider 클래스는 content:// 프로토콜로 구성된 URI 를 생성해준다.
즉, FileProvider 를 이용하려면 공유할 파일의 URI 값을 만들어야 한다. 프로젝트의 xml 디렉터리에 파일 프로바이더용 XML 파일을 만들어야 한다.
// 파일 프로바이더용 XML 파일 <paths> <external-path name="myfiles" path="Android/data/com.example.패키지명/files/Pictures"/> </paths>
이곳에 지정한 경로는 getExternalFilesDir() 함수로 파일을 만들었을 때 파일이 저장되는 위치이다.
해당 파일 프로바이더용 XML 파일을 메니페스트에 등록해야한다.
// manifest 에 file provider xml 등록 <provider android:name="androidx.core.content.FileProvider" android:authorities="com.example.패키지명.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider>
resource 속성에 아까 만든 XML 파일을 지정한다.
이제 코드에서 파일을 만들어야 한다.
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES) val file = File.createTempFile( "JPEG_${timeStamp}_", ".jpg", storageDir ) filePath = file.absolutePath
Environment.DIRECTORY_PICTURES 로 지정하여 아까 파일 프로바이더용 XML 파일을 만들때 path로 지정한 Android/data/com.example.패키지명/files/Pictures 에 저장된다.
createTempFile 에 해당 매개변수를 지정한 이유는 파일명이 중복되지 않게 하여 날짜와 시각을 이용했다.
filePath 는 나중에 파일 내용을 읽을 때 사용하려고 파일 경로를 저장했다.
인텐트를 만들어 카메라 앱을 실행해보자.
val requestCameraFileLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult()) { val option = BitmapFactory.Options() option.inSampleSize = 4 // OOM Error 방지 val bitmap = BitmapFactory.decodeFile(filePath, option) bitmap.let { // View 에 출력 binding.cameraImage.setImageBitmap(it) } } val photoUri = FileProvider.getUriForFile( this, "com.example.패키지명.fileprovider", file ) val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) // 암시적 인텐트 intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri) requestCameraFileLauncher.launch(intent)
이렇게 하면 카메라 앱을 내 앱에 연동하여 카메라 정보를 가져올 수 있다.
'Android' 카테고리의 다른 글
안드로이드 기본 앱 연동하기 - 지도 앱, 전화 앱 (0) 2024.10.03 안드로이드 기본 앱 연동하기 - 주소록 앱 (0) 2024.09.26 서비스 생명주기 - startService/bindService (0) 2024.09.12 안드로이드 기본 앱과 연동하기 - 갤러리 앱 (3) 2024.09.05 브로드캐스트 리시버(Broadcast Receiver) (0) 2024.08.28