개발하는 두더지

[안드로이드] 카메라 파일 공유 방식으로 이미지 로드하기 본문

Java,Android

[안드로이드] 카메라 파일 공유 방식으로 이미지 로드하기

덜지 2019. 2. 19. 18:49

[안드로이드] 카메라 파일 공유 방식으로 이미지 로드하기


Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 30);

위 방식으로 촬영된 사진 데이터를 가져올 수 있지만 섬네일 크기의 이미지만 가져오는 문제가 있습니다. 

카메라로 촬영한 크기 그대로 가져오려면 어떻게 해야할까요?


파일을 공유하는 방식으로 가져와야 합니다. 임의의 경로에 파일을 하나 만들고 FileProvider를 통해서 파일의 URI 값을 만들고 카메라 앱에 RI를 던져서 사진 촬영 이후 이미지를 가져오는 방법입니다.


카메라 앱과 같은 외부 앱에 파일 정보 공유 방법은 Android 7.0 ( API 24) 부터 변화가 있습니다.

API 24 이전 버전까지는 아래처럼 intent에 담아서 바로 보낼 수 있었습니다.

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(filePath));


API 24 이후부터는 앱 외부에 file:// 같은 URI를 외부에서 사용을 금지하는 정책이 생겼습니다. 그래서 FileProvider를 이용하면 됩니다.

FileProvider는 서포트 라이브러리 v4 에서 제공하는 ContentProvider인데 xml에서 설정한 내용을 기반으로 파일들에 대한 Content Uri를 만들어 줍니다.


res/xml/provider_paths.xml

<paths>
<external-path name="images" path="."/>
</paths>

외부 저장소의 경우 external-path를 사용하면 외부 저장소 루트 하위에 있는 파일들의 Uri를 만들 수 있습니다.

Environment.getExternalStorageDirectory().getAbsolutePath()



Androidmanifest.xml 에서는 application 태그 안에 아래의 코드를 넣어줍니다.

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



액티비티에서는 FileProvider를 통해 카메라 앱에 Intent를 넘겨주고

try {
String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myApp";
File dir = new File(dirPath);
if(!dir.exists()) {
dir.mkdir();
}

filePath = File.createTempFile("IMG", ".jpg", dir);
if(!filePath.exists()) {
filePath.createNewFile();
}

photoUri = FileProvider.getUriForFile(this, "프로젝트 패키지명.provider", filePath);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(filePath));
startActivityForResult(intent, 40);

}catch (Exception e) {
e.printStackTrace();
}


사진 촬영 이후 다시 앱으로 데이터를 넘겨 받으면 저장된 파일을 로드하여 원하는 크기로 이미지를 조절하면 됩니다.

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);


if(requestCode == 40 && resultCode == RESULT_OK) {
if(filePath != null) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
InputStream in = new FileInputStream(filePath);
BitmapFactory.decodeStream(in, null, options);
in.close();
in = null;
} catch ( Exception e ) {
e.printStackTrace();
}

final int width = options.outWidth;
final int height = options.outHeight;

// width, height 값에 따라 inSaampleSize 값 계산


BitmapFactory.Options imgOptions = new BitmapFactory.Options();
imgOptions.inSampleSize = inSampleSize;
Bitmap bitmap = BitmapFactory.decodeFile(filePath.getAbsolutePath(), imgOptions);
resultImageView.setImageBitmap(bitmap);
}
}
}








Comments