Android本地音乐播放器

Android本地音乐播放器_第1张图片

UI界面模仿QQ音乐
实现一个简单的本地播放器,功能包括:播放,暂停,上一曲,下一曲,进度条。

功能实现

读取本地音乐
1.创建一个Song类

public class Song {
    public String song;//歌曲名
    public String singer;//歌手
    public long size;//歌曲所占空间大小
    public int duration;//歌曲时间长度
    public String path;//歌曲地址
    public String album;//专辑名
}

2.用于获取本地音乐的Utils

public class Utils {
    //定义一个集合,存放从本地读取到的内容
    public static List list;
    public static Song song;
    public static List getmusic(Context context) {
        list = new ArrayList<>();
        Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                null, null, null, MediaStore.Audio.AudioColumns.IS_MUSIC);
        if (cursor != null) {
            while (cursor.moveToNext()) {
                song = new Song();
                song.song = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
                song.album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
                song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
                song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                song.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
                //把歌曲名字和歌手切割开
                if (song.size > 1000 * 800) {
                    if (song.song.contains("-")) {
                        String[] str = song.song.split("-");
                        song.singer = str[0];
                        song.song = str[1];
                    }
                    list.add(song);
                }
            }
        }
        cursor.close();
        return list;
    }
    //    转换歌曲时间的格式
    public static String formatTime(int time) {
        if (time / 1000 % 60 < 10) {
            String tt = time / 1000 / 60 + ":0" + time / 1000 % 60;
            return tt;
        } else {
            String tt = time / 1000 / 60 + ":" + time / 1000 % 60;
            return tt;
        }
    }
}

3.在布局里面定义一个ListView,并写一个适配器

//适配器
    class MyAdapter extends BaseAdapter {
        Context context;
        List list;
        private int mSelect;   //选中项
        public MyAdapter(MainActivity mainActivity, List list) {
            this.context = mainActivity;
            this.list = list;
        }
        @Override
        public int getCount() {
            return list.size();
        }
        @Override
        public Object getItem(int i) {
            return list.get(i);
        }
        @Override
        public long getItemId(int i) {
            return i;
        }
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            Myholder myholder;
            if (view == null) {
                myholder = new Myholder();
                view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.text, null);
               // myholder.t_position = view.findViewById(R.id.t_postion);
                myholder.t_song = view.findViewById(R.id.t_song);
                myholder.t_singer = view.findViewById(R.id.t_singer);
                myholder.t_blank=view.findViewById(R.id.t_blank);
                myholder.t_albumn=view.findViewById(R.id.t_albumn);
                myholder.t_point=view.findViewById(R.id.t_point);
                myholder.t_duration = view.findViewById(R.id.t_duration);
                view.setTag(myholder);
            } else {
                myholder = (Myholder) view.getTag();
            }
            myholder.t_song.setText(list.get(i).song.toString());
            myholder.t_singer.setText(list.get(i).singer.toString());
            String time = Utils.formatTime(list.get(i).duration);
            myholder.t_albumn.setText(list.get(i).album.toString());
            myholder.t_duration.setText(time);
            //myholder.t_position.setText(i + 1 + "");
            //设置相关数据
            if (mSelect==-1){
                myholder.t_song.setEnabled(true);
                myholder.t_singer.setEnabled(true);
                myholder.t_blank.setVisibility(View.INVISIBLE);
                //选中项背景
                myholder.t_song.setTextColor(getResources().getColor(R.color.tilte_color));
                myholder.t_singer.setTextColor(getResources().getColor(R.color.tilte_color));
                myholder.t_albumn.setTextColor(getResources().getColor(R.color.tilte_color));
                myholder.t_point.setTextColor(getResources().getColor(R.color.tilte_color));
            }
            if (mSelect == i) {
                myholder.t_song.setEnabled(true);
                myholder.t_singer.setEnabled(true);
                myholder.t_blank.setVisibility(View.VISIBLE);
                //选中项背景
                myholder.t_song.setTextColor(getResources().getColor(R.color.theme));
                myholder.t_singer.setTextColor(getResources().getColor(R.color.theme));
                myholder.t_albumn.setTextColor(getResources().getColor(R.color.theme));
                myholder.t_point.setTextColor(getResources().getColor(R.color.theme));
                myholder.t_duration.setTextColor(getResources().getColor(R.color.theme));
            } else {
                myholder.t_song.setEnabled(false);
                myholder.t_singer.setEnabled(false);
                myholder.t_blank.setVisibility(View.INVISIBLE);
                //其他项背景
                myholder.t_song.setTextColor(getResources().getColor(R.color.tilte_color));
                myholder.t_singer.setTextColor(getResources().getColor(R.color.song));
                myholder.t_albumn.setTextColor(getResources().getColor(R.color.song));
                myholder.t_point.setTextColor(getResources().getColor(R.color.song));
                myholder.t_duration.setTextColor(getResources().getColor(R.color.song));
            }
            return view;
        }
        class Myholder {
            ImageView t_blank;
            TextView t_position, t_song, t_singer, t_duration,t_albumn,t_point;
        }
        //刷新方法
        public void changeSelected(int positon){
            if (positon != mSelect) {
                mSelect = positon;
                notifyDataSetChanged();
            }
        }
    }

在类里面定义一个刷新位置的方法changeSelectde与ListView的点击监听事件配合使用,用于ListView被点击后将position参数传入,相应的文字颜色的改变
4.给ListView设置适配器

mylist = (ListView) findViewById(R.id.mylist);
        list = new ArrayList<>();
        list = Utils.getmusic(this);//获取音乐
        myAdapter = new MyAdapter(this, list);
        mylist.setAdapter(myAdapter);

5.使用MediaPlayer播放音乐
把音乐读取到ListView之后,点击音乐列表的音乐,就能够进行音乐的播放,并在底栏显示相应的音乐名,歌手名,可以拖动进度条进行音乐的控制,点击相应的按钮能够暂停,上一曲,下一曲。
首先封装一个播放音乐的方法,传入的参数currentPosition为音乐的位置

private void musicPlay(int currentPosition) {
           seekBar.setMax(list.get(currentPosition).getDuration());
           try {
               // 重置音频文件,防止多次点击会报错
               mediaPlayer.reset();
               //调用方法传进播放地址
               mediaPlayer.setDataSource(list.get(currentPosition).getPath());
               //异步准备资源,防止卡顿
               mediaPlayer.prepareAsync();
               //调用音频的监听方法,音频准备完毕后响应该方法进行音乐播放
               mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                   @Override
                   public void onPrepared(MediaPlayer mediaPlayer) {
                       mediaPlayer.start();//开始播放
                       Thread thread = new Thread(new SeekBarThread());//更新SeekBar的线程
                       thread.start();
                   }
               });
           } catch (Exception e) {
           e.printStackTrace();
       }
   }

然后为ListView设置点击事件

mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                currentPosition=position;
                musicPlay(currentPosition);//播放音乐
                myAdapter.changeSelected(currentPosition);//设置字体变色
                play.setVisibility(View.INVISIBLE);//播放按钮消失
                pause.setVisibility(View.VISIBLE);//暂停按钮出现
                String song=list.get(currentPosition).song;//获取音乐名
                String singer=list.get(currentPosition).singer;//获取歌手名
                bottomSong.setText(song);//底栏显示音乐名
                bottomSinger.setText(singer);//底栏显示歌手名
                gang.setVisibility(View.VISIBLE);//横杠

            }
        });

播放,暂停,上一曲,下一曲按钮点击事件

//暂停按钮
        pause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    mediaPlayer.pause();//暂停音乐
                    pause.setVisibility(View.INVISIBLE);
                    play.setVisibility(View.VISIBLE);
            }
        });
        //播放按钮
        play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                play.setVisibility(View.INVISIBLE);
                pause.setVisibility(View.VISIBLE);
                mediaPlayer.start();//播放音乐
            }
        });
        /**
         * 下一曲
         */
        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentPosition++;
                if (currentPosition > list.size() - 1) {
                    currentPosition = 0;
                }
                musicPlay(currentPosition);
                myAdapter.changeSelected(currentPosition);//ListView颜色变化
                //底栏设置正在播放的歌曲信息
                String song=list.get(currentPosition).song;
                String singer=list.get(currentPosition).singer;
                bottomSong.setText(song);
                bottomSinger.setText(singer);
                gang.setVisibility(View.VISIBLE);
            }
        });
        /**
         * 上一曲
         */
        pre.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentPosition--;
                if (currentPosition < 0) {
                    currentPosition = list.size() - 1;
                }
                musicPlay(currentPosition);
                myAdapter.changeSelected(currentPosition);//ListView颜色变化
                //底栏设置正在播放的歌曲信息
                String song=list.get(currentPosition).song;
                String singer=list.get(currentPosition).singer;
                bottomSong.setText(song);
                bottomSinger.setText(singer);
                gang.setVisibility(View.VISIBLE);
            }
        });

给mediaPlayer添加一个监听事件,实现当前音乐播放完成后自动播放下一首的功能

mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                currentPosition++;
                if (currentPosition > list.size() - 1) {
                    currentPosition = 0;
                }
                musicPlay(currentPosition);
                myAdapter.changeSelected(currentPosition);
                //底栏设置正在播放的歌曲信息
                String song=list.get(currentPosition).song;
                String singer=list.get(currentPosition).singer;
                bottomSong.setText(song);
                bottomSinger.setText(singer);
                gang.setVisibility(View.VISIBLE);
            }
        });

5.进度条
使用Handler类,进行SeekBar的更新

private static final int UPDATE_SEEKBAR=0;
    private Handler  handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case UPDATE_SEEKBAR:
                    // 将SeekBar位置设置到当前播放位置
                    seekBar.setProgress(mediaPlayer.getCurrentPosition());
                    break;
                default:
                    break;
            }
        }
    };

定义一个类,实现Runnable接口进行SeekBar状态的刷新

class SeekBarThread implements Runnable {
        @Override
        public void run() {
            while (mediaPlayer.isPlaying()) {
                try {
                    // 每500毫秒更新一次位置
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Message message=new Message();
                message.what=UPDATE_SEEKBAR;
                handler.sendMessage(message);
            }
        }
    }

给SeekBar添加监听事件,实现拖动进度条改变音乐进度

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
              if(fromUser==true){
                  mediaPlayer.seekTo(progress);
              }
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
    }

源码下载链接:
下载链接

你可能感兴趣的:(Android本地音乐播放器)