MediaStore API là giao diện Android để truy cập các tệp phương tiện dùng chung của thiết bị: hình ảnh, video, âm thanh và tài liệu. Không giống như truy cập tệp trực tiếp, MediaStore hoạt động thông qua cơ sở dữ liệu phương tiện tập trung và nhà cung cấp nội dung. Theo Tài liệu dành cho nhà phát triển Android (2025), bắt đầu từ Android 10, API đã trở thành cơ chế chính để làm việc với phương tiện, thay thế READ_EXTERNAL_STORAGE lỗi thời. Các nhà phát triển sử dụng MediaStore trong thư viện ảnh, trình phát nhạc, máy ảnh và trình quản lý tệp.
Những điểm chính
MediaStore API là nhà cung cấp nội dung hệ thống trên nền tảng Android được thiết kế để lập chỉ mục, lưu trữ và cung cấp quyền truy cập vào các tệp phương tiện của thiết bị. API là một phần của Android SDK và có sẵn từ API Level 1.
MediaStore hoạt động thông qua cơ sở dữ liệu phương tiện hợp nhất tự động quét thiết bị và thu thập siêu dữ liệu của tất cả các tệp phương tiện. Cơ sở dữ liệu được cập nhật bởi hệ thống khi tệp được thêm, sửa đổi hoặc xóa, do đó các ứng dụng luôn nhận được thông tin cập nhật mà không cần quét thủ công.
Các bảng chính của MediaStore là: Images (hình ảnh), Video (video), Audio (âm thanh) và Files (tệp chung). Mỗi bảng chứa các cột với siêu dữ liệu: tên, ngày tạo, kích thước, loại MIME, tọa độ GPS và các thuộc tính khác.
Trước Android 10, các nhà phát triển sử dụng READ_EXTERNAL_STORAGE để truy cập tất cả tệp thiết bị. Android 10 (API 29) đã giới thiệu Scoped Storage: các ứng dụng chỉ có thể truy cập tệp của chính mình và thông qua MediaStore. Android 11 đã thắt chặt chính sách hơn nữa, chặn hoàn toàn đường dẫn trực tiếp đến các thư mục dùng chung.
Bắt đầu từ Android 13 (API 33), Google đã thay thế READ_EXTERNAL_STORAGE bằng các quyền chi tiết: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO và READ_MEDIA_AUDIO. Điều này cho phép người dùng cấp quyền truy cập chỉ cho các loại phương tiện cụ thể mà không tiết lộ toàn bộ bộ nhớ.
MediaStore được xây dựng trên kiến trúc nhà cung cấp nội dung: mỗi ứng dụng truy cập nó thông qua ContentResolver và Uri. Trình quét phương tiện hệ thống — MediaScannerConnection — tự động lập chỉ mục tất cả tệp trên thiết bị khi khởi động, kết nối USB hoặc khởi động lại.
Cơ sở dữ liệu phương tiện được lưu trữ trong cơ sở dữ liệu hệ thống và chứa bản ghi cho mỗi tệp phương tiện. Các cột khác nhau theo loại: hình ảnh có ORIENTATION và DATE_TAKEN, video có DURATION, tệp âm thanh có ARTIST và ALBUM. Nhà phát triển có thể chạy truy vấn giống SQL thông qua query với projection và selection để lọc.
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))
}
}
Mỗi tệp phương tiện được xác định bằng Content URI như content://media/external/images/media/1234. URI bên ngoài trỏ đến bộ nhớ dùng chung, trong khi URI bên trong trỏ đến các tệp phương tiện hệ thống. Sử dụng URI thay vì đường dẫn tệp là lợi thế chính của MediaStore: ứng dụng không cần quyền truy cập hệ thống tệp và hoạt động thông qua nhà cung cấp nội dung an toàn.
MediaStore hỗ trợ bốn loại phương tiện chính, mỗi loại có bảng và bộ siêu dữ liệu riêng. Nhà phát triển chọn bảng phù hợp dựa trên loại nội dung mà ứng dụng của họ làm việc.
Ngoài các cột tiêu chuẩn, mỗi bảng còn chứa các trường hệ thống: _ID, DATA (không dùng nữa), SIZE, MIME_TYPE, DATE_ADDED, DATE_MODIFIED. Từ Android 10, trường DATA được đánh dấu là không dùng nữa và các nhà phát triển nên làm việc bằng cách mở InputStream qua URI.
MediaStore yêu cầu quyền rõ ràng, khác nhau tùy theo phiên bản Android. Trước Android 13, quyền duy nhất READ_EXTERNAL_STORAGE được sử dụng. Bắt đầu từ Android 13 (API 33), Google đã giới thiệu các quyền chi tiết cho từng loại phương tiện.
| Loại phương tiện | Quyền (API 33+) | Cũ (API 29–32) |
|---|---|---|
| Hình ảnh | READ_MEDIA_IMAGES | READ_EXTERNAL_STORAGE |
| Video | READ_MEDIA_VIDEO | READ_EXTERNAL_STORAGE |
| Âm thanh | READ_MEDIA_AUDIO | READ_EXTERNAL_STORAGE |
| Ghi | WRITE_EXTERNAL_STORAGE | WRITE_EXTERNAL_STORAGE |
Ghi vào MediaStore cũng yêu cầu WRITE_EXTERNAL_STORAGE cho Android 9 trở xuống. Bắt đầu từ Android 10, ứng dụng có thể ghi tệp của riêng mình vào MediaStore mà không cần quyền bổ sung — hệ thống tự động cấp quyền truy cập khi chèn bản ghi qua ContentResolver.insert.
Quyền MediaStore được yêu cầu thông qua cơ chế tiêu chuẩn ActivityResultContracts.RequestMultiplePermissions. Người dùng có thể từ chối yêu cầu và ứng dụng phải xử lý tình huống này một cách chính xác. Nên kiểm tra quyền thông qua ContextCompat.checkSelfPermission trước mỗi lần truy cập MediaStore.
MediaStore cho phép không chỉ đọc mà còn ghi các tệp phương tiện. Để ghi hình ảnh hoặc video, nhà phát triển sử dụng ContentResolver.insert và mở OutputStream cho URI được trả về. Hệ thống tự động thêm tệp vào cơ sở dữ liệu phương tiện và lập chỉ mục nó.
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 ->
// ghi byte vào luồng
}
}
Việc xóa được thực hiện thông qua ContentResolver.delete với URI của tệp. Hệ thống kiểm tra quyền truy cập: nếu tệp thuộc về ứng dụng hiện tại, việc xóa diễn ra mà không cần quyền bổ sung. Đối với tệp của ứng dụng khác trên Android 10+, cần xác nhận của người dùng thông qua hộp thoại hệ thống.
MediaStore API khác biệt cơ bản so với truy cập tệp trực tiếp qua File API. Thay vì đường dẫn tệp, Content URI được sử dụng và thay vì thao tác tệp, các phương thức ContentResolver được sử dụng. Điều này mang lại ba lợi thế chính: bảo mật, lập chỉ mục tự động và giao diện hợp nhất.
Truy cập tệp trực tiếp bị hạn chế trên Android 10+ cho các thư mục dùng chung. MediaStore vẫn là cách duy nhất để đọc phương tiện từ Pictures, DCIM, Movies, Music và Download. Đối với tệp dành riêng cho ứng dụng (app-specific storage), quyền truy cập trực tiếp được bảo toàn — đó là các thư mục trong Android/data và Android/media.
Việc lựa chọn giữa MediaStore và truy cập trực tiếp phụ thuộc vào loại nội dung. MediaStore là bắt buộc đối với các tệp phương tiện dùng chung mà các ứng dụng khác có thể truy cập. File API trực tiếp phù hợp cho các tệp nội bộ của ứng dụng và bộ nhớ đệm. Storage Access Framework được sử dụng để chọn tài liệu tùy ý thông qua trình chọn hệ thống.
Câu hỏi thường gặp
MediaStore API là nhà cung cấp nội dung hệ thống Android để truy cập các tệp phương tiện của thiết bị: hình ảnh, video, âm thanh và tài liệu. API cung cấp giao diện hợp nhất thông qua ContentResolver và cơ sở dữ liệu phương tiện tự động lập chỉ mục tất cả các tệp.
MediaStore hỗ trợ Images (hình ảnh), Video (video), Audio (âm thanh) và Files (tài liệu). Mỗi loại có bảng riêng với bộ siêu dữ liệu riêng: hình ảnh có ORIENTATION, video có DURATION, tệp âm thanh có ARTIST.
Trên Android 13+, các quyền chi tiết được sử dụng: READ_MEDIA_IMAGES cho hình ảnh, READ_MEDIA_VIDEO cho video và READ_MEDIA_AUDIO cho âm thanh. Người dùng có thể cấp quyền truy cập chỉ cho các loại phương tiện cụ thể.
Để ghi, hãy tạo ContentValues với tên và loại MIME, gọi ContentResolver.insert để lấy URI, sau đó mở OutputStream qua ContentResolver.openOutputStream. Hệ thống tự động lập chỉ mục tệp mới.
MediaStore cung cấp quyền truy cập theo chương trình vào tất cả các tệp phương tiện của thiết bị thông qua cơ sở dữ liệu phương tiện. Storage Access Framework mở hộp thoại chọn tệp hệ thống và trả về URI — người dùng chọn một tệp hoặc thư mục cụ thể.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm