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

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

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

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

	@Override
	public void onCreate() {
		// 服务创建时,我们创建MediaPlayer
		super.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 block
			e.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() {

				@Override
				public 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);
					//发送消息给Activity
					MainActivity.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() {

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
				mInterface.seekTo(seekBar.getProgress());
			}

			@Override
			public void onStartTrackingTouch(SeekBar arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public 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;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sBar = (SeekBar) findViewById(R.id.seekBar1);
        sBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
				mInterface.seekTo(seekBar.getProgress());
			}

			@Override
			public void onStartTrackingTouch(SeekBar arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public 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
    {
		@Override
		public void onServiceConnected(ComponentName arg0, IBinder arg1) {
			//获得服务中间人
			mInterface = (MusicInterface)arg1;
		}

		@Override
		public 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;
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return new MusicController();
	}

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

	@Override
	public void onDestroy() {
		// 销毁服务时,需要先停止播放,再释放资源
		super.onDestroy();
		//停止服务
		player.stop();
		//释放底层硬件占有的资源
		player.release();
		player = null;
		if(timer != null)
		{
			//取消定时器
			timer.cancel();
			timer = null;
		}
	}

	class MusicController extends Binder implements MusicInterface
	{

		@Override
		public void play() {
			// TODO Auto-generated method stub
			MusicService.this.play();
		}

		@Override
		public void pause() {
			// TODO Auto-generated method stub
			MusicService.this.pause();
		}

		@Override
		public void continuePlay() {
			// TODO Auto-generated method stub
			MusicService.this.continuePlay();
		}

		@Override
		public void seekTo(int progress) {
			// TODO Auto-generated method stub
			MusicService.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 block
			e.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() {

				@Override
				public 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);
					//发送消息给Activity
					MainActivity.handler.sendMessage(msg);

				}
				//开始计时任务后的5毫秒,第一次执行run方法,以后每1000毫秒执行一次
			}, 5, 1000);
		}
	}

}

MusicInterface中代码:

public interface MusicInterface {

	void play();
	void pause();
	void continuePlay();
	void seekTo(int progress);
}

显示效果如下:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-10 16:20:45

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

用H5+Boostrap做简单的音乐播放器

用H5+Boostrap做简单的音乐播放器 前言:这个是综合一下我最近在学的东西做的小Demo,到实际使用还有距离,但是用来练手巩固知识点还是不错的,最近在二刷JS书和Boostrap.css的源码,做完这个Demo也算是暂告一段落,接下来是jQuery的源码和Boostrap.js的源码,任务很艰巨呢,加油~在此就不整篇的贴代码了,如果感兴趣的小伙伴可以发消息给我,可以把代码传给你们~ 正文: 先上效果图 1.布局:Boostrap里的响应式和自适应布局是自然跑不掉的,container中嵌套

简单本地音乐播放器

// //  ViewController.m //  AudioPlayer // //  Created by apple on 14-7-18. //  Copyright (c) 2014年 苹果IOS软件开发者. All rights reserved. // #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewController ()<AVAudi

Android学习之旅--简易音乐播放器实现之前期准备

学习Android有两个月了,感觉现在进入一个瓶颈--基础知识了解,但是不能灵活运用.我想这是所有新手学习android时都会遇到的 问题,所以打算做一个简易音乐播放器的小项目,这也是特别适合新手的练习项目.虽然小,但是也能考察不少东西.前几天看到一句话-----编 程不仅是一种知识,更是一种技能.既然是技能,那就需要不断练习才能熟练掌握. 项目目标前期实现本地音乐的播放,后期会往网络音乐方面发展,如果进行顺利的话,我会将源码放在github上,欢迎各位大神指导^- ^.我会坚持每天一更,记录每

Android开发本地及网络Mp3音乐播放器(十八)新下载歌曲加载准备SdcardSearchToList

扫描本地文件加载到item 不限于应用到音乐播放器,其他Android工程,也可以使用SdcardSearchToList 其他Android工程也可以使用,我现在做了很小的Demo 后续将博文,将在播放器里,加入这一功能,来实现刚下载好的音乐,加载到播放器 这个Demo的源码下载: http://download.csdn.net/album/detail/3105 名称为:SdcardSearchToList,如果没有显示,可能还没有审核完成 不下载也可以,因为只有1个java文件,2个xm

【程序开发小记】VB.NET音乐播放器

写在前面的话: 为了营造一个很好的交流学习的环境,也是为了迎合学校毕业设计的需求,开通了博客园.在下学期伊始,会每星期更新毕业设计的进度.博客业已开通,为了交流学习,要只是更新毕业设计的进度显得有些做作.博主并不是好看书时写些小评的主儿,遂不知有和内容好献于此,只得将之前课程中或是实习时开发的程序在此做个简述. 因这些项目也是博主心血,也是怕某些学弟学妹直接搬用引发事端,不便将源码原封不动摆在这里,在此只做简要说明. 若有意愿交流学习,可以在评论或是私信留下联系方式. 话不多说,接下来直奔主题.

用PHP+H5+Boostrap做简单的音乐播放器(进阶版)

前言:之前做了一个音乐播放器(纯前端),意外的受欢迎,然后有人建议我把后台一起做了,正好也想学习后台,所以学了两天php(不要吐槽我的速度,慢工出细活嘛~)然后在之前的基础上也又完善了一些功能,所以这个Demo比之前的可以算是进阶呢~v2.0哈哈哈~感觉截图体验很不好呢,所以在美图秀秀上面做了简易的动图,大家感受感受 正文: 老规矩,先上图~感觉有点卡,愿意等的就等等嘛,不愿意等的,往下看,有图片讲解 功能实现: 1.点击音乐列表播放音乐 2.拖动或点击进度条,调节音乐播放进度 3.浮动到音量控

新手作品~~~简单版音乐播放器

为了完成别人交给的小任务,作为一个新手看了很多的视频教程,实在是难死宝宝了,好在终于找到一篇合适我的布局的关于音乐播放器布局的文章,所以用了两天,就照猫画虎的学了下来,为了完全适配我的布局文件,删删减减,查了很多资料....才算是搞出个基本样子,废话不多说,直接上代码和效果图,新人作品,不喜勿喷. 功能很简单: 1.扫描sd卡内的音乐文件,将扫描到的音乐文件加载到音乐列表中. 2.点击音乐列表,实现播放音乐的功能 3.点击播放控制按钮(播放/暂停 上/下一曲)实现相关功能 首先是三个Java文件

Android开发本地及网络Mp3音乐播放器(八)状态存取与界面滑动

实现功能: 退出应用时,保存歌曲位置(也就是当前是第几首歌曲) 退出应用时,保存播放模式(也就是用户设置的是顺序播放/随机播放/单曲循环) 进入应用时,读取歌曲位置 进入应用时,读取播放模式 实现PlayActivity(独立音乐播放界面)的专辑图片layout滑动,滑动后展示歌词layout (目前源码,只实现了专辑图片layout与歌词layout,歌词layout的信息填充后续会进行补充) 截止到目前的源码下载: http://download.csdn.net/detail/iwangh

Android开发本地及网络Mp3音乐播放器(九)音乐收藏与列表切换

实现功能: 使用快速开发框架xUtils中的DbUtils模块,为音乐收藏功能做准备 实现PlayActivity(独立音乐播放界面)收藏.取消收藏按钮 实现MainActivity(主界面)菜单选择事件进入MyLoveMusicActivity(音乐收藏界面) 实现本地音乐列表与音乐收藏列表切换功能 (目前源码,只实现了音乐收藏列表,菜单中最近播放列表后续会进行补充) 截止到目前的源码下载: http://download.csdn.net/detail/iwanghang/9504916 x