前言
本次AS作业将实现利用AS里的广播实现一个简单的音乐播放器,具体功能有播放,暂停,上一曲,下一曲等.
具体实施
1.首先在MainActivity文件里,我们需要做到音乐播放器的一些基础控件的获取,监听.注册BroadcastReceiver并进行定义等工作.
public class MainActivity extends Activity implements View.OnClickListener {
// 获取界面中显示歌曲标题、作者文本框
TextView title, author;
// 播放/暂停、停止按钮
ImageButton play, stop, next, last;
ActivityReceiver activityReceiver;
public static final String CTL_ACTION =
"org.ssh.action.CTL_ACTION";
public static final String UPDATE_ACTION =
"org.ssh.action.UPDATE_ACTION";
// 定义音乐的播放状态,0x11代表没有播放;0x12代表正在播放;0x13代表暂停
int status = 0x11;
String[] titleStrs = new String[]{"Starfall","你曾是少年","夏天的风","打上花火"};
String[] authorStrs = new String[]{"袁娅维","泠鸢yousa","泠鸢yousa","DAOKO;米津玄师"};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取程序界面界面对应按钮
play = this.findViewById(R.id.imgplay);
stop = this.findViewById(R.id.imgstop);
next = this.findViewById(R.id.imgnext);
last = this.findViewById(R.id.imglast);
title = this.findViewById(R.id.txttitle);
author = this.findViewById(R.id.txtauthor);
// 为四个按钮的单击事件添加监听器
play.setOnClickListener(this);
stop.setOnClickListener(this);
next.setOnClickListener(this);
last.setOnClickListener(this);
activityReceiver = new ActivityReceiver();
// 创建IntentFilter
IntentFilter filter = new IntentFilter();
// 指定BroadcastReceiver监听的Action
filter.addAction(UPDATE_ACTION);
// 注册BroadcastReceiver
registerReceiver(activityReceiver, filter);
Intent intent = new Intent(this, MyMusicService.class);
// 启动后台Service
startService(intent);
}
// 自定义的BroadcastReceiver,负责监听从Service传回来的广播
public class ActivityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 获取Intent中的update消息,update代表播放状态
int update = intent.getIntExtra("update", -1);
// 获取Intent中的current消息,current代表当前正在播放的歌曲
int current = intent.getIntExtra("current", -1);
//如果状态为正在播放歌曲或暂停
if (current >= 0 && (update == 0x12 || update == 0x13 || update == 0x14)) {
title.setText(titleStrs[current]);
author.setText(authorStrs[current]);
}
//如果状态为未播放歌曲
else {
title.setText("未播放歌曲");
author.setText("未播放歌曲");
}
switch (update) {
//如果未播放歌曲,则播放图标为播放
case 0x11:
play.setImageResource(R.drawable.play);
status = 0x11;
break;
//如果正在播放歌曲,则播放图标为暂停
case 0x12:
play.setImageResource(R.drawable.pause);
status = 0x12;
break;
case 0x13:
play.setImageResource(R.drawable.play);
status = 0x13;
break;
case 0x14:
break;
}
}
}
@Override
public void onClick(View source)
{
// 创建Intent
Intent intent = new Intent("org.ssh.action.CTL_ACTION");
switch (source.getId())
{
// 按下播放/暂停按钮
case R.id.imgplay:
intent.putExtra("control", 1);
break;
// 按下停止按钮
case R.id.imgstop:
intent.putExtra("control", 2);
break;
//按下下一曲按钮
case R.id.imgnext:
intent.putExtra("control",3);
break;
//按下上一曲按钮
case R.id.imglast:
intent.putExtra("control",4);
break;
}
// 发送广播,将被Service组件中的BroadcastReceiver接收到
sendBroadcast(intent);
}
}
2.新建MyMusicService文件,将广播嵌套进Service,完成音乐播放器的播放,暂停等功能.
public class MyMusicService extends Service {
MyReceiver serviceReceiver;
AssetManager am;
String[] musics=new String[]{"Starfall.mp3","你曾是少年.mp3","夏天的风.mp3","打上花火.mp3"};
MediaPlayer mPlayer;
//0x11表示没有播放,0x12代表正在播放,0x13代表暂停
int status=0x11;
int current=0;
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate(){
super.onCreate();
am=getAssets();
//创建BroadcastReceiver
serviceReceiver=new MyReceiver();
//创建IntentFilter
IntentFilter filter=new IntentFilter();
filter.addAction(MainActivity.CTL_ACTION);
registerReceiver(serviceReceiver,filter);
mPlayer=new MediaPlayer();
//为MediaPlayer播放完成事件绑定监听器
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
current++;
if (current>=4)
{
current=0;
}
Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("update",0x14);
sendIntent.putExtra("current",current);
//发送广播,将被Activity组件中的BroadcastReceiver接收
sendBroadcast(sendIntent);
//准备播放音乐
prepareAndPlay(musics[current]);
}
});
}
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
int control =intent.getIntExtra("control",-1);
switch (control)
{
//播放或暂停
case 1:
//原来处于没有播放状态
if (status==0x11)
{
//准备并播放音乐
prepareAndPlay(musics[current]);
status=0x12;
}
//原来处于播放状态
else if (status==0x12)
{
//暂停
mPlayer.pause();
//改变为暂停状态
status=0x13;
}
//原来处于暂停状态
else if (status==0x13)
{
//播放
mPlayer.start();
//改变状态
status=0x12;
}
break;
//停止声音
case 2:
//如果原来正在播放或暂停
if (status==0x12||status==0x13) {
//停止播放
mPlayer.stop();
status = 0x11;
}
break;
case 3:
//原来处于没有播放或暂停状态
if (status==0x11||status==0x13)
{
if(current==0) {
current=3;
prepareAndPlay(musics[current]);
}
//准备并播放音乐
else {
current=current-1;
prepareAndPlay(musics[current]);
}
status=0x12;
}
//原来处于播放状态
else if (status==0x12)
{
//上一首//准备并播放音乐
if(current==0) {
current=3;
prepareAndPlay(musics[current]);
}
else {
current=current-1;
prepareAndPlay(musics[current]);
}
}
break;
case 4:
//原来处于没有播放或暂停状态
if (status==0x11||status==0x13)
{
if(current==3) {
current=0;
prepareAndPlay(musics[current]);
} //准备并播放音乐
else {
current=current+1;
prepareAndPlay(musics[current]);
}
status=0x12;
}
else if (status==0x12)
{
if(current==3) {
current=0;
prepareAndPlay(musics[current]);
}
else {
current=current+1;
prepareAndPlay(musics[current]);
}
}
break;
}
//广播通知Activity更改图标、文本框
Intent sendIntent=new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("update",status);
sendIntent.putExtra("current",current);
//发送广播,将被Activity组件中的BroadcastReceiver接收
sendBroadcast(sendIntent);
}
}
private void prepareAndPlay(String music)
{
try
{
//打开指定音乐文件
AssetFileDescriptor afd=am.openFd(music);
mPlayer.reset();
//使用MediaPlayer加载指定的音乐文件
mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
//准备声音
mPlayer.prepare();
//播放
mPlayer.start();
}catch (IOException e) {
e.printStackTrace();
}
}
}
3.完成效果
总结
本次音乐播放器实现了将AS里的广播嵌套进Service里使用,是一个很典型的范例.值得学习.
附上完整代码链接:https://gitee.com/delta-jiuli/MusicBroadcast