MediaStore API는 기기의 공유 미디어 파일(이미지, 비디오, 오디오, 문서)에 액세스하기 위한 Android 인터페이스입니다. 직접 파일 액세스와 달리 MediaStore는 중앙 집중식 미디어 데이터베이스와 콘텐츠 제공자를 통해 작동합니다. Android Developers Documentation(2025)에 따르면 Android 10부터 이 API는 더 이상 사용되지 않는 READ_EXTERNAL_STORAGE를 대체하여 미디어 작업의 주요 메커니즘이 되었습니다. 개발자는 갤러리, 음악 플레이어, 카메라 및 파일 관리자에서 MediaStore를 사용합니다.
핵심 사항
MediaStore API는 Android 플랫폼의 시스템 콘텐츠 제공자로, 기기의 미디어 파일을 인덱싱, 저장 및 액세스를 제공하도록 설계되었습니다. 이 API는 Android SDK의 일부이며 API Level 1부터 사용할 수 있습니다.
MediaStore는 기기를 자동으로 스캔하고 모든 미디어 파일의 메타데이터를 수집하는 통합 미디어 데이터베이스를 통해 작동합니다. 데이터베이스는 파일이 추가, 수정 또는 삭제될 때 시스템에 의해 업데이트되므로 애플리케이션은 수동 스캔 없이 항상 최신 정보를 받습니다.
MediaStore의 주요 테이블은 다음과 같습니다: Images(이미지), Video(비디오), Audio(오디오), Files(일반 파일). 각 테이블에는 이름, 생성 날짜, 크기, MIME 유형, GPS 좌표 및 기타 속성과 같은 메타데이터가 포함된 열이 있습니다.
Android 10 이전에는 개발자가 READ_EXTERNAL_STORAGE를 사용하여 모든 기기 파일에 액세스했습니다. Android 10(API 29)은 Scoped Storage를 도입하여 애플리케이션이 자체 파일과 MediaStore를 통해서만 액세스할 수 있게 했습니다. Android 11은 정책을 더욱 강화하여 공유 디렉토리에 대한 직접 경로를 완전히 차단했습니다.
Android 13(API 33)부터 Google은 READ_EXTERNAL_STORAGE를 세분화된 권한(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO)으로 대체했습니다. 이를 통해 사용자는 저장소 전체를 노출하지 않고 특정 미디어 유형에만 액세스 권한을 부여할 수 있습니다.
MediaStore는 콘텐츠 제공자 아키텍처를 기반으로 구축되었으며, 각 애플리케이션은 ContentResolver와 Uri를 통해 액세스합니다. 시스템 미디어 스캐너인 MediaScannerConnection은 부팅, USB 연결 또는 재부팅 시 기기의 모든 파일을 자동으로 인덱싱합니다.
미디어 데이터베이스는 시스템 데이터베이스에 저장되며 각 미디어 파일의 레코드를 유지합니다. 열은 유형에 따라 다릅니다: 이미지에는 ORIENTATION과 DATE_TAKEN, 비디오에는 DURATION, 오디오 파일에는 ARTIST와 ALBUM이 있습니다. 개발자는 projection과 selection을 사용한 query를 통해 SQL과 유사한 쿼리를 실행할 수 있습니다.
val projection = arrayOf(
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATE_ADDED
)
val cursor = contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
MediaStore.Images.Media.DATE_ADDED + " DESC"
)
cursor?.use {
while (moveToNext()) {
val name = getString(getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
}
}
각 미디어 파일은 content://media/external/images/media/1234와 같은 Content URI로 식별됩니다. 외부 URI는 공유 저장소를 가리키고, 내부 URI는 시스템 미디어 파일을 가리킵니다. 파일 경로 대신 URI를 사용하는 것이 MediaStore의 주요 이점입니다: 애플리케이션은 파일 시스템 액세스가 필요하지 않으며 안전한 콘텐츠 제공자를 통해 작동합니다.
MediaStore는 4가지 주요 미디어 유형을 지원하며, 각각 고유한 테이블과 메타데이터 세트가 있습니다. 개발자는 애플리케이션이 작업하는 콘텐츠 유형에 따라 적절한 테이블을 선택합니다.
표준 열 외에도 각 테이블에는 시스템 필드(_ID, DATA(더 이상 사용되지 않음), SIZE, MIME_TYPE, DATE_ADDED, DATE_MODIFIED)가 포함됩니다. Android 10부터 DATA 필드는 더 이상 사용되지 않는 것으로 표시되었으며, 개발자는 URI를 통해 InputStream을 열어 작업해야 합니다.
MediaStore에는 명시적 권한이 필요하며, Android 버전에 따라 다릅니다. Android 13 이전에는 단일 READ_EXTERNAL_STORAGE 권한이 사용되었습니다. Android 13(API 33)부터 Google은 미디어 유형별로 세분화된 권한을 도입했습니다.
| 미디어 유형 | 권한 (API 33+) | 이전 (API 29–32) |
|---|---|---|
| 이미지 | READ_MEDIA_IMAGES | READ_EXTERNAL_STORAGE |
| 비디오 | READ_MEDIA_VIDEO | READ_EXTERNAL_STORAGE |
| 오디오 | READ_MEDIA_AUDIO | READ_EXTERNAL_STORAGE |
| 쓰기 | WRITE_EXTERNAL_STORAGE | WRITE_EXTERNAL_STORAGE |
MediaStore에 쓰려면 Android 9 이하에서는 WRITE_EXTERNAL_STORAGE도 필요합니다. Android 10부터 애플리케이션은 추가 권한 없이 MediaStore에 자체 파일을 쓸 수 있습니다 — ContentResolver.insert를 통해 레코드를 삽입하면 시스템이 자동으로 액세스를 제공합니다.
MediaStore 권한은 표준 ActivityResultContracts.RequestMultiplePermissions 메커니즘을 통해 요청됩니다. 사용자가 요청을 거부할 수 있으므로 애플리케이션은 이 시나리오를 올바르게 처리해야 합니다. MediaStore에 액세스하기 전에 ContextCompat.checkSelfPermission을 통해 권한을 확인하는 것이 좋습니다.
MediaStore를 사용하면 미디어 파일을 읽을 뿐만 아니라 쓸 수도 있습니다. 이미지나 비디오를 쓰기 위해 개발자는 ContentResolver.insert를 사용하고 반환된 URI에 대한 OutputStream을 엽니다. 시스템은 자동으로 파일을 미디어 데이터베이스에 추가하고 인덱싱합니다.
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "photo_2025.jpg")
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/MyApp")
}
val uri = contentResolver?.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
)
uri?.let {
val outputStream = contentResolver?.openOutputStream(it)
outputStream?.use { stream ->
// 스트림에 바이트 쓰기
}
}
삭제는 파일의 URI와 함께 ContentResolver.delete를 사용하여 수행됩니다. 시스템은 액세스 권한을 확인합니다: 파일이 현재 애플리케이션에 속하는 경우 추가 권한 없이 삭제가 이루어집니다. Android 10+에서 다른 애플리케이션의 파일을 삭제하려면 시스템 대화 상자를 통한 사용자 확인이 필요합니다.
MediaStore API는 File API를 통한 직접 파일 액세스와 근본적으로 다릅니다. 파일 경로 대신 Content URI가 사용되고, 파일 작업 대신 ContentResolver 메서드가 사용됩니다. 이는 보안, 자동 인덱싱 및 통합 인터페이스라는 세 가지 주요 이점을 제공합니다.
직접 파일 액세스는 Android 10+에서 공유 디렉토리에 대해 제한됩니다. MediaStore는 Pictures, DCIM, Movies, Music 및 Download에서 미디어를 읽는 유일한 방법입니다. 애플리케이션별 파일(app-specific storage)의 경우 직접 액세스가 유지됩니다 — 이는 Android/data 및 Android/media의 폴더입니다.
MediaStore와 직접 액세스 중 선택은 콘텐츠 유형에 따라 다릅니다. MediaStore는 다른 애플리케이션이 액세스할 수 있는 공유 미디어 파일에 필수입니다. 직접 File API는 애플리케이션의 내부 파일 및 캐시에 적합합니다. Storage Access Framework는 시스템 선택기를 통해 임의 문서를 선택하는 데 사용됩니다.
자주 묻는 질문
MediaStore API는 기기의 미디어 파일(이미지, 비디오, 오디오, 문서)에 액세스하기 위한 Android 시스템 콘텐츠 제공자입니다. API는 ContentResolver와 모든 파일을 자동으로 인덱싱하는 미디어 데이터베이스를 통해 통합 인터페이스를 제공합니다.
MediaStore는 Images(이미지), Video(비디오), Audio(오디오), Files(문서)를 지원합니다. 각 유형에는 고유한 테이블과 메타데이터 세트가 있습니다: 이미지에는 ORIENTATION, 비디오에는 DURATION, 오디오 파일에는 ARTIST가 있습니다.
Android 13+에서는 세분화된 권한이 사용됩니다: 이미지에는 READ_MEDIA_IMAGES, 비디오에는 READ_MEDIA_VIDEO, 오디오에는 READ_MEDIA_AUDIO. 사용자는 특정 미디어 유형에만 액세스 권한을 부여할 수 있습니다.
쓰려면 이름과 MIME 유형으로 ContentValues를 만들고, ContentResolver.insert를 호출하여 URI를 얻은 다음, ContentResolver.openOutputStream을 통해 OutputStream을 엽니다. 시스템이 자동으로 새 파일을 인덱싱합니다.
MediaStore는 미디어 데이터베이스를 통해 기기의 모든 미디어 파일에 프로그래밍 방식으로 액세스를 제공합니다. Storage Access Framework는 시스템 파일 선택 대화 상자를 열고 URI를 반환합니다 — 사용자가 특정 파일 또는 폴더를 선택합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.