代码已经托管到码云,有兴趣的小伙伴可以下载看看
效果图:
Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,并且提供了一套数据库表格,通过Content Provider的方式提供给用户。当手机开机或者有SD卡插拔等事件发生时,系统将会自动扫描SD卡和手机内存上的媒体文件,如audio,video,图片等,将相应的信息放到定义好的数据库表格中。在这个程序中,我们不需要关心如何去扫描手机中的文件,只要了解如何查询和使用这些信息就可以了。
MediaStore中定义了一系列的数据表格,通过ContentResolver提供的查询接口,我们可以得到各种需要的信息。下面我们重点介绍查询SD卡上的音乐文件信息。
先来了解一下ContentResolver的查询接口:
Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder);
Uri:指明要查询的数据库名称加上表的名称,从MediaStore中我们可以找到相应信息的参数,具体请参考开发文档。
Projection: 指定查询数据库表中的哪几列,返回的游标中将包括相应的信息。Null则返回所有信息。
selection: 指定查询条件
selectionArgs:参数selection里有 ?这个符号是,这里可以以实际值代替这个问号。如果selection这个没有?的话,那么这个String数组可以为null。
SortOrder:指定查询结果的排列顺序
一、音乐播放器数据获取
1、根据videoPager里获取本地视频的方法,也是从Android系统里去获取本地音频
/**
* 从本地sd卡获取数据,有2中办法
* 1、遍历sd卡,根据后缀名
* 2、从内容提供者中获取,系统有自己会去扫描所有media信息。
* 3/6.0后的系统,需要加上动态权限
*/
private void getDataFromLocal() {
mediaList=new ArrayList<>();
new Thread(){
@Override
public void run() {
super.run();
SystemClock.sleep(2000);
//根据上下文,去获取内容解析者
ContentResolver resolver = context.getContentResolver();
Uri uri= MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] objs={
MediaStore.Audio.Media.DISPLAY_NAME, //视频文件名称
MediaStore.Audio.Media.DURATION, //视频时长
MediaStore.Audio.Media.SIZE, //文件大小
MediaStore.Audio.Media.DATA, //视频的绝对地址
MediaStore.Audio.Media.ARTIST, //歌曲的演唱者,艺术家(音频可能会有该字段)
};
Cursor cursor = resolver.query(uri, objs, null, null, null);
if (cursor!=null){
while(cursor.moveToNext()){
MediaItem item=new MediaItem();
String name=cursor.getString(0); //名称
item.setName(name);
long duration=cursor.getLong(1); //时长
item.setDuration(duration);
long size=cursor.getLong(2); //音频大小
item.setSize(size);
String data=cursor.getString(3); //音频的绝对地址
item.setData(data);
String artist=cursor.getString(4); //艺术家
item.setArtist(artist);
mediaList.add(item); //把每个item数据放到集合中
}
cursor.close();
}
//发消息,提示加载完media中的audio
handler.sendEmptyMessage(0);
}
}.start();
}
2、上面加载完所有音频数据后,会发消息给handler,handler里去setAdapter
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (mediaList!=null&&mediaList.size()>0){
//有数据
//设置适配器
myAdapter=new MyAdapter(context,mediaList,isVideo);
listview.setAdapter(myAdapter);
//Toast.makeText(context,"有数据",Toast.LENGTH_SHORT).show();
nomedia.setVisibility(View.GONE);
}else{
//没有数据
//文本显示
Toast.makeText(context,"没有数据",Toast.LENGTH_SHORT).show();
}
pb_loding.setVisibility(View.GONE);
//progressbar隐藏
}
};
3、在公用的MyAdapter里来展示listview的数据
package com.yuanlp.mobileplayer.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.yuanlp.mobileplayer.R;
import com.yuanlp.mobileplayer.bean.MediaItem;
import com.yuanlp.mobileplayer.utils.Utils;
import java.util.List;
/**
* Created by 原立鹏 on 2017/7/16.
*/
public class MyAdapter extends BaseAdapter {
private Context context;
private List<MediaItem> mediaList;
private Utils utils;
private boolean isVideo;
public MyAdapter(Context context,List<MediaItem> mediaList,boolean isVideo){
this.context=context;
this.mediaList=mediaList;
this.isVideo=isVideo;
utils=new Utils();
}
@Override
public int getCount() {
return mediaList.size();
}
@Override
public Object getItem(int position) {
return mediaList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=null;
if (convertView==null){
View view = LayoutInflater.from(context).inflate(R.layout.medialayout, null);
convertView=view;
viewHolder=new ViewHolder();
viewHolder.iv_icon= (ImageView) convertView.findViewById(R.id.iv_icon);
viewHolder.tv_name= (TextView) convertView.findViewById(R.id.tv_name);
viewHolder.tv_time= (TextView) convertView.findViewById(R.id.tv_time);
viewHolder.tv_size= (TextView) convertView.findViewById(R.id.tv_size);
convertView.setTag(viewHolder);
}else{
viewHolder= (ViewHolder) convertView.getTag();
}
//得到数据
MediaItem item=mediaList.get(position);
viewHolder.tv_name.setText(item.getName());
viewHolder.tv_size.setText(android.text.format.Formatter.formatFileSize(context,item.getSize()));
viewHolder.tv_time.setText(utils.stringForTime((int) item.getDuration()));
if (!isVideo){
//来自音频,那么就把listview的图片换掉
viewHolder.iv_icon.setImageResource(R.drawable.music_default_bg);
}
return convertView;
}
/**
* 公共的控件类,里面包含每一行要显示的控件
*/
private static class ViewHolder{
ImageView iv_icon;
TextView tv_name;
TextView tv_time;
TextView tv_size;
}
}
这样本地音乐也能展示并播放,但是播放页面共用的是视频的页面,比较丑,所以后面会做一个音乐专用的播放界面,到时候里面有歌词展示,敬请期待。
转载于:https://blog.51cto.com/cm0425/1951354