MediaPlayerService作为通用的音乐播放Service类,它的功能有:

  1. 控制音乐播放,停止,暂停,前/后歌曲切换。
  2. Audio Focus相关处理(对应应用程序切换)。
  3. Intent处理(对应多媒体键,耳机线拔出,打入电话)
  4. Notification处理

其实这个类本来是和LyricPlayerService在一起的,但是随着功能的增加代码越来越乱。于是就有了分开的想法。但是分也要分出点名堂,于是为这个类定义的功能就是实现一个通用的媒体播放服务。

分开后的类关系可以从下面的全体图中看出。

下面针对各功能加以说明

控制音乐播放,停止,暂停,前/后歌曲切换。

在开始真正的工作之前要解决的一个问题是:作为通用的音乐播放那个服务,就一定会还有在后台时播放前/后一首歌的要求。但是这是应用已经不存在了,不可能把这个任务交个Activie来处理。为了解决这个问题定义了一个用于取得相应的媒体文件信息的MediaInfoProvider类。

  1. public interface MediaInfoProvider{
  2. String getUrl();
  3. String getTitle();
  4. boolean moveToNext();
  5. boolean moveToPrev();
  6. }

通过调用moveToNext和moveToPrev方法实现媒体文件的切换,然后通过调用getUrl和getTitle来取得文件的信息。

注意在这里只是规定接口,真正的实例必须由利用者通过下面的方法来提供。有一点额外的工作就是如果希望播放的歌曲和正在播放的不一样的话就先停止正在播放的歌曲。

  1. public void setMediaInfoProvider(MediaInfoProvider provider) {
  2. if( mDataSource != provider.getUrl() && (isStop() == false)){
  3. stop();
  4. }
  5. mMediaInfoProvider = provider;
  6. mDataSource = provider.getUrl();
  7. mTitle = provider.getTitle();
  8. }

当然在利用MediaPlayer之前我们需要onCreate方法中进行一些准备工作。内容包括

  1. 创建MediaPlayer对象,
  2. 设定唤醒方式(目的是防止播放中CPU进入休眠状态,记得在 AndroidManifest.xml中设定权限为android.permission.WAKE_LOCK)
  3. 指定播放完了后的监听器。
  1. mMediaPlayer = new MediaPlayer();
  2. mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
  3. mMediaPlayer.setOnCompletionListener(this);
 

这个播放完了监听器的目的有两个。一个是停止任务栏上的图标显示,另外一个是在没有前台应用的时候自动关闭本服务。要是没有人管了怎么办?对吧。

  1. @Override
  2. public void onCompletion(MediaPlayer mp) {
  3. mIsPausing = false;
  4. mNotificationManager.cancel(NOTIFICATION);
  5. if(mBinded == false){
  6. stopSelf();
  7. }
  8. }

然后就是onDestroy中进行适当的收尾工作。其中停止播放的部分看起来好像没有也可以,还是一切都按部就班好一些吧。

  1. mMediaPlayer.setOnCompletionListener(null);
  2. if(!isStop()){
  3. stop();
  4. }
  5. mMediaPlayer.release();
  6. mMediaPlayer = null;

终于到到了真正的控制部分。接下来的程序比较长但内容确实比较简单。

在最前面的start方法比较复杂,主要是因为虽然说起来都是播放,但是从暂停恢复播放和播放新歌的处理有所不同。其他的没有什么好讲的。

  1. public void start() {
  2. tryToGetAudioFocus();
  3. if(!isPausing()){
  4. if(isPlaying()){
  5. stop();
  6. }
  7. try{
  8. mMediaPlayer.reset();
  9. mMediaPlayer.setDataSource(mDataSource);
  10. mMediaPlayer.prepare();
  11. }catch(IOException e) {
  12. return;
  13. } catch  (IllegalArgumentException e) {
  14. return;
  15. }
  16. mMediaPlayer.start();
  17. }else{
  18. mIsPausing = false;
  19. mMediaPlayer.start();
  20. }
  21. showNotification();
  22. }
  23. public void stop() {
  24. giveUpAudioFocus();
  25. mMediaPlayer.stop();
  26. mIsPausing = false;
  27. mNotificationManager.cancel(NOTIFICATION);
  28. }
  29. public void pause() {
  30. giveUpAudioFocus();
  31. mIsPausing = true;
  32. mMediaPlayer.pause();
  33. }
  34. public void playNext(){
  35. if(mMediaInfoProvider.moveToNext()){
  36. if(isPlaying() || isPausing()){
  37. stop();
  38. }
  39. mDataSource = mMediaInfoProvider.getUrl();
  40. mTitle = mMediaInfoProvider.getTitle();
  41. start();
  42. }
  43. }
  44. public void playPrev(){
  45. if(mMediaInfoProvider.moveToPrev()){
  46. if(isPlaying() || isPausing()){
  47. stop();
  48. }
  49. mDataSource = mMediaInfoProvider.getUrl();
  50. mTitle = mMediaInfoProvider.getTitle();
  51. start();
  52. }
  53. }
  54. public boolean isPausing(){
  55. return mIsPausing;
  56. }
  57. public boolean isPlaying() {
  58. return mMediaPlayer.isPlaying();
  59. }
  60. public boolean isStop(){
  61. return (isPlaying() == false && isPausing() == false);
  62. }
  63. public int getDuration() {
  64. return mMediaPlayer.getDuration();
  65. }
  66. public int getPosition() {
  67. return mMediaPlayer.getCurrentPosition();
  68. }
  69. public long seek(long whereto) {
  70. mMediaPlayer.seekTo((int ) whereto);
  71. return whereto;
  72. }

下面的代码的功能是处理各种有关播放控制的Intent。媒体键(就是其实就是线控上的那几个钮),耳机线拔出,来电暂停都是通过这种方式实现的。当然它们都需要在AndroidManifest.xml中进行定义。

  1. public static final String ACTION_PAUSE = "MediaPlayer.xwg.action.PAUSE";
  2. public static final String ACTION_PLAY_PAUSE = "MediaPlayer.xwg.action.PLAY_PAUSE";
  3. public static final String ACTION_PREVIOUS = "MediaPlayer.xwg.action.PREVIOUS";
  4. public static final String ACTION_NEXT = "MediaPlayer.xwg.action.NEXT";
  5. @Override
  6. public int onStartCommand(Intent intent, int flags, int startId) {
  7. String action = intent.getAction();
  8. if(action != null)
  9. {
  10. if (action.equals(ACTION_PLAY_PAUSE)){
  11. if(isPlaying()){
  12. pause();
  13. }else{
  14. start();
  15. }
  16. }else if (action.equals(ACTION_PAUSE)){
  17. if(isPlaying())
  18. {
  19. pause();
  20. }
  21. }else if (action.equals(ACTION_PREVIOUS)){
  22. if(isPlaying() || isPausing())
  23. {
  24. playPrev();
  25. }
  26. }else if (action.equals(ACTION_NEXT)){
  27. if(isPlaying() || isPausing())
  28. {
  29. playNext();
  30. }
  31. }
  32. }
  33. return START_NOT_STICKY; // Means we started the service, but don't want it to
  34. // restart in case it's killed.
  35. }

其实在前面代码中的有几个地方没有提,就是关于AudioFocus和MEDIA_BUTTOn,,耳机插头拔出,来电处理和Notification表示的部分。关于这部分内容请参阅

Android歌词秀设计思路(3)通用的音乐播放服务(上)相关推荐

  1. Android歌词秀设计思路(7)水到渠成

    我们用了6篇文章的篇幅做了铺垫,终于到了真正的应用程序了.这部分还是一如既往的简单. 有关应用的类有两个,一个是LiryicMain,一个是SelectFileActivity.都是差不多最低限度的内 ...

  2. Android歌词秀设计思路(8)后记

    写下这篇博文的时候,访问量的总数刚好过2000次,先自己庆祝一下. 做程序已经十八九年,但是写文章介绍自己的程序还是第一次.是实话这件事的难度超出了我的预想. 一个是篇幅长,原先以为很简单的一个程序, ...

  3. Android歌词秀设计思路(2)歌词处理

    这次的内容是歌词处理模块LyricAdapter类.这个类的主要功能有 1.歌词文件的解析 2.对外提供歌词访问服务(歌词数取得,歌词内容,时间的取得等) 3.根据播放位置检索对应的歌词. 4.在歌词 ...

  4. Android歌词秀设计思路(6)运用Proxy设计模式简化歌词播放服务的使用

    开始开发歌词秀的时候还是夏天,没有想到写这篇文章的时候大连已经迎来的今年的第一次大规模降温.多少有点冬天的感觉了. 上一篇文章我们已经介绍了,带有歌词播放功能的服务,按说接下来就该是利用歌词播放服务的 ...

  5. android 歌词点击播放,Android歌词秀设计思路(5)歌词播放服务

    接下来说明一下,提供歌词播放器服务的LyricPlayerService.这个类在整个播放过程中的作用是 1.负责管理LyricAdapter的生命周期. 2.控制音乐播放,歌词解析,并且协调音乐与歌 ...

  6. android 歌词解析时间,Android歌词秀设计思路(1)SafetyTimer

    Android中使用Timer时需要同时访问TimerTask,Handle等类,手续繁杂而且是真正想做的事淹没在手续化的代码中.本文介绍了的SafetyTimer类隐藏了TimerTask,Hand ...

  7. Android歌词秀设计思路歌词播放服务

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://craftsman1970.blog.51cto.com/3522772/6627 ...

  8. Andorid歌词秀设计思路(1)SafetyTimer

    在Android中实现多媒体播放功能主要是通过MediaPlayer实现的.为了方便用户检测MediaPlayer的动作状态,Andorid为我们提供了一下接口 Nested Classes inte ...

  9. Android歌词秀1.5版

    功能简介: 0.本软件可以在Android2.1以上(2.1,2.2,2.3测试通过)执行. 1.自动读取与音乐相同位置的歌词文件. 2.根据播放进度,表示当前的歌词 3.按歌词语句快进,快退. 5. ...

最新文章

  1. url传递中文的解决方案
  2. 符号链接和硬链接有什么区别?
  3. 操作系统设计与实现第3版笔记与minix3心得(4)-操作系统发展历史(2)
  4. Tornado,了解一下
  5. Spring Boot笔记-自动配置(Spring Boot封装成jar被其他项目引用)
  6. 洛谷 P2762 太空飞行计划问题
  7. Redis3集群搭建
  8. 第四章节 窗体应用(Form窗体)
  9. SGU-169 Numbers(找规律)
  10. 随身助手271个可用api接口网站php源码(随身助手API)
  11. Java合并两个有序链表
  12. 领英问题问答--有关领英各类问题整理,置顶推荐
  13. struts2+quartz定时任务
  14. win7系统下联想thinkpad x220笔记本电脑关闭触摸板
  15. 安卓微信小程序https抓包
  16. 计算机课程思政目标有哪些,《人工智能导论》教学大纲(含课程思政内容)
  17. java-net-php-python-springboot健身房管理系统计算机毕业设计程序
  18. 法国出售给阿联酋的卫星可能含有后门组件
  19. 为什么很多大学生甚至研究生抛弃专业去做码农呢?
  20. c#第二课,气泡屏保

热门文章

  1. Ubuntu14.04 安装CUDA7.5 + Caffe + cuDNN
  2. 电力系统 matlab程序,电力系统稳定性分析matlab程序
  3. mysql user分销查询_荐查询无限级/三级分销的简单易用SQL...
  4. 推进养老服务智慧化 认知症障碍友好社区物联网平台
  5. h5简笔画填色小游戏源码
  6. pr颜色遮罩怎么使用?
  7. python 并发笔记--------简单的进程/线程池实现并发IO/CPU 操作
  8. JavaStudy7(18章-坦克大战2)—B站韩顺平
  9. 各种增删改查(员工管理)
  10. 推荐一堆好掂嘅 标头 影嘅东东 (内有靓女,慎入!)