Android音乐播放器---实现Notification控制音乐播放
2014-08-24 12:36
671 查看
最近一直在学习Android服务(Service)、广播接收者(BroadcastReceiver)、通知(Notification)的用法,趁着刚学完的热乎劲儿,做了个音乐播放器来练手。在此,我就把自己在编写过程中对服务、广播接收者、通知的理解及通知栏实现音乐播放功能的实现,和各位喜欢Android编程的基友们一起分享一下。(第一次写技术文章,想想还真有点小紧张呢!以下内容均为个人理解,所以说的不到位的地方,还请基友们指出哦)。废话不多说,直接进入主题。
准备工作:
定义接口,用于传递音乐的播放信息:
定义Application类,用于传递全局变量:
定义Service类,用于控制音乐播放:
初始化Notification,该部分主要在Activity中完成:
Notification的布局效果(即contentView):
定义BroadcastReceiver类,用于接收来自Notification的广播并控制音乐播放:
最后别忘了在清单文件中声明广播类并定制广播哦:
大功告成!
为区分通知栏点击的是哪个控件,刚开始我是想通过在意图中通过putExtra()方法添加参数,来区分控件,但后来实现发现行不通。之后我便转换思路用action来区分,成功为不同控件实现了不同的点击响应。不知道区分点击事件还有没有其他方法,还请贴心的基友指出来哦!
另外,还有好基友可能还会碰见动态更新Notification布局内容的需求,各位可以试试NotificationManager类对象的notify()方法,参数可根据需要来添加。
以上博文希望能给各位正在学服务、广播、通知以及还在纠结通知栏实现音乐播放控制的好基友一些帮助。
为什么选择音乐播放器来作为服务、广播接收者、通知的练习项目呢?
想必各位初学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; @Override public void onCreate() { super.onCreate(); application = (Mp3Application) getApplication(); songs = application.songsList; } @Override public 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(); } } @Override public boolean onUnbind(Intent intent) { mp.stop(); mp.release(); mp = null; return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); } <span style="white-space:pre"> </span>//实现IMusic接口,用于接收播放信息 private class MusicListener extends Binder implements IMusic { @Override public void moveon() { if (mp != null) { mp.start(); } } @Override public void pause() { if (mp != null) { mp.pause(); } } @Override public void stop() { if (mp != null) { mp.stop(); mp.release(); mp = null; } } @Override public void nextSong() { if (mp != null) { mp.stop(); play(++application.songItemPos); } } @Override 4000 public 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; ..... @Override protected 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; @Override public 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); } } }
最后别忘了在清单文件中声明广播类并定制广播哦:
<application android: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> ...... <receiver android: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控制音乐播放
- Android音乐播放器---实现Notification控制音乐播放
- Android音乐播放器---实现Notification控制音乐播放
- Android实战 - 音心播放器 (通知实现音乐的播放/暂停/下一曲控制)
- 实现Activity中控制service里音乐播放、暂停的两种方式
- HTML5+JavaScript+CSS实现音乐播放器——难点二:自己设计一个控制音乐播放的控制器
- Swift如何实现音乐播放,后台播放及控制。
- 控制音乐播放器的退出再次播放相同音乐的功能实现
- AS3.0实现音乐的播放,停止,暂停,和音量的控制
- OpenWrt - MPDroid实现Android手机控制OpenWRT播放音乐
- Android中通过耳机按键控制音乐播放的实现
- Android中通过耳机按键控制音乐播放的实现
- 实现点击通知栏发送广播控制音乐的播放、暂停、上一曲、下一曲
- Unity中实现在切换场景时控制音乐的同步播放
- 使用手机控制电脑 实现音乐播放 电影播放控制 关机等操作
- HTML5+JavaScript+CSS实现音乐播放器——难点二:自己设计一个控制音乐播放的控制器
- IOS 控制音量并实现后台播放音乐
- [原创]网页中自动连续播放音乐文件的实现
- 控制iphone中的实体按钮和音乐播放
- 解决关于如何实现锁屏后继续播放音乐的问题