基於Service的音樂播放器
開發思路
播放器音樂由後臺運行的Service組件負責播放,當後臺的播放狀態發生改變時程序通過發送廣播通知前臺Activity更新界面;當用戶操作前臺界面時,系統將通過發送廣播通知後臺Service來改變播放狀態。
程序包括兩個BroadcasetReceiver(廣播接收器)和一個service服務
一個廣播接收器用於接收播放狀態發生改變的廣播
一個廣播接收器用於接收歌曲播放完成時發送的廣播
MainActivity:ActivityReceiver廣播接收器用於接收來自Service的廣播
MusicSerice(音樂播放服務):ServiceReceiver廣播接收器用於接收Activity的廣播
開發步驟
文件放置位置
- MP3文件位置
打開res文件夾:
res>New>Android resource directory:
彈出提示框New Resource Directory,在Resource type欄選擇raw,如下圖所示,然後點擊OK:
即可創建raw文件夾,用於存放MP3文件,我們可以將音樂文件直接複製存放在此文件夾下面。
- 圖片位置
可以直接存放在res文件夾下面的drawable文件夾:
也可以新建drawable-mdpi文件夾存放項目用到的圖片,這裏存放在drawable-mdpi裏面。
Activity界面佈局
在Activity中內嵌一個廣播接收器ActivityReceiver,用於接收來自Service的廣播。
// 定義一個廣播接收器
public class ActivityReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
int update = intent.getIntExtra("update",-1);
int current = intent.getIntExtra("current",-1);
if(current>=0) {
title.setText(titles[current]);
author.setText(authors[current]);
}
switch (update) {
case 0x11:
play.setImageResource(R.drawable.play);
break;
case 0x12:
play.setImageResource(R.drawable.pause);
break;
case 0x13:
play.setImageResource(R.drawable.play);
break;
default:
break;
}
}
}
定義一個內部類,用來監聽點擊事件,在點擊事件中發送廣播:
private class MyListener implements View.OnClickListener {
public void onClick(View v) {
Intent intent = new Intent("com.example.leseul.ServiceReceiver");
switch (v.getId()) {
case R.id.play: // 點擊播放按鈕
intent.putExtra("control",1);
break;
case R.id.stop: // 點擊暫停按鈕
intent.putExtra("control",2);
break;
default:
break;
}
sendBroadcast(intent); // 發送廣播
}
}
聲明的變量和onCreate方法:
private ImageButton stop,play; // 用於獲取暫停和開始按鈕元素
private TextView title,author; // 用於獲取音樂標題和作者文本元素
private ActivityReceiver activityReceiver;
private String[] titles = new String[]{"Color Blind","可樂"}; //保存音樂名稱
private String[] authors = new String[]{"Matt B","趙紫驊"}; //保存作者名稱
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stop = (ImageButton) findViewById(R.id.stop);
play = (ImageButton) findViewById(R.id.play);
title = (TextView) findViewById(R.id.title);
author = (TextView) findViewById(R.id.author);
MyListener myListener = new MyListener();
play.setOnClickListener(myListener);
stop.setOnClickListener(myListener);
//註冊廣播接收器
activityReceiver = new ActivityReceiver();
IntentFilter intentFilter = new IntentFilter("com.example.leseul.ActivityReceiver");
registerReceiver(activityReceiver, intentFilter); //進行關聯
//初始化
Intent intent = new Intent(MainActivity.this,MusicService.class); //顯示調用
startService(intent); //啓動服務
}
音樂播放服務
在服務中內嵌一個廣播接收器ServiceReceiver,用於接收來自Activity的廣播:
//廣播接收器
public class ServiceReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
// 接收到了廣播
int control = intent.getIntExtra("control",-1);
switch (control) {
case 1:
if(status == 0x11) { // 未播放,讓其播放
prepareAndPlay(current); // 播放
status = 0x12;
} else if(status == 0x12) {
mediaPlayer.pause(); // 停止
status = 0x13;
}else if(status == 0x13) {
mediaPlayer.start();
status = 0x12; // 變成播放狀態
}
break;
case 2:
if(status == 0x12 || status == 0x13) {
mediaPlayer.stop();
status = 0x11;
}
break;
default:
break;
}
Intent sendIntent = new Intent("com.example.leseul.ActivityReceiver");
// 狀態設置
sendIntent.putExtra("update",status);
sendIntent.putExtra("current",current); // 當前播放哪一首歌
sendBroadcast(sendIntent); // 發送廣播
}
}
編輯廣播接收器的業務邏輯處理,寫一個播放音樂的方法:
// 準備播放音樂
public void prepareAndPlay(final int index) {
try{
mediaPlayer = MediaPlayer.create(this,musics[current]);
// 事件監聽,音樂是否播放完成
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// 播放完成,則播放下一首
current++;
if(current == musics.length) { // 超過邊界了
current = 0;
}
Intent sendIntent = new Intent("com.example.leseul.ActivityReceiver");
sendIntent.putExtra("current",current);
sendBroadcast(sendIntent);
prepareAndPlay(current); // 播放下一首
}
});
if(mediaPlayer!=null) {
mediaPlayer.stop();
}
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}