今天的球员趁service。播放音乐service结束,进度条activity结束,因此,基础工作activity和service互动,本文将使用IBinder互动。主要activity能够调用service的函数。能够參考我的这篇博客

本文关键点:利用利用IBinder实现activity 控制service

实现功能:

1 控制播放进度:

activity调用service的函数,对MediaPlayer进行控制。

包含启动时的播放和滑动seekbar时。对MediaPlayer进行设置,达到控制播放进度的控制。

2 播放进度更新:

在activity开启多线程。后台每隔100ms就发送一次message,在UI线程中利用handler对message进行判定,之后activity调用service的函数。得到播放的进度(百分比),及时更新seekbar的进度条。

效果图例如以下:

布局非常easy,例如以下所看到的:

<?xml version="1.0" encoding="utf-8"?

>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="play"/> <Button
android:id="@+id/playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="play"
/> <Button
android:id="@+id/pauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="pause"
/> <SeekBar
android:id="@+id/seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:max="100"
android:progress="10"
/> </LinearLayout>

activity的代码例如以下:

<pre name="code" class="java">public class MainActivity extends Activity {

	Boolean mBound = false;

	MusicService mService;

	SeekBar seekBar;

	//多线程,后台更新UI
Thread myThread; //控制后台线程退出
boolean playStatus = true; //处理进度条更新
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg){
switch (msg.what){
case 0:
//从bundle中获取进度。是double类型,播放的百分比
double progress = msg.getData().getDouble("progress"); //依据播放百分比,计算seekbar的实际位置
int max = seekBar.getMax();
int position = (int) (max*progress); //设置seekbar的实际位置
seekBar.setProgress(position);
break;
default:
break;
} }
}; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //定义一个新线程。用来发送消息。通知更新UI
myThread = new Thread(new MyThread()); //绑定service;
Intent serviceIntent = new Intent(this , MusicService.class); //假设未绑定,则进行绑定
if(!mBound){
bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
} //初始化播放button
Button playButton = (Button)findViewById(R.id.playButton);
playButton.setOnClickListener(new OnClickListener(){ @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(mBound){
mService.play();
}
} }); //初始化暂停button
Button pauseButton = (Button)findViewById(R.id.pauseButton);
pauseButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//首先须要判定绑定情况
if(mBound){
mService.pause();
}
}
}); seekBar = (SeekBar)findViewById(R.id.seekbar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override
public void onStopTrackingTouch(SeekBar seekBar) {
//手动调节进度
// TODO Auto-generated method stub
//seekbar的拖动位置
int dest = seekBar.getProgress();
//seekbar的最大值
int max = seekBar.getMax();
//调用service调节播放进度
mService.setProgress(max, dest);
} @Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub } @Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub } }); } //实现runnable接口。多线程实时更新进度条
public class MyThread implements Runnable{ //通知UI更新的消息 //用来向UI线程传递进度的值
Bundle data = new Bundle(); //更新UI间隔时间
int milliseconds = 100;
double progress;
@Override
public void run() {
// TODO Auto-generated method stub //用来标识是否还在播放状态,用来控制线程退出
while(playStatus){ try {
//绑定成功才干開始更新UI
if(mBound){ //发送消息,要求更新UI Message msg = new Message();
data.clear(); progress = mService.getProgress();
msg.what = 0; data.putDouble("progress", progress);
msg.setData(data);
mHandler.sendMessage(msg);
}
Thread.sleep(milliseconds);
//Thread.currentThread().sleep(milliseconds);
//每隔100ms更新一次UI } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} } /** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() { @Override
public void onServiceConnected(ComponentName className,
IBinder binder) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
MyBinder myBinder = (MyBinder) binder; //获取service
mService = (MusicService) myBinder.getService(); //绑定成功
mBound = true; //开启线程,更新UI
myThread.start();
} @Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
}; @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public void onDestroy(){
//销毁activity时。要记得销毁线程
playStatus = false;
super.onDestroy();
} }

service的代码例如以下:

public class MusicService extends Service {

	IBinder musicBinder  = new MyBinder();

	//获取到activity的Handler。用来通知更新进度条
Handler mHandler; //播放音乐的媒体类
MediaPlayer mediaPlayer; //本地歌曲的路径
String path = "/storage/sdcard1/Music/浪漫满屋.mp3"; private String TAG = "MyService"; @Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() executed"); init(); } @Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
//当绑定后。返回一个musicBinder
return musicBinder;
} class MyBinder extends Binder{ public Service getService(){
return MusicService.this;
}
} //初始化音乐播放
void init(){
//进入Idle
mediaPlayer = new MediaPlayer();
try {
//初始化
mediaPlayer.setDataSource(path); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); // prepare 通过异步的方式装载媒体资源
mediaPlayer.prepareAsync(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} //返回当前的播放进度,是double类型,即播放的百分比
public double getProgress(){
int position = mediaPlayer.getCurrentPosition(); int time = mediaPlayer.getDuration(); double progress = (double)position / (double)time; return progress;
} //通过activity调节播放进度
public void setProgress(int max , int dest){
int time = mediaPlayer.getDuration();
mediaPlayer.seekTo(time*dest/max);
} //測试播放音乐
public void play(){
if(mediaPlayer != null){
mediaPlayer.start();
} }
//暂停音乐
public void pause() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
} //service 销毁时。停止播放音乐,释放资源
@Override
public void onDestroy() {
// 在activity结束的时候回收资源
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
super.onDestroy();
}
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

android 使用 service 实现音乐的更多相关文章

  1. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

  2. 【Android 】Service 全面总结

    1.Service的种类 按运行地点分类: 类别 区别  优点 缺点   应用 本地服务(Local) 该服务依附在主进程上,  服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外L ...

  3. Android Activity/Service/Broadcaster三大组件之间互相调用

    我们研究两个问题,1.Service如何通过Broadcaster更改activity的一个TextView.(研究这个问题,考虑到Service从服务器端获得消息之后,将msg返回给activity ...

  4. Android应用开发--MP3音乐播放器代码实现(一)

    需求1:将内存卡中的MP3音乐读取出来并显示到列表当中 1.   从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象 2.   迭代List集合,把每一个Mp3 ...

  5. BroadcastReceiver的实例----基于Service的音乐播放器之二

    该程序的后台Service会在播放状态发生改变时对外发送广播(广播将会激发前台Activity的BroadcastReceiver):它也会采用BroadcastReceiver监听来自前台Activ ...

  6. android服务Service(上)- IntentService

    Android学习笔记(五一):服务Service(上)- IntentService 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服 ...

  7. Android它Service

    服务是一段代码的后台执行. 无法处理,也不是螺纹,但它是在进程和线程的执行. Android该服务与Activity不同,不能与用户交互,无法启动自己. 媒体播放服务.当用户退出媒体选择用户界面,不过 ...

  8. Android Foreground Service (前台服务)

    一.如何保活后台服务 在Android Services (后台服务) 里面,我们了解了Android四大组件之一的Service,知道如何使用后台服务进行来完成一些特定的任务.但是后台服务在系统内存 ...

  9. 关于Android的Service知识点,你知道吗?

    目录 学习Service相关知识点: 概述: Service生命周期: Service的基本用法: 服务. 问:达叔,今日工作累吗? 答:累啊,那么问你,你知道Android中的 Service(服务 ...

随机推荐

  1. Maven直接部署Web应用Tomcat

    1. 下载解压版tomcat,并配置环境变量.所以tomcat你可以成功启动. 使用版本解压tomcat可以方便查看tomcat的后台输出的出错信息,便于调试. 2. 给tomcat配置用户名密码. ...

  2. bootstrap之Click大事

    上一篇文章中谈到了bootstrap流程,本文开始把目光bootstrap它可以接受指令(从源代码视图的透视.因为appium该项目现在还处于不断更新,因此,一些指令已经实现.也许未来会实现一些.从视 ...

  3. SSH-Struts(两)—调节器(ActionServlet)

    第一部分介绍的博客Struts架构,下一节介绍中特定成分,这个博客是写Struts控制器ActionServlet. 扮演的角色 ActionServlet类是Struts的控制中心,全部来自于浏览器 ...

  4. My97DatePicker日历控件日报、每周和每月的选择

    My97DatePicker日历控件日报.每周和每月的选择 1.设计源代码 <%@ page language="java" import="java.util.* ...

  5. 《学习opencv》笔记——矩阵和图像处理——cvAnd、cvAndS、cvAvg and cvAvgSdv

    矩阵和图像的操作 (1)cvAnd函数 其结构 void cvAnd( //将src1和src2按像素点取"位与运算" const CvArr* src1,//第一个矩阵 cons ...

  6. Redis 缓存 + Spring 的集成示例(转)

    <整合 spring 4(包括mvc.context.orm) + mybatis 3 示例>一文简要介绍了最新版本的 Spring MVC.IOC.MyBatis ORM 三者的整合以及 ...

  7. 开展project 正常的生活之路

    相对刚走出学校的学生在其他行业工作,竞争力的薪酬,同时.并不断地不仅学习更新专业知识让你感到生活的充实,更满足了你那不让外人知的虚荣心.在刚出校门的几年中,你常常回头看看被你落在后面的同学们,在内心怜 ...

  8. handlebar的一些用法——个人使用总结

    handlebar的一些用法 概述与介绍 Handlebars 是 JavaScript 一个语义模板库,通过对view和data的分离来快速构建Web模板.它采用"Logic-less t ...

  9. AES加密CBC模式兼容互通四种编程语言平台【PHP、Javascript、Java、C#】

    原文:AES加密CBC模式兼容互通四种编程语言平台[PHP.Javascript.Java.C#] 由于本人小菜,开始对AES加密并不了解,在网络上花了比较多时间查阅资料整理: 先简单从百度找来介绍: ...

  10. 经典算法题每日演练——第十七题 Dijkstra算法

    原文:经典算法题每日演练--第十七题 Dijkstra算法 或许在生活中,经常会碰到针对某一个问题,在众多的限制条件下,如何去寻找一个最优解?可能大家想到了很多诸如“线性规划”,“动态规划” 这些经典 ...