在开始正式开发功能以前,我们需要对要完成的功能做一个技术验证,确保有足够的能力和技术积累能完成它。
之后再根据调查的结果,设计程序的结构。这就好比造房子之前要规划好蓝图,不然房子很可能造着造着就暴露出很多没有想到的问题。
安卓系统作为一个应用开发的框架,为我们提供了丰富的工具,包括了音乐播放支持,很多格式的音乐都能播放。正因如此,我们才不需要从第一行代码开始去研究各种音频格式,不用去考虑二进制格式的音频文件该如何解包、如何解码等等。
只需要告诉系统,我有一个音频文件,要交给你播放,怎么播放的我不管,你全权负责,只需要把播放时的状态向我报告就好了。
安卓系统提供的组件MediaPlayer
就能实现音频文件的播放,我们只需要遵循以下的步骤,
创建一个MediaPlayer
对象,
MediaPlayer mMusicPlayer = new MediaPlayer();
为MediaPlayer
设置要播放的文件,可以是文件的物理地址,也可以是文件的Uri地址,
mMusicPlayer.setDataSource(context, songUri);
设置完成参数,准备播放,
mMusicPlayer.prepare();
播放、暂停、停止播放,
//开始播放
mMusicPlayer.start();
//暂停播放
mMusicPlayer.pause();
//停止播放
mMusicPlayer.stop();
//重置播放器
mMusicPlayer.reset();
//跳转到特定时间
mMusicPlayer.seekTo();
通过设置监听器,获取播放器返回的各种播放状态,
//注册监听器,监听音乐是否播放完成
mMusicPlayer.setOnCompletionListener(mOnCompletionListener);
private MediaPlayer.OnCompletionListener mOnCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//完成播放后会触发这里被调用
}
};
//注册监听器,监听音乐是否播放错误
mMusicPlayer.setOnErrorListener(null);
例如播放一个Uir地址为content://media/external/audio/media/20422
的音乐,
try {
Uri songUri = Uri.parse("content://media/external/audio/media/20422");
MediaPlayer mMusicPlayer = new MediaPlayer();
mMusicPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//完成播放后会触发这里被调用
}
});
mMusicPlayer.setDataSource(MusicListActivity.this, songUri);
mMusicPlayer.prepare();
mMusicPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
如果你此时对Uri
并不熟悉,没有关系,就把它当作文件的一个地址就好了,我们会在后面的章节做详细的介绍。
播放列表需要能长期的存储起来,即使程序退出了,下次启动的时候也能得到上次等待播放的音乐任务。
这里我们将正在播放的音乐列表存储到安卓系统提供的SQLite
数据库中。
这个数据库可以被要获取它保存的数据的组件直接使用,也可以被封装在自定义的ContentProvider
当中,让别人通过查询ContentProvider
来间接使用。
ContentProvider
是安卓开发中很重要的组件之一,可以向其他组件提供数据访问的能力。它就像是一个网站,其他组件(或者其他应用)可以通过“网址”访问它,获取需要的信息。因此它可以作为不同应用之间共享数据的一种方式。
以后很多应用的开发可能都会与它打交道,都需要我们自定义一个合适的ContentProvider
。所以我们就借此机会来学习如何自定义一个ContentProvider
吧。
自定义一个ContentProvider
,需要
ContentProvider类
重新创建一个类,并实现其中的一些方法;AndroidManifest.xml
文件中,声明这个新添加的组件;在这里,我们将利用它来存储播放列表。
启动主界面的Activity
,在该Activity
中创建MediaPlayer
,让它来播放音乐看起来是可以的,不过这种设计有个很严重的问题-音乐不能在后台播放,也就是说你不能一边听音乐,一边刷微博。
原因很简单,当前的程序结构将系统的MediaPlayer
与播放器的主界面Activity
关联在一起。当主界面的Activity
被用户按下了返回键时,它会被系统销毁。逻辑上讲,主界面Activity
所包含的MediaPlayer
也就应该寿终正寝了,怎么还能让它来继续播放音乐呢?!
所以在此,我们需要一个能够在主界面Activity
退出以后,还能保证让MediaPlayer
继续工作的方案。这个问题的解决方案,将有安卓系统的另一个重要组件Service
提供。
Service
就像是个不需要界面显示的Activity
(虽然不太严谨,但大体上可以这样想象,帮助我们理解新的概念),它运行在系统的后台,当系统资源不足需要进行强行的资源回收时,回收优先级也比那些没有显示出来的Activity低,正是我们用来委托播放音乐最好的组件。
桌面小工具的实现,由安卓系统给出了专门的设计方案。
桌面小工具是安卓系统桌面框架的一部分,不需要我们绞尽脑汁从头设计,只要按照它的设计规则来开发就可以了。
在项目工程上点击右键,选择new->Wideget->App Widget
就为我们创建好了开发用的模版,非常的简单方便。
基于上面的分析,我们将整个应用的框架做了大致的梳理,
主界面Activity
-MusicListActivity
:展示音乐列表,当前播放进度;它与播放服务
建立联系,获取播放列表和播放控制接口;
播放列表记录存储模块-PlayListContentProvider
:记录当前的播放列表;提供给播放服务使用;
播放服务-MusicService
:对外,为主界面MusicListActivity
提供控制音乐播放、操作播放列表的接口;对内从PlayListContentProvider
获取播放列表的操作,拥有MediaPlayer
对象,实际的控制播放器;
桌面小工具-AnddleMusicAppWidget
:与MusicService
联系,提供主界面上快速控制音乐播放流程的便捷方式;
/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。
*另外,我们还推出了Arduino智能硬件相关的教程,您可以在我们的网店跟我学Arduino开发中购买相关硬件。同时也感谢大家对我们这些码农的支持。
*最后再次感谢各位读者对安豆
的支持,谢谢:)
/*******************************************************************/