黑马程序员_Mp3播放器之歌词显示和拖动进度条的跳转
?分析流程,首先看到onStartCommand(Intent intent, int flags, int startId) ,这里其实我们只是用了第一个参数的内容,这是因为在mp3的播放界面的时候点击了相应的按钮后,会随着intent传送一个int类型的数字过来,当然不同的数字都有不同的含义。上面的定义已经给出了。
?
关于createPlayer():
我们先看在正常播放的时候,当然我们在上一个歌曲列表的界面点击某首歌的时候,将会打开这个service,并且在intent的里面含有的doPlayer==CREATE。
所以会引发createPlayer()的方法。其中如果要看歌词的话,会这样lrc=getLrc()得到歌词对象,再调用readLrc(),其中map=lrc.getContent(),
是
public LinkedHashMap<Long, String> getContent() {
return content;
}
?
将这个链表的hashmap赋值给map。
其他的内容,请参看readLrc()函数里面的注释,我写的很清楚了。
接着,createPlayer()里还有一段非常重要,这一段设置
Mp3PlayerActivity.bar.setMax(player.getDuration()); ?//这里是以为毫秒为单位
?
其中getDuration () 的方法:
public int getDuration ()?
Added in API level 1
Gets the duration of the file.
?
Returns
the duration in milliseconds?
?
得到的是一个以毫秒为单位的数字,这一点记录开始时间的begin的单位想匹配,这样为我们切换拉动进度跳的时候找到相应的歌词提供了非常大的方便。
begin=System.currentTimeMillis();//Returns the current system time in milliseconds
?
其中,是为了慢慢的滚动歌词而单独设置的线程
handler.post(updateSeekBar)。这一段我也写了详尽的注释。
?
其它的play();pauseMp3();stopMp3();changeMp3();changeMp3();比较简单,请自己参看,。
?
我最想特别说明的是:move(),即当我们在播放的MP3的activity里面拖动了进度条的时候,
相应代码:
bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {//这里的几个方法,我们只关心,用户在哪里按下和在哪里松开按钮,所以我们只写了一个onStopTrackingTouch和onStartTrackingTouchpublic void onStopTrackingTouch(SeekBar arg0) {// TODO Auto-generated method stubif(!PlayerService.stop){//如果音乐器正在播放i=bar.getProgress();//得到松开手的进度条的位置movetime+=(i-startmove);//得到两者的差值player_intent.putExtra("doPlayer",PlayerService.MOVE);startService(player_intent);}else{bar.setProgress(0);}}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {// TODO Auto-generated method stubstartmove=bar.getProgress();//当用户想要拖动进度条的时候,第一次触碰的地方}@Overridepublic void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {// TODO Auto-generated method stub}});
?
就会调用move()。这里面对拖动的时间的处置利用这样一个算式:
//这个mv时间设置的非常巧妙。是不算暂停时间(减去了pausetime)和去除了拖动滚动条的时间(减去了movetime)。是现在时间和开始时间之差
mv=System.currentTimeMillis()-begin+Mp3PlayerActivity.movetime-pausetime;
再清空时间点的队列:timeQueue=new LinkedList<Long>();?
再把只是比mv大的部分的时间点加入到timeQueue队列即可,再让handler.post(updateSeekBar)这个线程里run()去处理拖动后的歌词。这样歌词的显示就正常了。
?
我们再看看,对歌曲播放的的处理,居然只有一句话,
player.seekTo(Mp3PlayerActivity.i)
?
?
这个i=bar.getProgress();(来自bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener()的onStopTrackingTouch(SeekBar arg0) (松开手指的地方) )
?
而public synchronized int getProgress ()?
Returns:
the current progress, between 0 and getMax()
?
还记得我们是如何设置这个bar的最大值的吗?就是
Mp3PlayerActivity.bar.setMax(player.getDuration());?
?
这样再去设置歌曲的时候只需要拿到松开手处的bar.getProgress(),再seekto到bar.getProgress()即可。
?
虽然好像我再纠结非常2的问题。但是我觉得让我思路变得好清晰好清晰。
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ------- android培训、java培训、期待与您交流! ----------