AndroidStudio 简单却功能完备的音乐播放器

本文详细介绍了一款功能丰富的音乐播放器的设计与实现过程,包括总体设计思路、具体功能模块如歌曲列表、播放控制等的设计与实现细节。

前言

课设设计作品,参考了网上很多资料和实例,整了一个功能齐全的播放器
发上来供大家借鉴学习,如果大家能继续改进就再好不过了。
实验目的:

  1. 学会如何使用 MediaPlayer 等媒体播放组件。
  2. 学会如何进行数据保存。

总体设计

设计介绍:
综合运用UI界面设计、数据存储、Activity(活动)、Service(服务)、MediaPlayer、ListView、RecyclerView等知识,设计开发一款具有音乐列表的音乐播放器。
设计步骤:
在这里插入图片描述

音乐播放器功能模块:

  1. 播放列表:能够读取手机中的音频文件,建立播放列表。
  2. 播放控制:能够对播放进行控制,能够开始/继续播放、暂停播放、上一
    首、下一首、单曲循环、列表播放,并能根据进度条自由选择播放进度。
  3. 播放历史:能够存储已播放过的历史,并能够清空历史。
  4. 歌单操作:能够在歌单页面建立额外的自定义歌单,并能够选择歌曲添加其中,并能够移除歌曲,删除歌单。
  5. 侧边栏:作为拓展辅助功能,方便操作,方便以后扩充。
  6. 搜索栏:根据所在页面,能够在搜索栏搜索需要的对象。

详细设计

程序流程:
在这里插入图片描述

扫描功能

歌曲JavaBean数据库文件Song.java,主要存储数据如下

public class Song implements Serializable {
   
   //javabean数据库
    public String id;      //歌曲id
    public String song;    //歌曲名称
    public String singer;  //歌手名称
    public String album;   //专辑名称
    public long duration;  //歌曲时长
    public String path;    //歌曲路径
    public long size;//大小

扫描本地歌曲对应文件:MusicUtils.java

public class MusicUtils {
   
   
    // 扫描系统里面的音频文件,返回一个list集合
    public static List<Song> getMusicData(Context context) {
   
   
        List<Song> list = new ArrayList<Song>();
        // 查询曲库
        //Cursor 提供遍历查询结果的方法//getcontentresolver访问数据//
        Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null,null, MediaStore.Audio.AudioColumns.IS_MUSIC);
        int id=-1;
            if (cursor != null) {
   
   //查询结果非空 {
   
   
                while (cursor.moveToNext()) {
   
   //循环查询数据库
                    Song song = new Song();//获取相应的属性值
                    song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                    song.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
                    if (song.duration>30*1000&&song.size > 1000 * 800) {
   
   
                    song.song = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
 //获取列,getColumnIndexOrThrow如果没找到该列名,会抛出IllegalArgumentExceptio异常
                    song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
                    song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                     song.album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
//获取相应的的属性值
                        if (song.song.contains(".mp3")) {
   
     //分离文件格式后缀
                            String[] str = song.song.split(".mp3");
                            song.song = str[0];
                        }
                        if (song.song.contains(".ogg")) {
   
   //分离文件格式后缀
                            String[] str = song.song.split(".ogg");
                            song.song = str[0];
                        }
                        if (song.song.contains(".flav")) {
   
   //分离文件格式后缀
                            String[] str = song.song.split(".flav");
                            song.song = str[0];
                        }  //分离后缀
                        if (song.song.contains("-")) {
   
   //用-分离歌名和歌手
                            String[] str = song.song.split("-");
                            song.singer = str[0];
                            song.song = str[1];
                        }
                        ++id;
                        String sid = String.valueOf(id+1);
                        song.id=sid;
                        list.add(song);//添加到表中
                    }
                }
                cursor.close();// 释放资源
            }
            return list;
        }

歌曲列表功能

音频数据适配器MyAdapter.java,将扫描到的音频文件进行数据适配,关键代码:

public void onBindViewHolder(@NonNull LocalMusicViewHolder holder, final int position) {
   
   
    Song musicBean = mDatas.get(position);
    if (musicBean != null) {
   
   //非空判断,防止报错
        holder.idTv.setText(musicBean.getId());
        holder.songTv.setText(musicBean.getSong());
        holder.singerTv.setText(musicBean.getSinger());
        holder.albumTv.setText(musicBean.getAlbum());
        //转换时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
        String time = sdf.format(new Date(musicBean.getDuration()));
        holder.timeTv.setText(time);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
   
   
            @Override
            public void onClick(View v) {
   
   
                onItemClickListener.OnItemClick(v, position);
            }
        });
    }
}
class LocalMusicViewHolder extends RecyclerView.ViewHolder{
   
   
    TextView idTv,songTv,singerTv,albumTv,timeTv;
    public LocalMusicViewHolder(View itemView) {
   
   
        super(itemView);
        idTv = itemView.findViewById(R.id.music_num);//id
        songTv = itemView.findViewById(R.id.music_song);//歌名
        singerTv = itemView.findViewById(R.id.music_singer);//歌手
        albumTv = itemView.findViewById(R.id.music_album);//专辑
        timeTv = itemView.findViewById(R.id.music_duration);//时长
    }
}

其中的id对应布局文件item_song.xml中的控件,布局效果如下
在这里插入图片描述
在MusicListActivity(歌曲列表Activity)初始化控件后再初始化数据。
初始化数据函数initData():

public static List<Song> list;
list = new ArrayList<>();//歌单数组
list.addAll(sheet.getList());
adapter = new MyAdapter(this,list);// 创建适配器对象
musicRv.setAdapter(adapter);
//musicRV为对应布局文件activity_music_list.xml中的RecyclerView控件的id
//设置布局管理器
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
musicRv.setLayoutManager(layoutManager);
adapter.notifyDataSetChanged();

播放控制功能

服务类:MusicService.java 包含与播放有关的函数,关键代码:

public class MyBinder extends Binder {
   
   
        public boolean setDatas(List<Song> musicBeans){
   
   //获取歌曲列表list
            Log.d("MusicService----0----", "setDatas");
            mDatas = musicBeans;
            musicDataSize = mDatas.size();
                      return true;
        }
                  public void setMusic(int Id){
   
   
            Log.d("MusicService----1----", "setMusic");
            //重置播放
            mediaPlayer.reset();
            //进度记录清零
            pausePosition=0;
            //设置新的音乐
            music_Id=Id;
            Song musicBean = mDatas.get(music_Id);
            try {
   
   
                //设置信息
                path = musicBean.getPath();
                mediaPlayer.setDataSource(path);
                music_song = musicBean.getSong();
                music_singer = musicBean.getSinger();
                music_duration = (int) musicBean.getDuration();
                // music_num=musicBean.getNum();
                //调用意图服务,更新activity内容
                Intent intentInfo = new Intent("com.example.musicapplication.intentService");
                intentInfo.setPackage(getPackageName());
                intentInfo.putExtra("music_id", music_Id);
                intentInfo.putExtra("music_song", music_song);
                intentInfo.putExtra("music_singer", music_singer);
                intentInfo.putExtra("music_duration", music_duration);
                // intentInfo.putExtra("music_duration", music_num);
                startService(intentInfo);
                myBinder.playMusic();
            } catch (IOException e) {
   
   
                e.printStackTrace();
            }

        }
        public void playMusic() {
   
   
            /* 播放音乐的函数*/
            Log.d("MusicService----2----", "playMusic");
            if (mediaPlayer != null && !mediaPlayer.isPlaying()) {
   
   
                if (pausePosition == 0) {
   
   
                    try {
   
   
                        mediaPlayer.prepare();
                        mediaPlayer.start();
                        playState=false;
                    } catch (IOException e) 
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值