FrontEnd/Android
[Android] 갤러리에서 사진 선택 기능 구현
Satisfaction
2020. 9. 14. 18:34
내 앱에서 갤러리 앱을 열고 선택한 사진을 내 앱에서 불러오는 기능을 구현한다.
파일 읽기 권한 추가
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
먼저 manifest.xml에 다음 권한을 추가하고,
마시멜로 이상의 Android 버전을 타게팅하는 경우 사용자에게 권한을 요청하여 받아낸다.
액티비티에서 갤러리 열기
우선 갤러리를 여는 코드부터 작성해 보자
public class SomeActivity extends FragmentActivity{
//...
if(PermissionChecker.checkPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)){
//권한이 확인된 경우 갤러리 오픈
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, OPEN_GALLERY); //OPEN_GALLERY는 임의의 requestCode (int)
}else{
PermissionChecker.getInst(this).request(this, "사진 업로드를 위해 파일 읽기 권한이 필요합니다", Manifest.permission.READ_EXTERNAL_STORAGE, 0);
}
//...
}
PermissionChecker부분은 설정된 권한을 확인하는 코드이니 알아서 작성하면 되고,
주목할 부분은
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, OPEN_GALLERY); //OPEN_GALLERY는 임의의 requestCode (int)
이 부분이다.
startActivity가 아닌 startActivityForResult를 사용한 이유는 해당 갤러리에서 사진을 선택하면 갤러리가 닫히고
내 앱으로는 선택한 사진 정보가 전달되는데 이를 캐치하는 부분이 onActivityResult 이기 때문이다.
선택한 사진 정보 로드
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case OPEN_GALLERY:
if (data != null && resultCode == RESULT_OK) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
if (cursor == null || cursor.getCount() < 1) {
return; // no cursor or no record. DO YOUR ERROR HANDLING
}
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if (columnIndex < 0) // no column index
return; // DO YOUR ERROR HANDLING
//선택한 파일 경로
String picturePath = cursor.getString(columnIndex);
cursor.close();
}
break;
}
}
성공적으로 유저가 사진을 선택했다면 String picturePath까지 내려올 수 있다.
이제 선택한 사진의 경로를 알게 되었다.
만약 해당 사진의 비트맵 오브젝트를 얻고 싶다면 picturePath 아래에 다음과 같이 추가한다.
Bitmap bitmap = BitmapFactory.decodeFile(picturePath);
얻어온 bitmap 객체를 이미지뷰에 표시하고 싶다면 someImageView.setImageBitmap(bitmap) 처럼 사용할 수도 있다.
BitmapFactory.decodeFile() return null (Android 10~)
안드로이드 10 부터 저장소에 접근하는 방식이 바뀌어서 위의 방법대로 했을 경우 bitmap 값에 null이 들어간다.
이 경우 manifest.xml의 application 속성에 android:requestLegacyExternalStorage="true" 를 추가한다.
그러면 정상적으로 비트맵 객체를 얻어올 수 있다.