Android 後臺播放音樂Demo
阿新 • • 發佈:2018-12-20
開發流程:
A,建立服務把想使用的方法暴露出來。
B,定義介面,bind呼叫時返回物件,在service 開啟播放音樂實時更新進度條的位置
C,Activity 中建立hander 更新UI
【1】佈局
<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" tools:context=".MainActivity" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click1" android:text="播放" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click2" android:text="暫停" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click3" android:text="繼續播放" /> <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
【2】建立介面
interface Iservice {
//把想暴露的方法定義在接口裡
public void callplayMusic();
public void callpauseMusic();
public void callrePlayMusic();
public void callplaySeekToPosition(int position);
}
【3】建立Service
A,onCredte 方法中是用MediaPlayer
B,為了呼叫Service 裡面方法 Bind開啟服務,提供Binder 物件 呼叫裡面方法
C,定義方法,使用Binder的子類暴露出去。
public class MusicService extends Service { private Timer timer; private TimerTask task; private MediaPlayer mediaPlayer; //[2]把我們定義的中間人物件返回 @Override public IBinder onBind(Intent intent) { return new MyBinder(); } @Override public void onCreate() { //[1]播放sd卡里面的小蘋果音樂 mediaPlayer = new MediaPlayer(); super.onCreate(); } // 播放音樂的方法 public void playMusic() { try { //[2]設定播放音樂的路徑 設定資料 原:在sd卡 mediaPlayer.setDataSource("/mnt/sdcard/xpg.mp3"); //[3]準備播放 mediaPlayer.prepare(); //[4]播放音樂 mediaPlayer.start(); //[5]歌曲播放的同時 更新進度條 updateSeekBar(); } catch (Exception e) { e.printStackTrace(); } } //更新進度條的方法 private void updateSeekBar() { //[1]獲取當前歌曲的總時長 final int duration = mediaPlayer.getDuration(); //[2]要不停的獲取當前歌曲播放的進度 計時器 Timer timer = new Timer(); task = new TimerTask() { @Override public void run() { int currentPosition = mediaPlayer.getCurrentPosition(); //[3]更新進度條 Message msg = Message.obtain(); //[4]準備bundle Bundle bundle = new Bundle(); //實際就是map bundle.putInt("duration", duration); bundle.putInt("currentPosition", currentPosition); //[5]使用msg攜帶多條資料 msg.setData(bundle); //[6]發訊息 maniActivity的handlemessage方法就會執行 MainActivity.handler.sendMessage(msg); //[7]給mediaplayer設定播放完成的監聽 mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { System.out.println("歌曲播放完成了"); timer.cancel(); task.cancel(); } }); } }; //3秒後 執行task timer.schedule(task, 1000,1000); } // 暫停音樂的方法 public void pauseMusic() { mediaPlayer.pause(); } // 繼續播放音樂的方法 public void rePlayMusic() { //繼續播放也是start方法 mediaPlayer.start(); } //設定歌曲播放位置的方法 public void playSeekToPosition(int position){ mediaPlayer.seekTo(position); } //[1]定義中間人的物件 (IBinder型別) private class MyBinder extends Binder implements Iservice{ @Override public void callplayMusic() { //呼叫播放音樂的方法 playMusic(); } @Override public void callpauseMusic() { //呼叫暫停音樂的方法 pauseMusic(); } @Override public void callrePlayMusic() { //呼叫繼續播放音樂的方法 rePlayMusic(); } @Override public void callplaySeekToPosition(int position) { playSeekToPosition(position); } } } 【3】MainActiivty 中呼叫: A,獲取控制元件,startService 開啟服務確保能夠在後臺長期執行 B,BindService獲取返回的介面物件,呼叫其中暴露給我們的方法,播放, 暫停。 C,seekBar.設定位置關聯進度。 public class MainActivity extends Activity { private Iservice iservice;//我們定義的中間人物件 private MyConn conn; private static SeekBar seekBar; public static Handler handler = new Handler(){ //這個方法處理訊息的時候執行 public void handleMessage(android.os.Message msg) { //[1]獲取發訊息攜帶的資料 資料是怎麼發的 就怎麼取 資料發的是什麼型別就取什麼型別 Bundle data = msg.getData(); //[2]獲取歌曲的總時長和 當前進度 int duration = data.getInt("duration"); int currentPosition = data.getInt("currentPosition"); //[3]更新進度條 seekBar.setMax(duration); seekBar.setProgress(currentPosition); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //[1]呼叫startservice 保證服務在後臺長期執行 Intent intent = new Intent(this,MusicService.class); startService(intent); //[2]想點選按鈕的時候 呼叫服務裡面的方法 獲取我們在服務內部定義的中間人物件 conn = new MyConn(); bindService(intent, conn, BIND_AUTO_CREATE); //[3]找到進度條 seekBar = (SeekBar) findViewById(R.id.seekBar1); //[4]給seekbar設定監聽 seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { //當拖動進度條停止 執行 @Override public void onStopTrackingTouch(SeekBar seekBar) { //在這個方法裡面實現拖動到哪就播放歌曲對應的位置 iservice.callplaySeekToPosition(seekBar.getProgress()); } //幹開始託 @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } }); } //監視服務的狀態 private class MyConn implements ServiceConnection { //當連線服務成功後呼叫 @Override public void onServiceConnected(ComponentName name, IBinder service) { //獲取我們定義的中間人物件 iservice = (Iservice) service; } @Override public void onServiceDisconnected(ComponentName name) { } } @Override protected void onDestroy() { //當Activity銷燬的時候 解綁服務 unbindService(conn); super.onDestroy(); } // 點選按鈕實現音樂的播放 public void click1(View v) { iservice.callplayMusic(); } // 點選按鈕實現音樂的暫停 public void click2(View v) { iservice.callpauseMusic(); } // 點選按鈕實現音樂的繼續播放 public void click3(View v) { iservice.callrePlayMusic(); } }