花了一段时间写了一个比较简单基础的音乐播放器,实现功能如下:
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() {

    }
}

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

如何查看本地sql server 如何查看本地音乐_如何查看本地sql server

二. 主界面的简介(MainActivity.java):

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

如何查看本地sql server 如何查看本地音乐_音乐_02

当然,在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方法中注册和解除。接下来需要初始化成员变量。
好了,此篇就介绍这些,下篇介绍主界面和服务初始化时需要做的事情