界面如下:
![](http://static.oschina.net/uploads/img/201605/11091850_iAiJ.jpg)
![](http://static.oschina.net/uploads/img/201605/11091851_tiBc.jpg)
![](http://static.oschina.net/uploads/img/201605/11091852_iZPq.jpg)
![](http://static.oschina.net/uploads/img/201605/11091853_tlz5.jpg)
说明一下实现这个音乐播放器的思路。
首先,打开应用后查找手机上所有的音乐,放在Application中。这样做避免以后查找播放音乐的时候使用静态变量(上个应用就是应为大量使用静态变量,内存消耗太大,Activity老是被回收,所以这次直接把要使用的数据放在Application,使用的时候再取出来)
获取手机上所有音乐(有个缺点,就是所有是声音的文件都查找出来了,这部分以后还要优化,优化成自定义扫描目录,获获取手机上歌曲。)
代码如下:
<pre name="code" class="java"> private List<Music> musiclist;
@Override
public void onCreate() {
super.onCreate();
searchMusicONPhone();
}
/**
* 查找手机上所有歌曲
*/
private void searchMusicONPhone(){
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
musiclist = new ArrayList<Music>();
if(cursor == null || cursor.getCount() <= 0){
setMusiclist(musiclist);
}else{
while(cursor.moveToNext()){
Music music = new Music();
music.setId(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media._ID))); //歌曲ID
music.setTitle(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)));//歌曲的名称
music.setAlbum(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM))); //歌曲的专辑名
music.setArtists(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST))); //歌曲的歌手名
music.setTimes(toTime(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))));//歌曲的总播放时长
music.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));//歌曲文件的路径
music.setSize(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)));//歌曲文件的大小
musiclist.add(music);
}
setMusiclist(musiclist);
}
if(cursor != null){
cursor.close();
cursor = null;
}
}
public List<Music> getMusiclist() {
return musiclist;
}
public void setMusiclist(List<Music> musiclist) {
this.musiclist = musiclist;
}
在Activity中获取歌曲代码如下:
mApplication = (MyApplication)getApplication();
musiclist = mApplication.getMusiclist();
第二步:当点击播放音乐的时候,传递给Service音乐id,在后台打开音乐。代码如下:
1、在<manifest>中
声明<service>
<service
android:name="com.mini.service.MusicService">
<intent-filter>
<action android:name="com.app.media.music_service"/>
</intent-filter>
</service>
2、创建自己的Service
package com.mini.service;
import java.io.IOException;
import java.util.List;
import com.mini.MyApplication;
import com.mini.R;
import com.mini.activity.base.BaseActivity;
import com.mini.bean.Music;
import com.mini.constans.Constants;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.MediaStore;
@SuppressLint("HandlerLeak")
public class MusicService extends Service implements MediaPlayer.OnCompletionListener {
private MyApplication mApplication;
private List<Music> mList;
private MediaPlayer mPlayer;
private int op;
private Uri uri;
private int id;
private int position;
private int currentTime;
private Handler mHandler;
private int duration;
@Override
public void onCreate() {
super.onCreate();
mApplication = (MyApplication)getApplication();
mList = mApplication.getMusiclist();
if(mPlayer != null){
mPlayer.reset();
mPlayer.release();
mPlayer = null;
}
mPlayer = new MediaPlayer();
mPlayer.setOnCompletionListener(this);
}
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
position = intent.getIntExtra("idOption", -1);
if(position == -1){
}else{
playMusic();
}
op = intent.getIntExtra("op", -1);
switch (op) {
case Constants.MUSIC_PLAY:
playing();
break;
case Constants.MUSIC_PAUSE:
pause();
break;
case Constants.MUSIC_STOP:
stop();
break;
case Constants.PROGRESS_CHANGE:
currentTime = intent.getExtras().getInt("progress");
mPlayer.seekTo(currentTime);
break;
case -1:
setUp();
initBorderCastService();
break;
default:
break;
}
}
/**
* 初始化歌曲信息、进度条
*/
private void setUp(){
final Intent intent = new Intent();
intent.setAction(Constants.MUSIC_DURATION);
try {
if(!mPlayer.isPlaying()){
mPlayer.prepare();
}
mPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mHandler.sendEmptyMessage(1);
}
});
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
duration = mPlayer.getDuration();
intent.putExtra("duration", duration);
sendBroadcast(intent);
}
/**
* 初始化广播机制
*/
private void initBorderCastService(){
final Intent intent = new Intent();
intent.setAction(Constants.MUSIC_CURRENT);
if(mHandler == null){
mHandler = new Handler(){
public void handleMessage(Message msg){
if(msg.what == 1){
currentTime = mPlayer.getCurrentPosition();
intent.putExtra("currentTime", currentTime);
if(position == -1){
intent.putExtra("position",intent.getIntExtra("position", -1));
}else{
intent.putExtra("position",position);
}
sendBroadcast(intent);
}
mHandler.sendEmptyMessageDelayed(1, 1000);
}
};
}
}
/**
* 播放歌曲
*/
private void playing(){
if(mPlayer != null){
mPlayer.start();
}
}
/**暂停*/
private void pause() {
if (mPlayer != null) {
mPlayer.pause();
}
}
/** 停止*/
private void stop() {
if (mPlayer != null) {
mPlayer.stop();
try {
mPlayer.prepare();
mPlayer.seekTo(0);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mHandler.removeMessages(1);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private static int i;
@Override
public void onCompletion(MediaPlayer mp) {
nextMusic();
}
private void nextMusic() {
switch (BaseActivity.loop_method) {
case Constants.LOOP_ONE:
break;
case Constants.LOOP_ALL:
if (position == mList.size()-1) {
position = 0;
} else if (position < mList.size()-1) {
position++;
}
break;
case Constants.LOOP_NONE:
position = BaseActivity.mRandomID();
break;
default:
break;
}
playMusic();
setUp();
initBorderCastService();
playing();
}
public void playMusic(){
id = mList.get(position).getId();
uri = Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id + "");
try {
mPlayer.reset();
mPlayer.setDataSource(this,uri);
mPlayer.prepare();
mPlayer.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、播放事件
/**
* 随机播放音乐事件
*/
radom_begin_music.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
myPosition = mRandomID();
Intent intent = new Intent();
intent.setAction("com.app.media.music_service");
intent.putExtra("idOption", myPosition);
startService(intent);
flag = Constants.MUSIC_PAUSE;
}
});
接下来是细节问题,比如进度条改变,暂停音乐,继续播放。。
1、进度条改变是通过Service不断发送广播,然后在Activity中接收广播
/**
* 接收广播,更新歌曲的进度
*/
protected BroadcastReceiver musicReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
String actionString = intent.getAction();
if(actionString.equals(Constants.MUSIC_CURRENT)){
currentPosition = intent.getExtras().getInt("currentTime");
position = intent.getExtras().getInt("position");
music_durtion_sBar.setProgress(currentPosition);
music_preform_time.setText(toTime(currentPosition));
bottomUpdate();
}else if(actionString.equals(Constants.MUSIC_DURATION)){
duration = intent.getExtras().getInt("duration");
music_durtion_sBar.setMax(duration);
}
}
};
2、底部的暂停播放按钮事件
/**
* 底部播放暂停按钮
*/
bottom_play_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
switch (flag) {
case Constants.MUSIC_PAUSE:
pause();
break;
case Constants.MUSIC_PLAY:
play();
break;
default:
break;
}
}
});
/**
* 播放音乐
*/
public void play() {
flag = Constants.MUSIC_PAUSE;
bottom_play_btn.setBackgroundResource(R.drawable.bottom_play);
Intent intent = new Intent();
intent.setAction("com.app.media.music_service");
intent.putExtra("op", Constants.MUSIC_PLAY);// 向服务传递数据
startService(intent);
}
/**
* 暂停
*/
public void pause() {
flag = Constants.MUSIC_PLAY;
bottom_play_btn.setBackgroundResource(R.drawable.bottom_pause);
Intent intent = new Intent();
intent.setAction("com.app.media.music_service");
intent.putExtra("op", Constants.MUSIC_PAUSE);
startService(intent);
}
3、下一首事件代码
/**
* 下一首
*/
public void nextOne() {
stop();
setup();
playNext();
}
public void playNext() {
flag = Constants.MUSIC_PAUSE;
int music_id = position;
switch (loop_method) {
case Constants.LOOP_ONE:
music_id = position;
break;
case Constants.LOOP_ALL:
if (position == musiclist.size()-1) {
position = 0;
music_id = position;
} else if (position < musiclist.size()-1) {
position++;
music_id = position;
}
break;
case Constants.LOOP_NONE:
music_id = mRandomID();
break;
default:
break;
}
bottom_play_btn.setBackgroundResource(R.drawable.bottom_play);
Intent intent = new Intent();
intent.setAction("com.app.media.music_service");
intent.putExtra("idOption", music_id);// 向服务传递数据
startService(intent);
}
/**
* 停止播放音乐
*/
private void stop() {
unregisterReceiver(musicReceiver);
Intent intent = new Intent();
intent.setAction("com.app.media.music_service");
intent.putExtra("op", Constants.MUSIC_STOP);
startService(intent);
}
/**
* 初始化
*/
private void setup() {
init();
}
这里可以下载源码:http://download.csdn.net/detail/yan943789510/8615689