MediaStore API is an Android interface for accessing the device’s shared media files: images, videos, audio, and documents. Unlike direct file access, MediaStore works through a centralized media database and content provider. According to Android Developers Documentation (2025), starting with Android 10 the API became the primary mechanism for working with media, replacing the deprecated READ_EXTERNAL_STORAGE. Developers use MediaStore in galleries, music players, cameras, and file managers.
Key Takeaways
MediaStore API is a system content provider on the Android platform designed for indexing, storing, and providing access to device media files. The API is part of the Android SDK and has been available since API Level 1.
MediaStore operates through a unified media database that automatically scans the device and collects metadata for all media files. The database is updated by the system when files are added, modified, or deleted, so applications always receive up-to-date information without manual scanning.
The main MediaStore tables are: Images (pictures), Video (videos), Audio (audio files), and Files (general files). Each table contains columns with metadata: name, creation date, size, MIME type, GPS coordinates, and other attributes.
Before Android 10, developers used READ_EXTERNAL_STORAGE to access all device files. Android 10 (API 29) introduced Scoped Storage: applications could only access their own files and through MediaStore. Android 11 tightened the policy, completely blocking the direct path to shared directories.
Starting with Android 13 (API 33), Google replaced READ_EXTERNAL_STORAGE with granular permissions: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, and READ_MEDIA_AUDIO. This allows users to grant access only to specific media types without exposing the entire storage.
MediaStore is built on a content provider architecture: each application accesses it through ContentResolver and Uri. The system media scanner — MediaScannerConnection — automatically indexes all files on the device during boot, USB connection, or reboot.
The media database is stored in the system database and contains records for each media file. Columns differ by type: images have ORIENTATION and DATE_TAKEN, videos have DURATION, audio files have ARTIST and ALBUM. Developers can run SQL-like queries using query with projection and selection for filtering.
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))
}
}
Each media file is identified by a Content URI like content://media/external/images/media/1234. The external URI points to shared storage, while the internal URI points to system media files. Using URIs instead of file paths is a key advantage of MediaStore: the application does not need file system access and works through a secure content provider.
MediaStore supports four main media types, each with its own table and metadata set. Developers select the appropriate table based on the type of content their application works with.
In addition to standard columns, each table contains system fields: _ID, DATA (deprecated), SIZE, MIME_TYPE, DATE_ADDED, DATE_MODIFIED. Since Android 10, the DATA field is marked as deprecated, and developers should work by opening an InputStream via URI.
MediaStore requires explicit permissions, which differ depending on the Android version. Before Android 13, the single READ_EXTERNAL_STORAGE permission was used. Starting with Android 13 (API 33), Google introduced granular permissions for each media type.
| Media Type | Permission (API 33+) | Legacy (API 29–32) |
|---|---|---|
| Images | READ_MEDIA_IMAGES | READ_EXTERNAL_STORAGE |
| Video | READ_MEDIA_VIDEO | READ_EXTERNAL_STORAGE |
| Audio | READ_MEDIA_AUDIO | READ_EXTERNAL_STORAGE |
| Write | WRITE_EXTERNAL_STORAGE | WRITE_EXTERNAL_STORAGE |
Writing to MediaStore also requires WRITE_EXTERNAL_STORAGE for Android 9 and below. Starting with Android 10, an application can write its own files to MediaStore without additional permissions — the system automatically grants access when inserting a record via ContentResolver.insert.
MediaStore permissions are requested through the standard ActivityResultContracts.RequestMultiplePermissions mechanism. The user may deny the request, and the application must handle this scenario correctly. It is recommended to check permission via ContextCompat.checkSelfPermission before each access to MediaStore.
MediaStore allows not only reading but also writing media files. To write an image or video, the developer uses ContentResolver.insert and opens an OutputStream for the returned URI. The system automatically adds the file to the media database and indexes it.
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 ->
// write bytes to stream
}
}
Deletion is performed using ContentResolver.delete with the file’s URI. The system checks access rights: if the file belongs to the current application, deletion occurs without additional permissions. For files from other applications on Android 10+, user confirmation via a system dialog is required.
MediaStore API fundamentally differs from direct file access via the File API. Instead of file paths, Content URIs are used, and instead of file operations, ContentResolver methods are used. This provides three key advantages: security, automatic indexing, and a unified interface.
Direct file access is restricted on Android 10+ for shared directories. MediaStore remains the only way to read media from Pictures, DCIM, Movies, Music, and Download. For application-specific files (app-specific storage), direct access is preserved — these are folders in Android/data and Android/media.
The choice between MediaStore and direct access depends on the content type. MediaStore is mandatory for shared media files accessible by other applications. The direct File API is suitable for internal application files and cache. The Storage Access Framework is used for selecting arbitrary documents through the system picker.
Frequently Asked Questions
MediaStore API is Android’s system content provider for accessing device media files: images, videos, audio, and documents. The API provides a unified interface through ContentResolver and a media database that automatically indexes all files.
MediaStore supports Images (pictures), Video (videos), Audio (audio files), and Files (documents). Each type has its own table with its own metadata set: images have ORIENTATION, videos have DURATION, audio files have ARTIST.
On Android 13+, granular permissions are used: READ_MEDIA_IMAGES for images, READ_MEDIA_VIDEO for video, and READ_MEDIA_AUDIO for audio. The user can grant access only to specific media types.
To write, create ContentValues with the name and MIME type, call ContentResolver.insert to obtain a URI, then open an OutputStream via ContentResolver.openOutputStream. The system automatically indexes the new file.
MediaStore provides programmatic access to all device media files through a media database. Storage Access Framework opens a system file picker dialog and returns a URI — the user selects a specific file or folder.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also