Android 界一直流传着一句话,想学习Service, 那么你就要写一个音乐播放器。
为什么要用 Service?
Service 是运行于幕后的,它并不轻易见人,而正巧,音乐也是只闻其声不见其人的,相信这就是它们在一起的原因。
大家都知道,从Activity中跟Service交互有两种方式:
1)startService。在Activity 中直接调用 startService的方法,我们就可以在后台看不见的地方(但还是在同一个进程里)创建一个叫Service 的东西,它能够在后面静悄悄地执行类似下载的任务,也能够热热闹闹地唱起“苍茫的天涯是你的爱...”,但是这种方式呢,我们就只能跟它说,“Service,做这件事吧”,而没办法在它做一半的时候跟它说,“Service,别做这事了,做那一件事吧”(其实也可以,但是每次都要重新创建一个Intent,里面定义我们要做的事情,然后再次调用startService,让它重新再做,但我觉得,这不科学)。
2)bindService。我们也可以通过 bindService的方法来将Activity 跟 Service 绑定在一起,为什么绑定Service了之后就能够随时叫Service做事了呢?因为通过绑定,从Service返回了一个继承于Binder的类给Activity,而通过这个继承类,可以在里面定义一些交互的回调函数,那么Activity就可以通过这些方法来随时告诉Service要做些啥事了,这才叫交互嘛。
那么,音乐播放器肯定是要用后面这种 bindService的方法了啊,因为我们要交互啊。先看一下界面:
在列表界面上和歌词界面上有着不同的控制按钮,比如向前向后,模式改变,播放暂停等,所以我们得想想怎么去设计Service。
如何设计Service?
我把 Service 分成三种情况:
1)要响应 Activity 中按钮的控制;
2)Service中自己要控制的逻辑,比如一首歌播放完之后,要自动播放下一首等;
3)要能够主动地去通知Activity。
第一种情况,其实就是我们要在Binder中定义的接口啦,响应列表界面的唱停前后和模式变换。
class NatureBinder extends Binder{
/**
* 唱吧,有人想听
*/
public void startPlay(int currentMusic, int currentPosition){}
/**
* 别唱了
*/
public void stopPlay(){}
/**
* 后一首
*/
public void toNext(){}
/**
* 前一首
*/
public void toPrevious(){}
/**
* 有人改变模式了,我得把它记下来
*/
public void changeMode(){}
/**
* 告诉别人,你现在到底是顺序播放,还是随机乱弹
* MODE_ONE_LOOP = 1;
* MODE_ALL_LOOP = 2;
* MODE_RANDOM = 3;
* MODE_SEQUENCE = 4;
* @return
*/
public int getCurrentMode(){}
/**
* 告诉调用者,到底有没有在做事。。。
* @return
*/
public boolean isPlaying(){}
/**
* 要告诉调用者,当前播哪首歌了,歌多长啊
*/
public void notifyActivity(){}
/**
* 有人拖动Seekbar了,要告诉service去改变播放的位置
* @param progress
*/
public void changeProgress(int progress){}
}
那么第二种情况,就是servcie本身的逻辑控制了,其实主要的逻辑是当一首歌播放完了,它得自己去判断下一首要播什么,还有没有得播啊,所以我们要实现MediaPlayer的OnCompletionListener方法,在这里,我们要实现下一步该怎么做,继续播呢,还是停下来,要不要通知列表界面,我换歌了。。。
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
...
});
}
而第三种情况,就是怎么去通知列表界面了。在这里是通过发送广播的方式,而Activity中会注册相应的广播过滤器来接收Service中发送出去的消息,比如歌曲播放的进度,换歌了之类的。下面的代码是告诉前台,我现在播到哪个位置了,你给我更新一下进度条的位置。
private void toUpdateProgress(){
if(mediaPlayer != null && isPlaying){
int progress = mediaPlayer.getCurrentPosition();
Intent intent = new Intent();
intent.setAction(ACTION_UPDATE_PROGRESS);
intent.putExtra(ACTION_UPDATE_PROGRESS,progress);
sendBroadcast(intent);
handler.sendEmptyMessageDelayed(updateProgress, 1000);
}
}
而相对应的,我们在Activity中,会接收到这样的广播,从而做相应的更新,当然,也别忘了要注册对应的Action,不然可收不到。代码如下:
private void registerReceiver(){
progressReceiver = new ProgressReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(NatureService.ACTION_UPDATE_PROGRESS);
...
registerReceiver(progressReceiver, intentFilter);
}
//上面是注册广播,下面是接收广播,最后别忘了,要注销广播
...
class ProgressReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(NatureService.ACTION_UPDATE_PROGRESS.equals(action)){
int progress = intent.getIntExtra(NatureService.ACTION_UPDATE_PROGRESS, 0);
if(progress > 0){
currentPosition = progress; // Remember the current position
pbDuration.setProgress(progress / 1000);
}
...
}
}
既然已经把Service 该干什么都想好了,那么很显然下一步,就是来调用Service了嘛。
Service该怎么用?
废话!当然是在Activity中调用了。没错,就是这样,在Activity中我们通过BindService来获得一个Binder,然后就可以通过Binder来跟Service眉来眼去地交流了。
private NatureBinder natureBinder;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
natureBinder = (NatureBinder) service;
}
};
private void connectToNatureService(){
Intent intent = new Intent(MainActivity.this, NatureService.class);
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
当然,也是有几步要走的:
1)创建一个ServiceConnection 对象,在其onServiceConnected方法中返回我们的Binder。
2)就是调用bindService了,将serviceConnection作为参数传进去。
就是这么简单,接下来,就可以拿binder来做事了。比如
播放:
natureBinder.startPlay(currentMusic,currentPosition);
暂停:
natureBinder.stopPlay();
下一首:
分享到:
相关推荐
用android的service做的音乐播放器,让service后台播放.mp3文件
Android音乐播放器实战,实现本地歌曲播放控制,可后台播放,拔出耳机暂停,来电暂停,电话挂断继续播放。这个项目很好的结合了Android的四大组件知识。其中音乐来源于手机本地,使用了Content Provider获取,播放...
Android实例源码-音乐播放器类安卓源代码(9例) ...简单音乐播放器,实现了播放器基本功能,使用service后台播放音乐,并使用异步线程加载音乐图片 边下载边播music 音乐播放器 音乐播放器 音乐播放器源码
Android实现简单音乐播放器(MediaPlayer),供大家参考,具体内容如下 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 实现一个简单的音乐播放器,要求功能有: 播放、暂停功能; 进度条显示...
android音乐播放 android音乐
使用Android实现的带进度条的播放器,音乐播放在Service中实现播放、暂停、继续和停止,但是停止和进度条的关联还有些问题,有待改进。
4.4 Android 音乐播放器的工程 - 26 - 4.4.1 Android项目 - 26 - 4.4.2 Android工程程序结构 - 27 - 4.4.3 AndroidManifest.xml文件 - 29 - 第五章 播放器系统功能详细设计 - 31 - 5.1音乐播放器主界面功能实现 - 31...
综合运用UI界面设计、Sqlite数据存储、Activity(活动)、Service(服务)、MusicPlayer(音乐播放类)、ListView(列表)、GridView(网格列表)、Fragment(碎片)、BaseAdapter(适配器)等知识,设计开发一款具有...
android音乐播放器源码(改进版)。这个版本已经放在了service中,在服务中控制播放音乐,通过BroadcastReceiver传递一些数据,并且实现了在电话打过来时,停止播放音乐,打完电话继续播放。当然还有上一个版本的甩...
Android Studio开发的简易音乐播放器app,读取本地SD卡指定路径的mp3文件进行播放,实现以下功能: 1. 播放、暂停,停止,退出功能; 2. 后台播放功能;(service) 3. 进度条显示播放进度、拖动进度条改变进度功能...
Android手机平台音乐播放器毕业论文 目录 第一章 引 言 - 1 - 1.1 项目背景 - 1 - 1.2 编写目的 - 2 - 第二章 系统需求分析 - 3 - 2.1 功能需求(用例图分析) - 3 - 2.1.1 播放器的基本控制需求 - 3 - 2.1.2 播放...
一个简单的音乐播放器。用Service后台播放音乐。用BroadcastReceiver与前台通信
音乐播放器学习下bindservice和startService。
本地service练习,实现简易音乐播放器,后台播放
Android版本4.1.2,实现资源res/raw文件中音频的播放、暂停、停止,并实现程序的退出,供初学者参考!
实现了扫描本地音乐以及音乐的播放、暂停、上一首下一首和自动循环播放,用户从点击爱心标记可以将当前歌曲加入喜欢歌曲列表,歌曲进度条可拖拽。当用户点击歌曲时开启服务在通知栏显示当前播放的歌曲。在退出app的...
综合运用UI界面设计、数据存储、Activity(活动)、Service(服务)、MusicPlayer、ListView等知识,设计开发一款具有音乐列表的音乐播放器。 运行效果演示请参考博客:...
Android高级应用源码-简单音乐播放器,实现了播放器基本功能,使用service后台播放音乐,并使用异步线程加载音乐图片.zip
Android 简单音乐播放器,具有上一曲、下一曲、播放、暂停,播放进度等功能,使用android的button、service、seekbar实现的 Android 简单音乐播放器截图
课设 实现了 播放列表 音乐播放 暂停 继续 上一首 下一首 同步SD卡歌曲,从现有文件读取歌曲,播放列表 ,提取ID3信息使用到了Activity BroadCast Service