我们今天的目的是学习如何创建一个简单的音乐播放器,可支持播放,暂停,继续播放,以及进度显示,已经进度拖拽。

既然我们的目的已经很明确,那我们先分析一下:

1: 我们播放音乐的任务可以放在Activity中吗?

假设我们当前音乐播放,我们切到别的应用,这时候播放音乐的Activity所在的进程就属于后台进程,因为后台进程会由于系统资源不足时,会杀死当前进程,会导致音乐不播放了。所以采用Activity是不行的。

2:播放音乐的任务放在一个服务中,那服务有2中启动方式,应该使用那种服务?

a:如果采用StartServer启动服务,那服务里的播放音乐的方法是没法拿到的。

b:如果采用BindService启动服务,但是BindService启动的服务,当Activity退出时,服务也会退出的。

3:所以,我们就将2中服务结合起来,用StartServer启动服务,然后用BindService绑定服务,这时候即便是Activity退出了,服务也照常工作。同时也可以拿到服务里的音乐控制方法。

那既然分析清楚了如何做。那我们就开始行动。

第一步: 先创建一个简单的Activity,里面有播放,暂停,继续播放,退出按钮(布局文件就不贴出了)。然后启动服务

 //启动服务,然后需要绑定服务conn = new MyServiceConn();intent = new Intent(this, MusicService.class);startService(intent);bindService(intent, conn, BIND_AUTO_CREATE);

第二步:在服务的OnCreate方法中创建MediaPlayer

 @Overridepublic void onCreate() {// 服务创建时,我们创建MediaPlayersuper.onCreate();player = new MediaPlayer();}

第三步:启动音乐播放,启动音乐播放当然要有步骤的:

我们先看一张关于如何启动音乐的图

从上图中可以看到,启动音乐播放需要几个步骤:

1:reset(重置)

2:setDataSource(设置数据源)

3:prepare(准备)

4:start(播放)

如果当前正在播放,需要暂停就需要调用pause()

如果想从暂停回到播放就需要调用(onstart)

如果向停止播放就需要调用(onstop),如果向接着播放就需要重新prepare,start

一下是如何启动音乐播放:

//服务的播放方法public void play(){//1: 先重置player.reset();try {//2:设置数据player.setDataSource("sdcard/smallapple.mp3");//3.准备player.prepare();//4.开始播放player.start();//5.启动定时器addTimer();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}

暂停方法:

 //服务的暂停服务public void pause(){player.pause();}

继续播放:

 //服务的继续播放public void continuePlay(){player.start();}

第四步: 如果向给音乐播放增加进度显示,那我们添加一个SeekBar,这样 以后还可以拖拽

既然需要每秒都使得进度条的进度改变,那就需要增加一个定时器,定时器每秒得到当前播放进度,然后通知UI显示更新

//添加定时器,用于每秒更新播放进度public void addTimer(){if(timer == null){timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {//获取音乐的总时间int duration = player.getDuration();//获取音乐的当前播放时间int currposition = player.getCurrentPosition();//获得到的数据,需要传入到UI更新,我们用msg传送Message msg = MainActivity.handler.obtainMessage();//通过bundle传送数据Bundle data = new Bundle();data.putInt("duration", duration);data.putInt("currposition", currposition);msg.setData(data);//发送消息给ActivityMainActivity.handler.sendMessage(msg);}//开始计时任务后的5毫秒,第一次执行run方法,以后每1000毫秒执行一次}, 5, 1000);}}

这时候当播放后,定时器获得到数据就会传送给MainActivity用于显示:

    static Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {Bundle data = msg.getData();sBar.setMax(data.getInt("duration"));sBar.setProgress(data.getInt("currposition"));};};

第五步: 如果我们想实现拖拽,就可以给SeekBar增加Seekbar改变监听

sBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stubmInterface.seekTo(seekBar.getProgress());}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {// TODO Auto-generated method stub}@Overridepublic void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {// TODO Auto-generated method stub}});

因为当我们手指滑动的过程中我们不需要让播放进度,只有当手指抬起后才播放,那我们只需要在onStopTrackingTouch中更新播放进度

到这里大概就完事了,以下是详细 代码

MainActivity中代码:

public class MainActivity extends Activity {MusicInterface mInterface;private static SeekBar sBar;private MyServiceConn conn;private Intent intent;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sBar = (SeekBar) findViewById(R.id.seekBar1);sBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stubmInterface.seekTo(seekBar.getProgress());}@Overridepublic void onStartTrackingTouch(SeekBar arg0) {// TODO Auto-generated method stub}@Overridepublic void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {// TODO Auto-generated method stub}});//启动服务,然后需要绑定服务conn = new MyServiceConn();intent = new Intent(this, MusicService.class);startService(intent);bindService(intent, conn, BIND_AUTO_CREATE);}static Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {Bundle data = msg.getData();sBar.setMax(data.getInt("duration"));sBar.setProgress(data.getInt("currposition"));};};class MyServiceConn implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName arg0, IBinder arg1) {//获得服务中间人mInterface = (MusicInterface)arg1;}@Overridepublic void onServiceDisconnected(ComponentName arg0) {// TODO Auto-generated method stub}}//开始播放public void start(View v){mInterface.play();}//暂停播放public void pause(View v){mInterface.pause();}//继续播放public void continuePlay(View v){mInterface.continuePlay();}//退出public void exit(View v){//先解绑服务unbindService(conn);//在停止服务stopService(intent);finish();}}

MusicService中代码:

public class MusicService extends Service {MediaPlayer player;private Timer timer;@Overridepublic IBinder onBind(Intent arg0) {// TODO Auto-generated method stubreturn new MusicController();}@Overridepublic void onCreate() {// 服务创建时,我们创建MediaPlayersuper.onCreate();player = new MediaPlayer();}@Overridepublic void onDestroy() {// 销毁服务时,需要先停止播放,再释放资源super.onDestroy();//停止服务player.stop();//释放底层硬件占有的资源player.release();player = null;if(timer != null){//取消定时器timer.cancel();timer = null;}}class MusicController extends Binder implements MusicInterface{@Overridepublic void play() {// TODO Auto-generated method stubMusicService.this.play();}@Overridepublic void pause() {// TODO Auto-generated method stubMusicService.this.pause();}@Overridepublic void continuePlay() {// TODO Auto-generated method stubMusicService.this.continuePlay();}@Overridepublic void seekTo(int progress) {// TODO Auto-generated method stubMusicService.this.seekTo(progress);}}//服务的播放方法public void play(){//1: 先重置player.reset();try {//2:设置数据player.setDataSource("sdcard/smallapple.mp3");//3.准备player.prepare();//4.开始播放player.start();//5.启动定时器addTimer();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}//服务的暂停服务public void pause(){player.pause();}//服务的继续播放public void continuePlay(){player.start();}//服务的拖动移动public void seekTo(int progress){player.seekTo(progress);}//添加定时器,用于每秒更新播放进度public void addTimer(){if(timer == null){timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {//获取音乐的总时间int duration = player.getDuration();//获取音乐的当前播放时间int currposition = player.getCurrentPosition();//获得到的数据,需要传入到UI更新,我们用msg传送Message msg = MainActivity.handler.obtainMessage();//通过bundle传送数据Bundle data = new Bundle();data.putInt("duration", duration);data.putInt("currposition", currposition);msg.setData(data);//发送消息给ActivityMainActivity.handler.sendMessage(msg);}//开始计时任务后的5毫秒,第一次执行run方法,以后每1000毫秒执行一次}, 5, 1000);}}}

MusicInterface中代码:

public interface MusicInterface {void play();void pause();void continuePlay();void seekTo(int progress);
}

显示效果如下:

Android 多媒体开发学习之简单的音乐播放器相关推荐

  1. Android开发做一个简单的音乐播放器

    Android开发如何做一个简单的音乐播放器,首先我们先要知道用到的知识点有哪些. 1.MediaPlayer:可以播放本地资源.sd卡内存资源以及网络uri资源,在这里我们播放sd卡上的音乐资源. ...

  2. android 音乐播放器专辑图片旋转,Android应用开发之简易、大气音乐播放器实现专辑倒影效果...

    今天要实现的功能是实现专辑倒影效果,这个功能已经属于图像处理方面的了,对图像处理我不怎么在行,等一下会介绍一个很实用的工具类,专门用来进行图像处理的.这个工具类不是我写的,我只是拿来用到自己的项目当中 ...

  3. 好程序员前端分享使用JS开发简单的音乐播放器

    好程序员前端分享使用JS开发简单的音乐播放器,最近,我们在教学生使用JavaScript,今天就带大家开发一款简单的音乐播放器.首先,最终效果如图所示: 首先,我们来编写html界面index.htm ...

  4. 一个基于Android开发的简单的音乐播放器

    一个基于Android开发的简单的音乐播放器 记得当时老师让我们写因为播放器时,脑子一头雾水,网上杂七杂八的资料也很少有用,因此索性就自己写一篇,希望对有缘人有用. 因为有好多人问我要源码,所以附上g ...

  5. android 简单的音乐播放器实现播放模式的切换

    以前写过一篇简单的音乐播放器,但是这个播放器没有实现播放模式的切换,在项目中要实现两个播放模式,循环播放和随机播放,经过这两天的努力搞定了,界面比较粗糙.可以先看一下前面的简单音乐播放器,详细的就不说 ...

  6. android 简单的音乐播放器

    在项目开发过程中需要一个简单的音频播放的功能,需求很简单,只需要能够播放一个指定文件夹的全部mp3和wav音频文件就可以,谷歌给我们提供了一套比较完整的API,使得我们可以很简单的写出一个简易的音乐播 ...

  7. Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51290181 觉得博文有用,请点赞,请留言,请关注,谢谢!~ 实现功能: 实现NetM ...

  8. Android学习之路4——音乐播放器后台播放

    Android学习之路4--音乐播放器后台播放 一.实验题目 简单音乐播放器 二.实现内容 实现一个简单的播放器,要求功能有: 播放.暂停.停止.退出功能,按停止键会重置封面转角,进度条和播放按钮:按 ...

  9. Android开发本地及网络Mp3音乐播放器(二十)歌曲下载完成后通知主界面更新本地音乐

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51448597 项目源码(打赏5积分请点这边):http://download.csdn ...

  10. Android开发本地及网络Mp3音乐播放器(十三)网络音乐搜索功能实现,歌名歌手专辑名搜索

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51298411 觉得博文有用,请点赞,请留言,请关注,谢谢!~ 实现功能: 实现网络音乐 ...

最新文章

  1. java 实验张智,JAVA实验指导
  2. 《过早退出是一切失败的根源》读后感
  3. 你知道出现“乱码”的原因是什么吗?(4)
  4. 【DP】【树状数组】免费馅饼(luogu 7302/金牌导航 数据结构优化DP-4)
  5. 大学生计算机社团该办什么活动,大学生社团活动策划方案
  6. C语言-freopen函数输入简单使用举例
  7. 【华为云技术分享】原来CTR预估模型的发展有这样的规律
  8. salt实现lamp自动化部署
  9. ad20如何画出pcb板大小_PCB板过孔对高频信号传输的影响,一定要重视
  10. 登录时候输入验证码,验证码图片从服务器获取方法
  11. Selenium+超级鹰进行识别滑动操作
  12. 计算机视觉-实验四(相机模型与参数标定)
  13. AppOps 命令大全
  14. python游戏联机后直接掉线,怪物猎人世界联机掉线怎么办 Steam联机掉线解决办法整理(一)...
  15. 使命召唤19发布时间曝光 确定将于10月28号发布
  16. 服务器性能指标图英文翻译,技术性能指标,technic performance guildline,在线英语词典,英文翻译,专业英语...
  17. 【毛球科技】食品供应链的可持续性挑战
  18. 聚名网:华为申请“燃力红”商标,广告语注册商标需要符合哪些条件呢?
  19. 速码工具箱,Excel批量生成二维码,瞬间搞定!
  20. 【VSCode】 VSCode配置LeetCode插件

热门文章

  1. 重读《从菜鸟到测试架构师》--构建测试
  2. 《众妙之门 JavaScript与jQuery技术精粹》 - 读书笔记总结[无章节版][1-60]
  3. [No000023]为何没有更多人从事程序员的工作?程序员常有,优秀程序员不常有!...
  4. Android2.2 新特性
  5. AIX PV VG LV详解
  6. Objective C类方法load和initialize的区别
  7. Python UDP broadcast PermissionError: [Errno 13] Permission denied
  8. Android Root权限静默安装
  9. 虚拟桌面与代理服务器的那些事
  10. SharePoint 2010工作流系列(2):SharePoint Designer 2010中工作流的条件和操作概览