最近一直在学习Android服务(Service)、广播接收者(BroadcastReceiver)、通知(Notification)的用法,趁着刚学完的热乎劲儿,做了个音乐播放器来练手。在此,我就把自己在编写过程中对服务、广播接收者、通知的理解及通知栏实现音乐播放功能的实现,和各位喜欢Android编程的基友们一起分享一下。(第一次写技术文章,想想还真有点小紧张呢!以下内容均为个人理解,所以说的不到位的地方,还请基友们指出哦)。废话不多说,直接进入主题。

为什么选择音乐播放器来作为服务、广播接收者、通知的练习项目呢?

想必各位初学Android的基友都有这样的经历,在我们接触服务之前,应用程序的运行都是依托于一个操作界面(即Activity),一旦离开这个界面,程序的操作也就随着终止了。然而,有时我们还有这样的需求,当离开一个操作界面时,程序任然需要继续执行(即后台运行),这时,我们就需要Android的另一大组件Service来实现这样的操作了。Service组件区别与Activity的一个最主要的特征他的运行不依赖界面,他就像一个幕后工作者,默默的运行在应用程序的背后,当应用程序界面关闭时,程序的运行就要靠他了,例如音乐的后台播放。

通知(Notification)为音乐播放器实现了那些功能?

后台播放的音乐,要实现对其播放的控制,可以通过通知栏工具来实现, 且看下图:
    

广播接收者(BroadCastReceiver)在音乐播放器中有什么作用?

老实说,对这个组件的理解,之前我一直都有点稀里糊涂,很多基友初接触时,可能和我一样,用他来实现了短信监听的功能,即接受系统内置的广播。音乐播放器的编写让我重新认识了广播接收者的运作机制。在Android应用中,游离着各种各样的由不同应用发出广播,广播的标记信息一般附着在Intent对象上(说白了就是在新建Intent对象时,给他一个字符串作为参数,这个参数可以作为广播接收的标记),随着Intent对象的传递,广播也就被发出了。此时,要想接收这个广播,我们只需要新建一个广播类,并定制带有这个标记的广播,在这个广播被发出时,我们就能接收这条广播,并完成相应的操作了。

服务、广播接收者、通知共同实现通知栏音乐播放控制:
准备工作:
定义接口,用于传递音乐的播放信息:
public interface IMusic {public void moveon();//继续public void pause();//暂停public void stop();//停止public void nextSong();//下一曲public void lastSong();//上一曲
}

定义Application类,用于传递全局变量:

public class Mp3Application extends Application {public List<Song> songsList;//当前播放列表public int songItemPos;//当前播放音乐在列表中的位置public NotificationManager notManager;public IMusic music;
}
定义Service类,用于控制音乐播放:
public class PlayerService extends Service {private MediaPlayer mp;private Mp3Application application;private List<Song> songs;private int songItemPos;@Overridepublic void onCreate() {super.onCreate();application = (Mp3Application) getApplication();songs = application.songsList;}@Overridepublic IBinder onBind(Intent intent) {play(songItemPos);return new MusicListener();}public void play(int position) {
<span style="white-space:pre">     </span>//传入播放位置在列表中的边界if(position>=0){position=position % application.songsList.size();}else{position = application.songsList.size()+ position;}application.songItemPos = position;//在全局变量中标记当前播放位置Song currentSong = songs.get(position);//获取当前播放音乐Uri musicTableForSD = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;Uri uri = Uri.withAppendedPath(musicTableForSD,"/" + currentSong.getId());//初始化mp对象mp = MediaPlayer.create(this, uri);System.out.println(currentSong.getName());try {mp.start();} catch (Exception e) {e.printStackTrace();}}@Overridepublic boolean onUnbind(Intent intent) {mp.stop();mp.release();mp = null;return super.onUnbind(intent);}@Overridepublic void onDestroy() {super.onDestroy();}
<span style="white-space:pre"> </span>//实现IMusic接口,用于接收播放信息private class MusicListener extends Binder implements IMusic {@Overridepublic void moveon() {if (mp != null) {mp.start();}}@Overridepublic void pause() {if (mp != null) {mp.pause();}}@Overridepublic void stop() {if (mp != null) {mp.stop();mp.release();mp = null;}}@Overridepublic void nextSong() {if (mp != null) {mp.stop();play(++application.songItemPos);}}@Overridepublic void lastSong() {if (mp != null) {mp.stop();play(--application.songItemPos);}}}}
初始化Notification,该部分主要在Activity中完成:
Notification的布局效果(即contentView):
public class MainActivity extends Activity {.....private RemoteViews contentView;private Notification notification;private Mp3Application application;private IMusic music;.....@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);......       // 初始化通知栏播放控件initNotificationBar();......}public void initNotificationBar() {notification = new Notification();//初始化通知notification.icon = R.drawable.ic_launcher;contentView = new RemoteViews(getPackageName(),R.layout.notification_control);notification.contentView = contentView;Intent intentPlay = new Intent("play");//新建意图,并设置action标记为"play",用于接收广播时过滤意图信息PendingIntent pIntentPlay = PendingIntent.getBroadcast(this, 0,intentPlay, 0);contentView.setOnClickPendingIntent(R.id.bt_notic_play, pIntentPlay);//为play控件注册事件Intent intentPause = new Intent("pause");PendingIntent pIntentPause = PendingIntent.getBroadcast(this, 0,intentPause, 0);contentView.setOnClickPendingIntent(R.id.bt_notic_pause, pIntentPause);Intent intentNext = new Intent("next");PendingIntent pIntentNext = PendingIntent.getBroadcast(this, 0,intentNext, 0);contentView.setOnClickPendingIntent(R.id.bt_notic_next, pIntentNext);Intent intentLast = new Intent("last");PendingIntent pIntentLast = PendingIntent.getBroadcast(this, 0,intentLast, 0);contentView.setOnClickPendingIntent(R.id.bt_notic_last, pIntentLast);Intent intentCancel = new Intent("cancel");PendingIntent pIntentCancel = PendingIntent.getBroadcast(this, 0,intentCancel, 0);contentView.setOnClickPendingIntent(R.id.bt_notic_cancel, pIntentCancel);notification.flags = notification.FLAG_NO_CLEAR;//设置通知点击或滑动时不被清除application.notManager.notify(Const.NOTI_CTRL_ID, notification);//开启通知}}

定义BroadcastReceiver类,用于接收来自Notification的广播并控制音乐播放:

public class Mp3Receiver extends BroadcastReceiver {private Mp3Application application;private IMusic music;@Overridepublic void onReceive(Context context, Intent intent) {application = (Mp3Application) context.getApplicationContext();String ctrl_code = intent.getAction();//获取action标记,用户区分点击事件music = application.music;//获取全局播放控制对象,该对象已在Activity中初始化if (music != null) {if ("play".equals(ctrl_code)) {music.moveon();System.out.println("play");} else if ("pause".equals(ctrl_code)) {music.pause();System.out.println("pause");} else if ("next".equals(ctrl_code)) {music.nextSong();System.out.println("next");} else if ("last".equals(ctrl_code)) {music.lastSong();System.out.println("last");}}if ("cancel".equals(ctrl_code)) {application.notManager.cancel(Const.NOTI_CTRL_ID);System.exit(0);}}}

最后别忘了在清单文件中声明广播类并定制广播哦:

    <applicationandroid:name="com.cxc.Mp3Player.util.Mp3Application"android:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><uses-library android:name="android.test.runner" ></uses-library>......<receiverandroid:name="com.cxc.Mp3Player.receiver.Mp3Receiver"android:exported="true" ><intent-filter><action android:name="play" /><!-- 定制play广播 --><action android:name="last" /><!-- 定制last广播 --><action android:name="next" /><!-- ...... --><action android:name="pause" /><action android:name="cancel" /></intent-filter></receiver></application>
大功告成!
为区分通知栏点击的是哪个控件,刚开始我是想通过在意图中通过putExtra()方法添加参数,来区分控件,但后来实现发现行不通。之后我便转换思路用action来区分,成功为不同控件实现了不同的点击响应。不知道区分点击事件还有没有其他方法,还请贴心的基友指出来哦!
另外,还有好基友可能还会碰见动态更新Notification布局内容的需求,各位可以试试NotificationManager类对象的notify()方法,参数可根据需要来添加。
以上博文希望能给各位正在学服务、广播、通知以及还在纠结通知栏实现音乐播放控制的好基友一些帮助。

Android音乐播放器---实现Notification控制音乐播放相关推荐

  1. Android应用--简、美音乐播放器增加音量控制

    Android应用--简.美音乐播放器增加音量控制 2013年6月26日简.美音乐播放器继续完善中.. 题外话:上一篇博客是在6月11号发的,那篇博客似乎有点问题,可能是因为代码结构有点乱的原因,很难 ...

  2. android 音乐播放器ui界面设计音乐播放器毕业设计。Android studio编译,项目有源码和apk

    使用Android Studio开发一个简易的音乐播放器 界面图: 视频展示: android 音乐播放器ui界面设计音乐播放器毕业设计.Android studio编译 项目下载: android音 ...

  3. 单片机音乐播放器课程设计C语言,单片机音乐播放器课程设计中音乐代码怎么弄...

    单片机音乐播放器课程设计中音乐代码怎么弄 答案:2  信息版本:手机版 解决时间 2019-10-06 13:16 已解决 2019-10-06 02:07 单片机音乐播放器课程设计中音乐代码怎么弄 ...

  4. 开源音乐播放器_使用开源音乐播放器设计生活中的配乐

    开源音乐播放器 我们围绕着自己的个人配乐. 我们的音乐让我们想起了人生中最重要的时刻,并帮助我们塑造了自己的感受和看法. 让音乐播放器支持自由选择音乐的播放方式,同时又不影响播放质量非常重要,而且我一 ...

  5. 仿网易云音乐html代码,仿网易云音乐外链播放器UI的HTML5音乐播放器插件

    简要教程 APlayer是一款仿网易云音乐外链播放器UI的HTML5音乐播放器插件.APlayer音乐播放器可以自定义歌曲封面,可以自定义同步歌词等,界面时尚大方,是一款非常好的HTML5音乐播放器插 ...

  6. html5自动播放音乐外链,仿网易云音乐外链播放器UI的HTML5音乐播放器插件

    APlayer是一款仿网易云音乐外链播放器UI的HTML5音乐播放器插件.APlayer音乐播放器可以自定义歌曲封面,可以自定义同步歌词等,界面时尚大方,是一款非常好的HTML5音乐播放器插件. 安装 ...

  7. html制作在线视频音乐播放器,用html5制作音乐播放器,这3款就足够了!

    用HTML5结合Jquery做一个简易版的音乐播放器 代码展示: 三生草 var sum = 1; function ssss(a) { var s = document.getElementById ...

  8. 使用Vitamio打造自己的Android万能播放器(5)——在线播放(播放优酷视频)

    前言 为了保证每周一篇的进度,又由于Vitamio新版本没有发布, 决定推迟本地播放的一些功能(截图.视频时间.尺寸等),跳过直接写在线播放部分的章节.从Vitamio的介绍可以看得出,其支持http ...

  9. Android 中封装优雅的 MediaPlayer 音频播放器,支持多个播放器

    Android 中封装优雅的 MediaPlayer 音频播放器,支持多个播放器实例的示例: public class AudioPlayer implements MediaPlayer.OnPre ...

最新文章

  1. R卡方检验(CHI-SQUARE TEST)
  2. cesium js 路径_Cesium开发学习路径
  3. emacs python plugin_Windows上配置Emacs来开发Python及用Python扩展Emacs
  4. 【C++学习之路】第一章——C++核心方法总论
  5. C#json数据的序列化和反序列化(将数据转换为对象或对象集合)
  6. java判断读到末尾_Java Web入门之java--第一节 java 简介及开发环境安装
  7. 使用 PyMOL 将靶点与配体复合物中的靶点和配体拆出来
  8. 蓝桥杯 ALGO-53 算法训练 最小乘积(基本型)
  9. 洛谷 1563 玩具谜题——模拟水题
  10. CIO:权大、钱多、但难干 | 凌云时刻
  11. 讲解wpe抓包,封包
  12. LAMMPS分子动力学模拟技术与应用 第一性原理计算方法及应用
  13. Proteus软件初学笔记
  14. CAD图纸打印出来后很多CAD文字消失了怎么办?
  15. linux下轻松修改pdf文件
  16. 安卓模拟ibeacon_Android BLE-iBeacon系列(二)扫描识别iBeacon设备
  17. Pvr_Controller
  18. 邵东一中2021年高考成绩查询,湖南邵阳2020高考成绩,邵东一中势头强劲,包揽邵阳市文理状元...
  19. ODOO15中如何在交货单中为客户设置出货范围?OCA模块
  20. 知乎 | 给博士一年级新生的建议!

热门文章

  1. 量子竞赛下一步:在应用中体现量子优势
  2. Python之有趣的小程序
  3. H5实时上传位置定位 pc生成轨迹;h5保持后台运行
  4. python循环5次_python基础-循环语句(5)
  5. 2020年创业风口:社交电商
  6. python数据分析岗位做什么_给力!数据分析岗位内部人的建议,可以少走很多弯路...
  7. 计算机组成原理语言方框图,计算机组成原理3---方框图语言
  8. Simulink之S-function函数笔记之一
  9. 如何写出难以维护的代码--代码命名
  10. (HOTA)多目标跟踪MOT指标计算方法