查找本地的多媒体文件,一般使用
MediaStore.Video.Media
MediaStore.Audio.Media
MediaStore.Images.Media
三个就足够了。
用法基本一致,例如想要获取媒体库中的所有图片,就这么写:
//获取cursor
Cursor cursor = this.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null,
null,
null,
null);
//图片路径所在列的索引
int indexPhotoPath = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
while (cursor.moveToNext()) {
//打印图片的路径
Log.i("uri:", cursor.getString(indexPhotoPath));
}
cursor.close();
最重要的步骤就是获取正确的cursor:
public final Cursor query(
Uri uri, //数据资源路径
String[] projection, //查询的列
String selection, //查询的条件
String[] selectionArgs, //条件填充值
String sortOrder) //排序依据
例如我想要查询目录为“pic”的所有图片的ID和名称,就这样写:
Cursor cursor = this.getContentResolver().query(
//数据源,EXTERNAL_CONTENT_URI是外部存储数据源,相应的INTERNAL_CONTENT_URI是内部存储源
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
//查询ID和名称
new String[]{MediaStore.Images.Media._ID, MediaStore.Images.Media.TITLE},
//条件为目录名
MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " = ?",
//目录名为pic
new String[]{"pic"},
//按ID倒序排列
MediaStore.Images.Media._ID+" DESC");
换作SQL语句大概是这样的:
SELECT _id,title FROM images WHERE bucket_display_name = "pic" ORDER BY _id DESC
不过总有些文件比较特殊,用上面的方法查询不出来,或者说,某些媒体文件扫描不到,就没有添加进上述三个数据源中,导致查询不出来;这种情况下,可以尝试用MediaStore.Files。
MediaStore.Files存储了所有应用中共享的文件,包括图片、文件、视频、音乐等多媒体文件,包括非多媒体文件。官方原文是这样说的:
Media provider table containing an index of all files in the media storage, including non-media files. This should be used by applications that work with non-media file types (text, HTML, PDF, etc) as well as applications that need to work with multiple media file types in a single query.
使用方法大体相同,需要注意的是其数据源和查询所用的列和上述三个数据源有区别。
例如要查询mp4文件:
Cursor cursor = this.getContentResolver().query(
//数据源
MediaStore.Files.getContentUri("external"),
//查询ID和名称
new String[]{MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.TITLE},
//条件为文件类型
MediaStore.Files.FileColumns.MIME_TYPE + "= ?",
//类型为“video/mp4”
new String[]{"video/mp4"},
//默认排序
null);
MediaStore.Files没有EXTERNAL_CONTENT_URI,所以只能用getContentUri()自行获取,得出的URI其实是
Uri.parse("content://media/external/files")
这个不难理解,以MediaStore.Images.Media为例,其URI有三种写法:
Uri uri1 = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri uri2 = MediaStore.Images.Media.getContentUri("external");
Uri uri3 = Uri.parse("content://media/external/images/media");
三种写法得到的URI其实是同一个。
使用MediaStore.Files获取的cursor再进行查询操作,得到的结果要更全面一些;
但是因为MediaStore依赖于MediaScanner的扫描存储,而MediaScanner主要作用还是扫描SD卡中的多媒体文件,所以查询内部存储可能仍然会有纰漏,尤其是对/data一类需要系统权限的内部存储目录,经常会出现查询不到的状况。