Android默认情况下会将每个多媒体文件的信息保存在一个数据库中。
(在系统收到某些消息,比如开机、插拔SD卡、设备连接上电脑这种涉及到可能更改文件系统内容的情况下,会触发系统扫描文件系统中的多媒体文件变化情况并同步到媒体数据库中;或者应用发送更新多媒体库广播时,也会触发多媒体数据库的更新),
应用在需要读取设备内指定格式的多媒体文件信息时,可以直接读取这个数据库,相比于文件全盘检索效率会高很多。
1.更新多媒体库广播
场景:在增加(下载完成)或者减少(删除)时候通知系统更新
String filepath = "filepath"
Uri contentUri = Uri.fromFile(new File(filepath));
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,contentUri);
getContext().sendBroadcast(mediaScanIntent);
这里的filepath 还是要通过
Environment.getExternalStorageDirectory().getAbsolutePath();
种方式获取比较稳妥。
2.查找多媒体文件
可以通过现有媒体库进行查找:举个栗子:
查找多媒体中过滤一定条件,如一定大小一定的文件体积的,文件大于100kb,时长大于100秒的可以这样写
String SELECTION = MediaStore.Audio.AudioColumns.SIZE + " >= ? AND " + MediaStore.Audio.AudioColumns.DURATION + " >= ?";
long filterSize = 100* 1024L;
long filterTime =100* 1000L;
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{
BaseColumns._ID,
MediaStore.Audio.AudioColumns.IS_MUSIC,
MediaStore.Audio.AudioColumns.TITLE,
MediaStore.Audio.AudioColumns.ARTIST,
MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.AudioColumns.ALBUM_ID,
MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.AudioColumns.DISPLAY_NAME,
MediaStore.Audio.AudioColumns.SIZE,
MediaStore.Audio.AudioColumns.DURATION
},
SELECTION,
new String[]{
String.valueOf(filterSize),
String.valueOf(filterTime)
},
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
看起来还是很简单的,context.getContentResolver().执行query语句,其中SELECTION是筛选条件语句,语句中对应的问号值在数组中。这样做的好处是安全,用问号代替参数,否则可能有数据泄露风险(SQl注入了解一下)。
3.查找指定目录下的文件
MediaStore.Audio.AudioColumns.DATA, 是文件的路径信息。
首先想到的是遍历寻找匹配加进列表。类似这种:
while (cursor.moveToNext()) {
//歌曲文件的路径 :MediaStore.Audio.Media.DATA
url = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
if(url.toLowerCase().indexOf("指定的歌曲路径") > 0)
{
......
}
}
cursor.close();
后又一想,直接在query 的条件中添加上 过滤条件不就好了。
String SELECTION = MediaStore.Audio.AudioColumns.SIZE + " >= ? AND " + MediaStore.Audio.AudioColumns.DURATION + " >= ? AND"+ MediaStore.Audio.AudioColumns.DATA+" like ?";
long filterSize = 100* 1024L;
long filterTime =100* 1000L;
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{
BaseColumns._ID,
MediaStore.Audio.AudioColumns.IS_MUSIC,
MediaStore.Audio.AudioColumns.TITLE,
MediaStore.Audio.AudioColumns.ARTIST,
MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.AudioColumns.ALBUM_ID,
MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.AudioColumns.DISPLAY_NAME,
MediaStore.Audio.AudioColumns.SIZE,
MediaStore.Audio.AudioColumns.DURATION
},
SELECTION,
new String[]{
String.valueOf(filterSize),
String.valueOf(filterTime),
"%指定的歌曲路径%"
},
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
这样就直接过滤出来了,其实还是sql 语句的拼凑,效率更高一点。
4.不想添加到多媒体库
在需要隐藏的目录建立一个文件名为“.nomedia”的空白文件,这样就不会被扫描了,但是不保证不会被第三方的有文件读写的权限的应用扫描到。