代码已经托管到码云,有兴趣的小伙伴可以下载看看

    https://git.oschina.net/joy_yuan/MobilePlayer


效果图:

    手机影音第十四天,本地音乐列表的展示与播放(利用视频播放的布局)_第1张图片


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 mediaList;
    private Utils utils;
    private boolean isVideo;
    public MyAdapter(Context context,List 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;
    }
}


    这样本地音乐也能展示并播放,但是播放页面共用的是视频的页面,比较丑,所以后面会做一个音乐专用的播放界面,到时候里面有歌词展示,敬请期待。