- 新創建一個Android工程《音樂播放器》,包名:com.itheima.musicPlayer。
在res目錄下新建一個文件夾raw(名字必須爲raw,約定大於配置的原則),然後在raw目錄中拷貝進一個音樂文件,注意文件名必須遵循Android資源文件的命名規則。
- 在src目錄下,新建一個MediaService繼承Service類,在該類中實現核心服務的方法。
private static MediaPlayer player;
public static int ispb;
@Override
public IBinder onBind(Intent intent) {
System.out.println("服務返回了MediaContoller對象。。。。");
return new MediaContoller();
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("創建一個服務,並初始化MediaPlayer");
player = MediaPlayer.create(getApplicationContext(), R.raw.a);
}
public static class MediaContoller extends Binder{
public int play(){
player.start();
return 0;
}
public int puse(){
player.pause();
return 1;
}
public void stop(){
player.stop();
}
public int getDuration(){
return player.getDuration();
}
public int getCurrentPosition(){
return player.getCurrentPosition();
}
public boolean isplaying(){
return player.isPlaying();
}
}
- 這是使用系統默認的佈局文件,activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="10dp"
android:text="音樂播放器"
android:textSize="20sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="play"
android:text="播放" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="puse"
android:text="暫停" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="stop"
android:text="停止" />
</LinearLayout>
<ProgressBar
android:id="@+id/pb"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp" />
</LinearLayout>
- 使用默認的MainActivity類,在該類中完成業務的控制
package com.example.servicemusic;
import com.example.service.MusicService;
import com.example.service.MusicService.MediaContoller;
import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
private ProgressBar pb;
private MediaContoller controller;
private boolean isrunning;
private static int ispb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pb = (ProgressBar) findViewById(R.id.pb);
Intent service = new Intent(this, MusicService.class);
isrunning = bindService(service, new MediaConnection(),
BIND_AUTO_CREATE);
if (isrunning) {
System.out.println("服務綁定成功!");
} else {
System.out.println("服務綁定失敗!");
}
}
/**
* 播放
*
* @param v
*/
@SuppressLint("ShowToast")
public void play(View v) {
if (controller != null) {
if (controller.isplaying()) {
Toast.makeText(this, "音樂正在播放中......", 1).show();
return;
}else{
controller.play();
System.out.println("開始播放音樂");
}
}
}
/**
* 暫停
*
* @param v
*/
public void puse(View v) {
if (controller != null) {
controller.puse();
System.out.println("音樂暫停");
}
}
/**
* 停止
*
* @param v
*/
public void stop(View v) {
if (controller != null) {
pb.setProgress(0);
controller.stop();
System.out.println("音樂停止");
}
}
/**
* 更新進度條
*/
private void updatePro() {
new Thread() {
public void run() {
while (true) {
SystemClock.sleep(400);
pb.setProgress(controller.getCurrentPosition());
if (controller.getCurrentPosition() == controller
.getDuration()) {
break;
}
}
};
}.start();
}
/**
* 實現ServiceConnection 類
*
* @author Blake
*
*/
class MediaConnection implements ServiceConnection {
/**
* 當service被綁定的時候回調該函數
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
controller = (MediaContoller) service;
pb.setMax(controller.getDuration());
updatePro();
System.out.println("服務器已經連接......");
}
/**
* 服務器斷開或關閉的時候調用該方法
*/
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("服務器斷開或關閉");
}
}
}
- 在AndroidManifest.xml中註冊Service
- 將工程部署到模擬器上,點擊播放,發現成功播放了音樂。點擊暫停,發現音樂暫停了,然後點擊播放,音樂再次響起。點擊停止,問題來了,我們發現點擊停止後再次點擊播放音樂沒能再次播放,因爲這裏面直接調用MediaPlayer的stop方法是有bug的。因此爲了解決這樣的問題,我們應該將停止調用層pause方法,同時只需調用MediaPlayer的seekTo(int)方法將音樂設置到開始位置。
//停止播放
public void stop(){
player.pause();
player.seekTo(0);
}