一、实现的功能

1、扫描虚拟机sdcard目录下所有的MP3音乐文件,并以列表的形式显示

2、点击想听的音乐,跳转至播放界面进行播放

3、播放界面中功能包括播放、暂停、停止、播放上一首、播放下一首、循环播放、显示当前播放时间、总播放时间,能进度条的拖拽进行快进等功能

二、界面截图

      

                        选择歌曲列表                                                   播放界面、具体功能都在底部

 三、关键代码

歌曲列表中ListView显示sdcard目录下所有的MP3文件

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_music);
        if(root.exists())
        {
            dirFiles = root.listFiles();
        }
        for (File dirFile : dirFiles) {
            if (dirFile.getAbsolutePath().endsWith(".mp3") || dirFile.getAbsolutePath().endsWith(".MP3")) {
                mp3Files.add(dirFile.getAbsolutePath());
                musicName.add(dirFile.getName());
            }
        }

        final  ListView listView = (ListView)findViewById(R.id.allMusic);

        listView.setAdapter(new MyAdapter(SelectMusicActivity.this,musicName));

点击相应歌曲跳转页面并传对应的歌曲编号

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent(SelectMusicActivity.this,MainActivity.class);
                Bundle bundle = new Bundle();
                bundle.putInt("id",i);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });

 ListView对应的适配器类中显示文件信息

public View getView(final int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if (view == null) {
            viewHolder = new ViewHolder();
            view = LayoutInflater.from(mContext).inflate(R.layout.allmusic_item, null);
            viewHolder.mPhoto = (ImageView) view.findViewById(R.id.photo);
            viewHolder.mMusicName = (TextView)view.findViewById(R.id.MusicName);
            viewHolder.mIcon = (ImageView)view.findViewById(R.id.micon);
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        viewHolder.mPhoto.setImageResource(pic[i%7]);
        viewHolder.mMusicName.setText(mList.get(i));
        viewHolder.mIcon.setImageResource(R.drawable.stopmusic);
        return view;
    }

播放、暂停功能的实现

play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mediaPlayer != null) {
                    Completion();
                    new MyThre().start();
                }
                else if(mediaPlayer.isPlaying()){
                    mediaPlayer.pause();
                    play.setImageResource(R.drawable.stopmusic);
                }
                else if(!mediaPlayer.isPlaying()){
                    mediaPlayer.start();
                    int duration = mediaPlayer.getDuration();//获取音乐的总时长
                    seekBar.setMax(duration);//设置进度条的最大值为音乐的总时长
                    if(duration%60000/1000>=0 && duration%60000/1000<=9)
                        totaltime.setText("0"+duration/60000+":0"+duration%60000/1000);
                    else
                        totaltime.setText("0"+duration/60000+":"+duration%60000/1000);
                    play.setImageResource(R.drawable.playmusic);
                }

            }
        });
 public void Completion(){
        play.setImageResource(R.drawable.playmusic);
        if(mediaPlayer.isPlaying()) {
            mediaPlayer.reset();
        }
        mediaPlayer = new MediaPlayer();
        file = new File(String.valueOf(mp3Files.get(number)));//获取音乐路径
        name.setText(MusicNames.get(number));
        icon.setImageResource(singerphotos[number%7]);
        try {
            mediaPlayer.setDataSource(MainActivity.this, Uri.parse(file.getPath()));//设置音乐路径
            mediaPlayer.prepare();//播放前准备
            int duration = mediaPlayer.getDuration();//获取音乐的总时长
            seekBar.setMax(duration);//设置进度条的最大值为音乐的总时长
            if(duration%60000/1000>=0 && duration%60000/1000<=9)
                totaltime.setText("0"+duration/60000+":0"+duration%60000/1000);
            else
                totaltime.setText("0"+duration/60000+":"+duration%60000/1000);
            mediaPlayer.seekTo(0);
            seekBar.setProgress(0);
        } catch (IOException e) {
            e.printStackTrace();
        }
        mediaPlayer.start();
    }

播放上一首

premusic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                number--;
                if(number == -1)
                    number=mp3Files.size()-1;
                Completion();
            }
        });

播放下一首

nextmusic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                number++;
                if(number == mp3Files.size())
                    number = 0;
                Completion();
            }
        });

停止播放

stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mediaPlayer.isPlaying()) {
                    mediaPlayer.reset();
                    file = new File(String.valueOf(mp3Files.get(number)));//获取音乐路径
                    try {
                        mediaPlayer.setDataSource(MainActivity.this, Uri.parse(file.getPath()));//设置音乐路径
                        seekBar.setProgress(0);
                        mediaPlayer.prepare();//播放前准备
                    } catch (IOException e) {//抛出异常
                        e.printStackTrace();
                    }
                    play.setImageResource(R.drawable.stopmusic);
                }
            }
        });

进度条的拖动

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int current = mediaPlayer.getCurrentPosition();
                if(current%60000/1000>=0 && current%60000/1000<=9)
                    nowtime.setText("0"+current/60000+":0"+current%60000/1000);
                else
                    nowtime.setText("0"+current/60000+":"+current%60000/1000);
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                int progress = seekBar.getProgress();//获取拖动结束之后的位置
                mediaPlayer.seekTo(progress);//跳转到某个位置播放
                play.setImageResource(R.drawable.playmusic);
                mediaPlayer.start();
            }
        });

进度条的实时更新播放进度

private class MyThre extends Thread{
        @Override
        public void run() {
            super.run();
            while(seekBar.getProgress()<=seekBar.getMax()){
                handler.sendEmptyMessage(mediaPlayer.getCurrentPosition());
                try{
                    MyThre.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

四、代码链接

https://git.coding.net/qhu_1600802113/MusicPlayer.git

五、APK链接

 https://coding.net/u/qhu_1600802113/p/MusicPlayer/git/tree/master/app

六、APP操作视频网址

http://www.iqiyi.com/w_19s4yjd6jh.html