接上:
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); } } }
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; } }
在下一博文中报运行结果发上来,不知道能不能发:期待。。。。