本地音乐播放器——简介篇

Posted xingxing_yan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了本地音乐播放器——简介篇相关的知识,希望对你有一定的参考价值。

花了一段时间写了一个比较简单基础的音乐播放器,实现功能如下:
1. 获取SD卡中的音频文件
2. 后台播放音乐
3. 切换播放模式
4. 切换上一首,下一首
5. 播放进度条,快进快退
6. 拔出耳机暂停播放
7. 如果有其他音乐播放器播放音乐,则暂停播放
功能看起来比较少,也很简单,但是要把这些所有功能整合一块还真有点不容易,下面,记录一下做的过程。

一. 首先来看获取sd卡中的音频文件:
我们都知道,android系统一般有一个数据库,这个库中存放着我们联系人,短信,音视频文件,图片等数据,而Android系统又把对这些数据的操作都封装成了相应的类,一般通过ContentResolver就可以操作这个数据库。今天需要读取音频文件,所以需要用到MediaStore这个类来获取音频数据,下边是写的一个获取sd卡音频文件的方法,最后会将数据封装成List返回(Music是一个实体类,存储音乐的一些信息,比较简单,这个就不贴代码了),如下:

public static List<Music> getMusicFile(Context context) 
        //生成动态数组,并且转载数据
        List<Music> MusicFiles = new ArrayList<Music>();

        //查询媒体数据库
        ContentResolver resolver = context.getContentResolver();
        Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
        //遍历媒体数据库
        if (cursor.moveToFirst()) 

            while (!cursor.isAfterLast()) 

                //歌曲编号
                int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
                //歌曲标题
                String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
                //歌曲的专辑名:MediaStore.Audio.Media.ALBUM
                String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
                //歌曲的歌手名: MediaStore.Audio.Media.ARTIST
                String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
                //歌曲文件的路径 :MediaStore.Audio.Media.DATA
                String url = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                //歌曲的总播放时长 :MediaStore.Audio.Media.DURATION
                int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                //歌曲文件的大小 :MediaStore.Audio.Media.SIZE
                long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));

                if (size > 1024 * 800) //大于800K
                    if (title.equals("<unknown>") || title.equals("")) 
                        title = "未知";
                    
                    if ("<unknown>".equals(artist) || "".equals(artist)) 
                        artist = "未知";
                    

                    Music music = new Music(id, title, artist,
                            url, album, duration, size);
                    MusicFiles.add(music);
                
                cursor.moveToNext();
            
        
        return MusicFiles;
    

可以看到,我们可以通过MediaStore拿到关于音乐文件的标题,歌手名,专辑,时间等信息,这个信息都存在Music中。我们只需要写一个activity,用listView将这些数据显示出来就好。
LocalMusicListActivity.java:

public class LocalMusicListActivity extends BaseActivty 
    private ListView mLvLocalMusic;
    private LocalMusicListAdapter mAdapter;
    private List<Music> mMusicDatas;
    private Context mContext = this;


    @Override
    protected void setLayout() 
        setContentView(R.layout.activity_local_music_list);
        mRight.setVisibility(View.INVISIBLE);
        mTitle.setText("本地歌曲");
    

    @Override
    protected void initView() 
        mLvLocalMusic = (ListView) findViewById(R.id.local_music_list);
        mMusicDatas = new ArrayList<Music>();
        mMusicDatas = Utils.getMusicFile(mContext);
        mAdapter = new LocalMusicListAdapter(this);
        mAdapter.resetData(mMusicDatas);
        mLvLocalMusic.setAdapter(mAdapter);
    

    @Override
    protected void setListener() 

    

到此,音频文件的读取和显示就完了,效果图如下:

二. 主界面的简介(MainActivity.java):
主界面我们主要显示的有歌曲名,已播放的时间,总播放时间,进度条,播放模式按钮,播放按钮,上一首,下一首按钮以及列表按钮和界面背景,效果图如下(这里就不贴布局代码了,后边会给出源码):

当然,在MainActivity内部需要有一个广播接收器来接受服务发过来的广播

class MusicReceiver extends BroadcastReceiver 

        @Override
        public void onReceive(Context context, Intent intent) 
            Bundle bundle = intent.getExtras();
            int activitySignal = bundle.getInt(Contants.ACTIVITY_SIGNAL, -1);
            switch (activitySignal) 
                case Contants.UPDATE_PLAY_ACTIVITY:
                    mMusicState = bundle.getInt(Contants.MUSIC_STATE);
                    mPlayingMusic = (Music) bundle.getSerializable(Contants.CURRENT_MUSIC);
                    mMusicMode = bundle.getInt(Contants.MUSIC_MODE);
                    mMusicPlayPosition = bundle.getInt(Contants.MUSIC_PLAY_POS, 0);
                    updateMusicInfo(mMusicMode, mMusicPlayPosition);
                    break;
            
        
    

服务发过来的任何广播都是为了更新界面,所以我们把需要更新的数据都封装在一起,不管是界面的那块需要更新,都会更新整个界面所有信息。

三. 服务的简单介绍(MusicServer.java):
既然服务的主要任务是播放音乐,那么服务中就需要一个MediaPlayer对象来播放音乐,还需要获取到sd卡中的音频文件,并且记录当前正在播放的音乐和位置,MusicServer的成员变量如下:

    private MediaPlayer mMediaPlayer;   //播放音乐对象
    private ServiceReceiver mReceiver;  //广播接收器(接收界面发来的广播)

    private Bundle mBundle;

    private List<Music> mMusicFiles;    //sd卡的音频文件集合
    private Music mPlayingMusic;    //当前正在播放的音乐
    private int mMusicPosition = 0;  //当前播放音乐在集合中的位置
    private int mMusicPlayPos = 0;  //当前音乐的播放位置
    private int mMusicState = Contants.STOP;    //音乐播放状态
    private int mMusicMode = Contants.MODE_MUSIC_LIST_ORDER;    //播放模式

    private PowerManager.WakeLock mWakeLock;    //电源锁对象

    private Timer mTimer;   //定时器
    private boolean isSeekbarChanged = false;   //进度条滑动标识

    private AudioManager mAmanager;
    MyOnAudioFocusChangeListener mListener;

当然,因为服务和界面是通过Broadcast进行通信的,所以MusicServer中肯定也要有一个接收器来接收服务发过来的广播:

    class ServiceReceiver extends BroadcastReceiver 

        @Override
        public void onReceive(Context context, Intent intent) 

        

    

广播接收器需要在onCreate方法和onDestroy方法中注册和解除。接下来需要初始化成员变量。
好了,此篇就介绍这些,下篇介绍主界面和服务初始化时需要做的事情

以上是关于本地音乐播放器——简介篇的主要内容,如果未能解决你的问题,请参考以下文章

iOS音频篇:使用AVPlayer播放网络音乐

酷狗音乐的URL怎么找?

iOS音频播放之AudioQueue:播放本地音乐

网易云音乐怎么看歌手的全部曲子

手机最新qq音乐怎么设置歌手写真

基于Vue2.0的音乐播放器——歌手模块(拿不到数据)