Android最简单音乐播放器的小例子总结
这只是一个小例子,实现三首mp3格式音乐的循环播放,并且有播放、暂停、停止的功能。
大体思想:
-
需要一个Activity用来与用户交互当前播放情况,用户通过点击按钮操作播放、暂停和停止。
-
还需要有一个后台Service处理音乐的播放(还好Android有MediaPlayer对象可以对音乐进行播放、暂停等操作)。
-
Activity和Service之间需要进行交互,
(1)用户点击按钮执行音乐的播放、暂停或者停止,每一个按钮对应一种状态,通过Broadcast广播传给Service。
(2)Service接收Activity发来的广播,对操作进行判断从而执行MediaPlayer的音乐操作。之后将音乐的信息同样以广播的形式发送回Activity。
(3)Activity接收Service的广播在页面上更新歌曲的信息。
下面是细节的问题:
1.首先Activity布局非常简单,一个文本框用来显示歌曲名,两个按钮,“播放”和“停止”。
2.然后是Activity:
(1)onCreate()方法:
这是Activity第一次创建的时候调用的,因此默认代码就是将布局文件进行加载。除了这些内容,我们要获取获取布局文件上的组件,尤其是Button,我们需要定义监听器处理用户点击的事件(一会就会说到)。其实最主要的两件事是创建BroadcastReceiver对象、Intent过滤器和Receiver的注册(Broadcast不同于监听器,Broadcast是一个系统级的监听器,拥有自己的进程,因此只要存在与之匹配的Intent被广播出来,BroadcastReceiver总会被触发),然后开启后台的Service。
ar = new ActivityReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(UPDATE_ACTION); //update更改界面播放信息
getApplicationContext().registerReceiver(ar,filter);
Intent in = new Intent(MainActivity.this,MP3Service.class);
startService(in); //开启Service
(2)定义BroadcastReceiver的子类并重写onReceive方法,这是Service发送歌曲信息的广播,然后Activity获取并更新页面的Receiver:onReceive方法在应用发送相应广播后自动执行,执行之后BroadcastReceiver实例就会被销毁。
public class ActivityReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("activity receive");
int update = intent.getIntExtra("update", -1);
int current = intent.getIntExtra("current", -1);
if(current>=0){
title.setText(titleStrs[current]);
}
switch(update){
case 0x11:
play.setText(R.string.play);
break;
case 0x12:
play.setText(R.string.pause);
break;
case 0x13:
play.setText(R.string.play);
break;
}
}
}
(3)onClick:首先Activity有两个按钮,定义一个control状态代表哪个按钮被执行,播放和暂停是一类的,停止是第二类的,将哪个按钮被执行的control状态封装到Intent中,然后发送广播给Service。
public void onClick(View source) {
Intent in = new Intent(CTL_ACTION); //Service中广播处理的是CTL_ACTION的Intent
switch(source.getId()){
case R.id.play:
in.putExtra("control", 1);
break;
case R.id.stop:
in.putExtra("control", 2);
break;
}
sendBroadcast(in);//发送广播到service
System.out.println("activity send");
}
(4)onDestroy:最后,因为Service是Activity开启的,而且同样在onCreate中注册了BroadcastReceiver,因此当Activity被销毁时,也需要将Service和BroadcastReceiver释放:
protected void onDestroy() {
stopService(in);
getApplicationContext().unregisterReceiver(ar);
super.onDestroy();
}
3.接着是Service:
(1)onCreate:创建MediaPlayer对象,为MediaPlayer设置CompletingListener监听器(当前数据被播放完之后执行,用来播放下一首),创建AssetManager对象用于读取sdcard的音乐文件,并创建接收Activity广播的BroadcastReceiver:
asset = getAssets();
mr = new MyReceiver();
IntentFilter filter = new IntentFilter(MainActivity.CTL_ACTION); //控制播放
getApplicationContext().registerReceiver(mr,filter);
mp = new MediaPlayer();
(2)MediaPlayer的监听器:根据current当前歌曲的标号进行歌曲的切换,并发送下一首歌曲的信息通过广播发送给Activity:
mp.setOnCompletionListener(new OnCompletionListener(){
@Override
public void onCompletion(MediaPlayer mp) {
current = current+1; //从0开始的,0,1,2三首
if(current>=3){
current = 0;
}
//通知界面更新歌曲信息
Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("current", current);
sendBroadcast(sendIntent);
prepareAndPlay(songs[current]);
}
});
(3)最重要的接收Activity中用户点击按钮的状态发来的广播进行音乐播放处理的Receiver:
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("serivce receive");
int control = intent.getIntExtra("control",-1);
switch(control){
case 1: //播放或暂停
if(status==0x11){
prepareAndPlay(songs[current]);
status = 0x12;
}
else if(status==0x12){
mp.pause();
status = 0x13;
}
else if(status==0x13){
mp.start();
status = 0x12;
}
break;
case 2: //停止音乐
if(status==0x12||status==0x13){
mp.stop();
status = 0x11;
}
}
Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("current",current);
sendIntent.putExtra("update", status);
sendBroadcast(sendIntent);
System.out.println("service send");
}
}
(4)最后在onDestroy中释放Receiver:
public void onDestroy() {
System.out.println("ondestroy");
getApplicationContext().unregisterReceiver(mr);
super.onDestroy();
}
(5)有一个细节,就是在播放完一个歌曲之后,再播放下一个的时候,MediaPlayer对象一定要执行reset方法,不然会发生MediaPlayer状态的异常。以下是prepareAndPlay方法:
public void prepareAndPlay(String music){
try{
File f = new File(Environment.getExternalStorageDirectory()+"/"+music);
if(f.exists()){
System.out.println("--cunzai--");
}
//AssetFileDescriptor afd = asset.openFd(Environment.getExternalStorageDirectory()+"/"+music);
try {
mp.reset(); //在执行新的一次play的时候需要reset
mp.setDataSource(Environment.getExternalStorageDirectory()+"/"+music);
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch(Exception e){
}
}
4.最后别忘记在Manifest文件中配置Service,由于Receiver是在代码中生成的,因此无需进行配置。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。