1、MusicService
音乐播放器的Service,里面获取音乐文件,封装了MediaPlayer,实现播放上一首和下一首,播放,停止,封装成方法供Activity调用,获取音乐的当前进度,总长度、名字,通过发送广播的方式发给Activity
package com.example.musicplayer;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
public class MusicService extends Service {
private List<File> musicList;
private MediaPlayer player;
//选择把媒体播放器放在服务
public static final String MFILTER = "broadcast.intent.action.text";
public final static String NAME = "name";
public final static String TOTALTIME = "totaltime";
public final static String CURTIME = "curtime";
public int curPage;
class MyBinder extends Binder {
public MusicService getMusicService() {
return MusicService.this;
}
public MediaPlayer getPlayer() {
return player;
}
public void seekTo(int position)
{
if(player!=null)
{
player.seekTo(position);
}
}
}
//获取当前播放进度
public int getMusicCurTime()
{
int curTime=0;
if(player!=null)
{
curTime=player.getCurrentPosition();
}
return curTime;
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MyBinder();
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
musicList = new ArrayList<File>();
// Environment.getExternalStorageDirectory()是获取sd中的内容的
Log.d(null, "1s");
File rootFile = Environment.getExternalStorageDirectory();
Log.d(null, "2s");
fillMusicList(rootFile);
Log.d(null, "3s");
player = new MediaPlayer();
if (musicList.size() != 0) {
startPlay();
}
Log.d(null, "4s");
//监听事件,网络流媒体播放结束监听
player.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// 重置 MediaPlayer 对象
mp.reset();
curPage=curPage==musicList.size()-1 ? (curPage-1)%musicList.size(): curPage+1;
startPlay();
}
});
}
public void playNext()
{
curPage=curPage==musicList.size()-1?(curPage+1)%musicList.size():curPage+1;
player.reset();
startPlay();
}
public void playPre()
{
curPage=curPage==0?0:curPage-1;
player.reset();
startPlay();
}
public void parse(){
player.pause();
}
public void reStart()
{
player.start();
}
public void startPlay() {
mSendBroadCast(NAME, musicList.get(curPage).getName());
try{
//设置播放的文件
player.setDataSource(musicList.get(curPage).getAbsolutePath());
player.prepare();
player.start();
player.getDuration();
mSendBroadCast(TOTALTIME, player.getDuration());
Timer timer=new Timer();
//将当前进度随着当地播放器的进度发广播到activity
timer.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
mSendBroadCast(CURTIME, player.getCurrentPosition());
}
},0, 1000);//这里缺少0,delay毫秒后重复的执行task,周期是period毫秒
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void mSendBroadCast(String key, String value) {
Intent intent = new Intent(MFILTER);
intent.putExtra(key, value);
sendBroadcast(intent);
}
private void mSendBroadCast(String key, int value) {
Intent intent = new Intent(MFILTER);
intent.putExtra(key, value);
sendBroadcast(intent);
}
/* 迭代获取的音乐文件 */
public void fillMusicList(File musicFile) {
File[] sources = musicFile.listFiles();
for (File file : sources) {
// 判断是不是目录,否则是文件
if (file.isDirectory()) {
fillMusicList(file);
} else {
String name = file.getName();
if (name.endsWith(".mp3") || name.endsWith(".acc")) {
musicList.add(file);
}
}
}
}
}
2、MusicActivity
主要是组件功能的实现,直接通过Service获取各种信息,相关播放功能
package com.example.musicplayer;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.http.util.EncodingUtils;
import com.example.musicplayer.MusicService.MyBinder;
import com.example.musicplayer.MusicService;
import android.R.layout;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MusicActivity extends Activity implements OnClickListener{
public MusicService mService;
public MyBinder myBinder;
ServiceConnection conn;
public boolean isStop;
public SeekBar seekBar;
TextView curTime;
TextView totalTime;
TextView title;
public double totalTimeInt;
public double curTimeInt;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(null, "1");
IntentFilter filter = new IntentFilter(MusicService.MFILTER);
Log.d(null, "2");
//广播动态注册
registerReceiver(new MusicReceiver(), filter);
conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
mService = ((MyBinder) service).getMusicService();
}
};
init();
setListener();
}
private void setListener() {
// TODO Auto-generated method stub
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// fromUser判断是用户改变的滑块的值
if(fromUser==true)
{
myBinder.seekTo(progress);
}
}
});
}
public void init()
{
Button previous = (Button) findViewById(R.id.previous);
Button next = (Button) findViewById(R.id.next);
Button stop = (Button) findViewById(R.id.stop);
Button stopService = (Button) findViewById(R.id.stopService);
seekBar = (SeekBar) findViewById(R.id.mSeekbar);
curTime = (TextView) findViewById(R.id.curTime);
totalTime = (TextView) findViewById(R.id.totalTime);
title = (TextView) findViewById(R.id.title);
previous.setOnClickListener(this);
next.setOnClickListener(this);
stop.setOnClickListener(this);
stopService.setOnClickListener(this);
//将歌曲的长度设置为播放进度条的最大值
// seekBar.setMax((int)totalTimeInt);
}
// Handler handler=new Handler();
// Runnable updateThread=new Runnable()
// {
// public void run() {
// //获取歌曲现在播放位置并设置成播放进度条的值
// seekBar.setProgress((int)curTimeInt);
// //每次延迟1000毫秒再启动线程
// handler.postDelayed(updateThread, 1000);
// }
// };
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Intent intent=new Intent(MusicActivity.this,MusicService.class);
intent.setAction("com.intent.musicplayer.MusicService");
Log.d(null, "3");
bindService(intent, conn, BIND_AUTO_CREATE);
Log.d(null, "4");
}
class MusicReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 如果没有取到,默认值为0,不为0说明取到
if(intent.getIntExtra(MusicService.CURTIME, 0)!=0)
{
curTimeInt=intent.getIntExtra(MusicService.CURTIME, 0);
curTime.setText(transferMilliToTime((int)curTimeInt));
double result = curTimeInt/totalTimeInt*100;
seekBar.setProgress((int) Math.floor(result));
}else if(intent.getIntExtra(MusicService.TOTALTIME, 0)!=0)
{
totalTimeInt=intent.getIntExtra(MusicService.TOTALTIME, 0);
totalTime.setText(transferMilliToTime((int)totalTimeInt));
}
else if(!TextUtils.isEmpty(intent.getStringExtra(MusicService.NAME)))
{
String result=intent.getStringExtra(MusicService.NAME);
try {
title.setText(EncodingUtils.getString(result.getBytes("GB2312"), "UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 将毫秒转换为时间格式
private String transferMilliToTime(int Millis) {
SimpleDateFormat format = new SimpleDateFormat("mm:ss");
String result = format.format(new Date(Millis));
return result;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.previous:
mService.playPre();
break;
case R.id.next:
mService.playNext();
break;
case R.id.stop:
if(isStop)
{
mService.reStart();
}else
{
mService.parse();
}
isStop=!isStop;
break;
case R.id.stopService:
Intent intent =new Intent("com.intent.musicplayer.MusicService");
unbindService(conn);
stopService(intent);
break;
default:
break;
}
}
}
注册Service
注意(不用在配置文件注册广播,因为广播是通过registerReceiver(new MusicReceiver(), filter);动态注册了)
<service android:name="com.example.musicplayer.MusicService" >
<intent-filter>
<action android:name="com.intent.musicplayer.MusicService" />
</intent-filter>