接上:
1. com.mp3player.service包
(1.)DownloadService类
package com.mp3player.service;
import com.download.HttpDownloader;
import com.model.Mp3Info;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class DownloadService extends Service{
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("AAAAAAAAAAAA");
// TODO Auto-generated method stub
Mp3Info mp3Info=(Mp3Info) intent.getSerializableExtra("mp3Info");
System.out.println("service"+mp3Info);
DownloadThread downloadThread=new DownloadThread(mp3Info);
Thread thread=new Thread(downloadThread);
thread.start();
return super.onStartCommand(intent, flags, startId);
}
class DownloadThread implements Runnable{
private Mp3Info mp3Info=null;
public DownloadThread(Mp3Info mp3Info){
this.mp3Info=mp3Info;
}
@Override
public void run() {
String mp3Url="http://192.168.1.104:8080/ServletForAndroid/" + mp3Info.getMp3Name();
HttpDownloader httpDownloader =new HttpDownloader();
int result = httpDownloader.downFile(mp3Url, "mp3/", mp3Info.getMp3Name());
String resultMessage = null;
if(result == -1){
resultMessage = mp3Info.getMp3Name()+"下载失败";
}else if(result == 0){
resultMessage = mp3Info.getMp3Name() +"下载成功";
}else if(result == 1){
resultMessage = mp3Info.getMp3Name() + "文件已经存在,不需要重新下载";
}
//使用Notification提示下载结果
}
}
}
package com.mp3player.service;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Queue;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import com.krc.KrcProcessor;
import com.model.Mp3Info;
import com.mp3player.AppConstant;
public class PlayerService extends Service {
private boolean isPlaying = false;
private boolean isPause = false;
private boolean isReleased = false;
private MediaPlayer mediaPlayer = null;
ArrayList<Queue> queues = null;
private Handler handler = new Handler();
private UpdateTimeCallback updateTimeCallback = null;
private long begin = 0;
private long currentTimeMill = 0;
private long nextTimeMill = 0;
private long pauseTimeMills = 0;
private Mp3Info mp3Info = null ;
private String message = null;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
mp3Info = (Mp3Info)intent.getSerializableExtra("mp3Info");
System.out.println("mp3Info.getLrcName--===" + mp3Info.getKrcName());
//接收MSG,默认值是1
int MSG = intent.getIntExtra("MSG", 0);
System.out.println("MSG:" + MSG);
if(mp3Info != null){
if(MSG == AppConstant.PlayerMsg.PLAY_MSG){
System.out.println("start play");
play(mp3Info);
}else {
if(MSG == AppConstant.PlayerMsg.PAUSE_MSG){
pause();
}else if(MSG == AppConstant.PlayerMsg.STOP_MSG){
stop();
}
}
}
return super.onStartCommand(intent, flags, startId);
}
private void play(Mp3Info mp3Info){
String path = getMp3Path(mp3Info);
mediaPlayer = MediaPlayer.create(this, Uri.parse("file://" + path));
mediaPlayer.setLooping(false);
mediaPlayer.start();
prepareLrc(mp3Info.getKrcName());
begin = System.currentTimeMillis();
//延后5毫秒执行UpdateTimeCallback
handler.postDelayed(updateTimeCallback, 5);
isPlaying = true;
isReleased = false;
}
private void pause(){
if(isPlaying){
mediaPlayer.pause();
handler.removeCallbacks(updateTimeCallback);
//暂停时取得当前时间
pauseTimeMills = System.currentTimeMillis() ;
}else{
mediaPlayer.start();
//再次播放
handler.postDelayed(updateTimeCallback, 5);
//得到再次开始播放的时间
begin = System.currentTimeMillis() - pauseTimeMills + begin;
}
//如果当前状态时暂停的话,点击后状态改为播放;如果是播放的话,点击后改为暂停
isPlaying = isPlaying?false : true;
}
private void stop(){
if (mediaPlayer != null) {
if (isPlaying) {
if (!isReleased) {
handler.removeCallbacks(updateTimeCallback);
mediaPlayer.stop();
mediaPlayer.release();
isReleased = true;
}
isPlaying = false;
}
}
}
private String getMp3Path(Mp3Info mp3Info) {
String SDCardRoot = Environment.getExternalStorageDirectory()
.getAbsolutePath();
String path = SDCardRoot + File.separator + "mp3" + File.separator
+ mp3Info.getMp3Name();
return path;
}
/**
* 根据歌词文件的名字来读取歌词信息
* @param lrcName
*/
private void prepareLrc(String lrcName){
try{
InputStream inputStream = new FileInputStream(Environment.getExternalStorageDirectory().getAbsoluteFile()
+ File.separator + "mp3/" + mp3Info.getKrcName());
KrcProcessor lrcProcessor = new KrcProcessor();
queues = lrcProcessor.process(inputStream);
//创建一个UpdateTimeCallback对象
updateTimeCallback = new UpdateTimeCallback(queues);
begin = 0;
currentTimeMill = 0;
nextTimeMill = 0;
}catch(FileNotFoundException e){
e.printStackTrace();
}
}
class UpdateTimeCallback implements Runnable{
Queue times = null;
Queue messages = null;
public UpdateTimeCallback(ArrayList<Queue> queues){
//从ArrayList当中取出相应的对象
times = queues.get(0);
messages = queues.get(1);
}
@Override
public void run() {
// TODO Auto-generated method stub
//计算偏移量,也即是从mp3播放开始到现在,共消耗了多少时间,单位毫秒
long offset = System.currentTimeMillis() - begin;
//第一次播放
if(currentTimeMill == 0){
//从times取出下一次要更新歌词的时间点
nextTimeMill = (Long)times.poll();
//下一个时间点对应的歌词
message = (String)messages.poll();
}
//已经播放的时间大于等于下一次要更新歌词的时间
if(offset >= nextTimeMill){
Intent intent = new Intent();
intent.setAction(AppConstant.LRC_MESSAGE_ACTION);
intent.putExtra("lrcMessage", message);
sendBroadcast(intent);
message = (String)messages.poll();
nextTimeMill = (Long)times.poll();
}
currentTimeMill = currentTimeMill + 10;
//10毫秒后再次用handler执行updateTimeCallback
handler.postDelayed(updateTimeCallback, 10);
}
}
}
2.com.krc包:解析.krc歌词文件,但不能解析成功(算是为以后扩展用)
KrcProcessor类:
package com.krc;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class KrcProcessor {
/**
* 处理歌词,把歌词和时间对应放到ArrayList<Queue>中
* @param inputStream
* @return
*/
public ArrayList<Queue> process(InputStream inputStream){
//存放时间点数据
Queue<Long> timeMills = new LinkedList<Long>();
//存放时间点对应的歌词
Queue<String> messages = new LinkedList<String>();
//将放时间和歌词存放到一起
ArrayList<Queue> queues = new ArrayList<Queue>();
try{
//创建BufferedReader对象
InputStreamReader inputReader = new InputStreamReader(inputStream,"UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputReader);
String temp = null;
int i = 0;
//创建一个正则表达式
Pattern p = Pattern.compile("\\[([^\\]]+)\\]");
String result = null;
boolean b= true;
while((temp = bufferedReader.readLine()) != null){
i ++;
Matcher m = p.matcher(temp);
if(m.find()){
if(result != null){
messages.add(result);
}
String timeStr = m.group();
Long timeMill = time2Long(timeStr.substring(1, timeStr.length() - 1));
if(b){
timeMills.offer(timeMill);
}
String msg = temp.substring(10);
result = "" + msg + "\n";
}else{
result = result + temp + "\n";
}
}
messages.add(result);
queues.add(timeMills);
queues.add(messages);
}catch(Exception e){
e.printStackTrace();
}
return queues;
}
/**
* 将分钟,秒全部转化为毫秒
* @param timeStr
* @return
*/
public Long time2Long(String timeStr){
String s[] = timeStr.split(":");
int min = Integer.parseInt(s[0]);
String ss[] = s[1].split("\\.");
int sec = Integer.parseInt(ss[0]);
int mill = Integer.parseInt(ss[1]);
return min * 60 * 1000 + sec * 1000 + mill * 10L;
}
}
至此,全部代码基本完成,我是在自己的机子上测试,在Eclipse中新建了一个动态的Web工程(ServletForAndroid),把resources.xml文件和mp3文件和歌词文件都放在了web的根目录下,运行该工程后,在运行Android端的Android工程(本例就是:Mp3Player01)就可以完成测试。
在下一博文中报运行结果发上来,不知道能不能发:期待。。。。