傳送到github看源碼
下載apk試用 密碼:rukn
前言
- 想在天朝聽音樂還是有些難度的, 一般來說, 兩三個app還是要的. 那何不嘗試自己做個手機播放器, 聽個爽呢?!今天就帶大家先做個簡單的帶進度條可拖動的音樂播放器.
- 添加了后臺播放的功能, 很實用哦~
先看效果圖
很尷尬的一點就是大家沒法聽到音樂, 就只能看看圖片.
效果圖
布局文件
布局文件
添加Service
我們需要先把Service添加進來, 再考慮使用MediaPlayer播放, 我們分步來說.
- 首先要有一個自定義接口, 這個接口中的方法都是要在服務中實現的, 然后要到Activity中使用的.
public interface IService {//1. 定義接口IService, 添加調用函數, 調用MusicService中對應的函數public void callPlayMusic(String path);public void callPauseMusic();public void callConMusic();public void callSeekToPos(int pos);
}
- 然后來看Service中的實現, 自定義一個類, 繼承Binder, 然后實現我們再接口中定義的方法.
/*** 類MyBinder繼承Binder實現接口IService*/private class MyBinder extends Binder implements IService {//2. 定義類MyBinder繼承Binder實現接口IService中的函數@Overridepublic void callPlayMusic(String path) {playMusic(path);}@Overridepublic void callPauseMusic() {pauseMusic();}@Overridepublic void callConMusic() {conMusic();}@Overridepublic void callSeekToPos(int pos) {seekToPos(pos);}}
- 具體的實現就要涉及到MediaPlayer的使用了, 我們等下說, 先把Service綁定到Activity. 首先要返回一個自定義類的實例.
@Nullable@Overridepublic IBinder onBind(Intent intent) {//3. 返回自定義類MyBinder對象return new MyBinder();}
//4. 開啟服務Intent intent = new Intent(this, MusicService.class);startService(intent);//7. 綁定服務MyConn myConn = new MyConn();bindService(intent, myConn, BIND_AUTO_CREATE);
- 中間的MyConn又是一個自定義的類, 我們來看下實現. 之中要獲取下IService對象, 以此調用定義的函數.
private class MyConn implements ServiceConnection {//5. 定義類MyConn實現接口ServiceConnection@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//6. 獲取IBinder對象, 以此調用暴露的函數iService = (IService) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {}}
MediaPlayer的使用
然后服務就完成一個綁定了, 之后我們來說下MediaPlayer和SeekBar的使用. 無非就是播放, 暫停, 繼續這些的實現. 具體的說明請移步官方文檔
/*** 播放音樂** @param path 播放文件的路徑*/public void playMusic(String path) {Log.i(TAG, "playMusic");try {mediaPlayer.reset();mediaPlayer.setDataSource(path);mediaPlayer.setLooping(true);mediaPlayer.prepare();mediaPlayer.start();updateSeekBar();} catch (Exception e) {e.printStackTrace();}}/*** 暫停播放音樂*/public void pauseMusic() {Log.i(TAG, "pauseMusic");if (mediaPlayer.isPlaying()) {mediaPlayer.pause();}}/*** 繼續播放音樂*/public void conMusic() {Log.i(TAG, "conMusic");mediaPlayer.start();}
讀取文件系統肯定是要權限的, 可以查看我之前的文章一個Util帶你獲取Android6.0以上的讀寫sdcard權限
進度條的設置
SeekBar這里用起來其實不難, 難就難在要從Service傳數據到Activity. 這里我選用Handler, 當然你也可以用其它辦法. 同樣我們分步來說.
- 之前調用mediaPlayer.start();之后我調用了一個updateSeekBar();, 現在來看看實現. 關鍵是要獲取到音樂的總長度, 并且實時更新, 要實時更新的話, 我這里開了一個線程, 1s刷一次, 就不多說了.
/*** 更新SeekBar*/private void updateSeekBar() {//獲取總時長final int duration = mediaPlayer.getDuration();//開啟線程發送數據new Thread() {@Overridepublic void run() {while (keepTrue) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}int currentPosition = mediaPlayer.getCurrentPosition();//發送數據給activityMessage message = Message.obtain();Bundle bundle = new Bundle();bundle.putInt("duration", duration);bundle.putInt("currentPosition", currentPosition);message.setData(bundle);MainActivity.handler.sendMessage(message);}}}.start();}
- 然后回到Activity要接收發送的message. 接收到之后也完成的差不多了. 然后就是一個SeekBar的監聽設置.
public static Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {Bundle data = msg.getData();int duration = data.getInt("duration");int currentPosition = data.getInt("currentPosition");sb_progress.setMax(duration);sb_progress.setProgress(currentPosition);}};
- 就是在放開拖動SeekBar的時候重新設置位置, 要注意的是, 函數seekToPos也是在Service中實現的.
//8. 設置進度條拖動事件sb_progress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {iService.callSeekToPos(seekBar.getProgress());}});
/*** 設置SeekBar位置** @param pos 當前位置*/public void seekToPos(int pos) {mediaPlayer.seekTo(pos);}
這樣就完成啦! 喜歡就趕緊下載試試吧! 有意見或者建議也可以評論區哦.
傳送到github看源碼
下載apk試用 密碼:rukn
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的用MediaPlayer做个带进度条可后台的音乐播放器的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。