在最初的构思中,我使用的是File类递归遍历SD卡中的所有文件,然后筛选出以".mp3"格式结尾的文件,放入一个map.然后将map放入List,让media加载.
但是,发现这样的方法耗时比较长,容易出现"卡住"的现象,然后就想将List永久化存到本地,但是发现如果有几百首歌的话,文件太大了,非常占内存控件.在查阅了一些资料后,发现android手机自身就有一个媒体库,可以直接查询.在多次尝试后,终于成功读取文件.这里做一个笔记.
一,获取ContextResolver实例;
方法:ContexrResolver cr=context.getContextResolver();
解释:context 表示Activity.this的这种context,就是要进行操作的Activity中的Context.
当使用getContextResolver();方法得到ContextResolver对象后,就可以直接查询了.
二,使用Cursor对象;
方法:
1,Cursor c=cr.getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder)
这里的cr就是前面得到的ContextResolver对象;这种方式必须先实例化ContextResolver对象.
那么,能不能直接实例出来呢?可以啊的哟~
2,Cursor c=context.getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder)
只要将context.getContextResolver()直接使用就可以了.两种方式不会出错,根据实际情况使用不同的方式吧.
参数的意义:
Uri:指明要查询的数据库名称加上表的名称,从MediaStore中可以找到相应信息的参数,具体请参考开发文档。
Projection: 指定查询数据库表中的哪几列,返回的游标中将包括相应的信息。Null则返回所有信息。
selection: 指定查询条件
selectionArgs:参数selection里有 ?这个符号是,这里可以以实际值代替这个问号。如果selection这个没有?的话,那么这个String数组可以为null。
SortOrder:指定查询结果的排列顺序
三,MediaStore数据库
主语句:
MediaStore.Audio :存放音频信息 MediaStore.Image :存放图片信息 MediaStoue.Video :存放视频信息
这三个是基本的三大文件信息,每个类后面还有许多方法和参数.目前我用到的是音频信息,其他的还没用到,想来方法应该差不多.
1,MediaStore.Audio查询参数:
首先我们要查询的是媒体文件,就是Media类,所以在主语句后面加上:Media
变成了:MediaStore.Audio.Media;
好,现在我们要查询的是媒体的一些信息,这里我搜集了一些常用的属性大家可以参考一下:
MediaStore.Audio.Media._ID; //内部ID
MediaStore.Audio.Media.DISPLAY_NAME;//音乐名称
MediaStore.Audio.Media.TITLE; //音乐标题
MediaStore.Audio.Media.ARTIST; //演唱者
MediaStore.Audio.Media.ALBUM; //所属专辑
MediaStore.Audio.Media.DURATION; //音乐时长
MediaStore.Audio.Media.DATA; //音乐路径
以上是一些查询文件时常用的属性.那么我们如何使用这些属性呢?
我搜到查询两种方式:
第一种:
这里我使用的就是直接将ContextResolver对象放在语句里面.
在获取音乐时长的时候要注意一点,这里的时长是没有转换的,我也不知道是按秒还是毫秒,反正打印出来老长一串.那么,我们就需要转化一下:
public class tools {
/**
* 转换时间
*
* @param time
* @return
*/
public static String formatTime(long time) {
String min = time / (1000 * 60) + "";
String sec = time % (1000 * 60) + "";
if (min.length() < 2) {
min = "0" + time / (1000 * 60) + "";
} else {
min = time / (1000 * 60) + "";
}
if (sec.length() == 4) {
sec = "0" + (time % (1000 * 60)) + "";
} else if (sec.length() == 3) {
sec = "00" + (time % (1000 * 60)) + "";
} else if (sec.length() == 2) {
sec = "000" + (time % (1000 * 60)) + "";
} else if (sec.length() == 1) {
sec = "0000" + (time % (1000 * 60)) + "";
}
return min + ":" + sec.trim().substring(0, 2);
}
}
啊~不是我写的,网上抄来的.哈哈哈.可以看到在获取时长的那一段之前我就用了.
第一种方法,个人感觉比较清晰一点.
public static List<Map<String, String>> findMusicFileUseCuesor(
Context context) {
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
if (cursor.moveToFirst()) {
do {
Map<String, String> map = new HashMap<String, String>();
// 获得音乐ID
map.put("_id",
cursor.getString(
cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID))
.toString());
// 获得音乐名称
map.put("name",
cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)));
// 获得音乐标题
map.put("tittle", cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)));
// 获得音乐歌手
map.put("artist", cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)));
// 获得音乐专辑
map.put("album", cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)));
// 获得音乐时长
map.put("duration",
tools.formatTime(cursor.getLong(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))));
// 获得音乐路径
map.put("path", cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));
list.add(map);
} while (cursor.moveToNext());
}
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
System.out.println("list :---->" + list.get(i).toString());
}
return list;
}
return null;
}
第二种方法:
public static List<Map<String, String>> findMusicFileFromPhone(
Context context) {
Cursor cursor = context.getContentResolver().query(Parameter.MEDIA_URI,
Parameter.MEDIA_PROJECTION, Parameter.MEDIA_SELECTION,
Parameter.MEDIA_SELECTIONARGS, null);
List<Map<String, String>> musicDate = new ArrayList<Map<String, String>>();
while (cursor.moveToNext()) {
Map<String, String> map = new HashMap<String, String>();
map.put("tittle", cursor.getString(0));
map.put("artist", cursor.getString(1));
map.put("durtion", tools.formatTime(cursor.getLong(2)));
map.put("path", cursor.getString(3));
musicDate.add(map);
}
if (musicDate.size() > 0) {
return musicDate;
} else {
System.out.println("musicDate :" + musicDate.size());
return null;
}
}
第二个方法的参数:
public static final Uri MEDIA_URI = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
public static final String[] MEDIA_PROJECTION = {
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATA };
public static final String[] MEDIA_SELECTIONARGS = { "audio/mpeg","audio/x-ms-wma" };
public static final String MEDIA_SELECTION = MediaStore.Audio.Media.MIME_TYPE+ "=? or " + MediaStore.Audio.Media.MIME_TYPE + "=?";
这里在后两句话是什么意思我大概猜得到,但还是希望大牛能给解释一下...
特别是最后一句,应该是筛选类型,网上看说"?"的地方可以自己定义,可以我一改这代码就报错了.不知道为啥....我试过.MP3和MP3小写的也试过...=.=求科普..
这种方式呢,我觉得一是看起来比较乱..(好吧,其实是我写的不好).二呢,总觉得在写的时候写死数据不太好,比如:
map.put("tittle", cursor.getString(0));
如果参数顺序改了的话,那就逗逼了...
但是这种方式在更新,增加,删除,操作的时候比较方便.@^@吧....?
好吧,笔记先记到这里,继续研究研究.....
转载于:https://blog.51cto.com/66390099/1558100