# Android怎么獲取手機相冊里所有照片
在Android應用開發中,訪問用戶相冊是一個常見需求。本文將詳細介紹如何通過`MediaStore API`和`ContentResolver`獲取手機相冊中的所有照片,并處理Android 10及以上版本的存儲權限變更。
## 一、準備工作
### 1. 添加權限聲明
在`AndroidManifest.xml`中添加以下權限:
```xml
<!-- 外部存儲讀取權限(Android 9及以下需要) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 所有文件訪問權限(Android 11及以上需要特殊場景申請) -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
對于Android 6.0及以上設備:
private fun checkPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED -> {
loadImages()
}
shouldShowRequestPermissionRationale(...) -> {
// 顯示解釋對話框
}
else -> {
requestPermissions(
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
REQUEST_CODE
)
}
}
} else {
loadImages()
}
}
fun getAllPhotos(context: Context): List<Image> {
val imageList = mutableListOf<Image>()
val projection = arrayOf(
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATE_ADDED,
MediaStore.Images.Media.SIZE,
MediaStore.Images.Media.WIDTH,
MediaStore.Images.Media.HEIGHT
)
val sortOrder = "${MediaStore.Images.Media.DATE_ADDED} DESC"
context.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
sortOrder
)?.use { cursor ->
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
val nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)
val dateColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED)
while (cursor.moveToNext()) {
val id = cursor.getLong(idColumn)
val name = cursor.getString(nameColumn)
val date = cursor.getLong(dateColumn)
val uri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
id
)
imageList.add(Image(id, uri, name, date))
}
}
return imageList
}
fun loadPagedPhotos(offset: Int, limit: Int): List<Image> {
val selection = "${MediaStore.Images.Media.DATE_ADDED} < ?"
val selectionArgs = arrayOf("$lastLoadedDate")
context.contentResolver.query(
uri,
projection,
selection,
selectionArgs,
"$sortOrder LIMIT $limit OFFSET $offset"
)
// ...處理邏輯同上
}
從Android 10開始:
// 在AndroidManifest中添加
<application
android:requestLegacyExternalStorage="true"
... >
val externalStorageVolumes = ContextCompat.getExternalFilesDirs(
context,
null
)
val primaryExternalStorage = externalStorageVolumes[0]
// 遍歷DCIM目錄
val dcimDir = File(primaryExternalStorage.absolutePath + "/DCIM")
dcimDir.listFiles()?.forEach { file ->
// 過濾圖片文件
}
val thumbnail = ContentResolver.loadThumbnail(
contentResolver,
uri,
Size(256, 256),
null
)
Glide.with(context)
.load(uri)
.override(600, 600)
.into(imageView)
CoroutineScope(Dispatchers.IO).launch {
val photos = getAllPhotos(context)
withContext(Dispatchers.Main) {
adapter.submitList(photos)
}
}
[GitHub Gist鏈接](示例代碼倉庫地址)
ACTION_OPEN_DOCUMENT_TREE通過以上方法,您可以高效地獲取Android設備相冊中的所有照片。建議始終遵循最小權限原則,并在應用中提供清晰的權限說明。 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。