標籤:bool 比較 gre 迴圈 iap click 時間 current orm
Android開發—MediaPlayer簡單音樂播放器
功能介紹
功能實現
1. MediaPlayer的實現
- MediaPlayer常用方法介紹
-
MediaPlayer的實現包括初始化MediaPlayer,MediaPlayer的功能實現,包括播放、暫停、停止、離開等,具體細節如下:
MediaPlayer的初始化包括讀取一個MP3格式的音樂檔案並設定其為迴圈播放:
public void initMediaPlayer() { try { //String file_path = "/storage/0123-4567/K.Will-Melt.mp3"; String file_path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/K.Will-Melt.mp3"; //String file_path = "/data/K.Will-Melt.mp3"; mediaPlayer.setDataSource(file_path); mediaPlayer.prepare(); mediaPlayer.setLooping(true); // 設定迴圈播放 } catch (Exception e) { e.printStackTrace(); } }
播放/暫停功能的實現放在Play/Pause按鈕中,所以需要二選一判斷MediaPlayer的狀態來設定音樂的播放與暫停:
public void playOrPause() { flag++; if (flag >= 1000) flag = 2; which = "pause"; if(mediaPlayer.isPlaying()){ mediaPlayer.pause(); animator.pause(); } else { mediaPlayer.start();
類似的,停止功能的實現放在Stop按鈕中,用於停止音樂並將其置於初始態即“00:00”:
public void stop() { which = "stop"; animator.pause(); if(mediaPlayer != null) { mediaPlayer.pause(); mediaPlayer.stop(); try { mediaPlayer.prepare(); mediaPlayer.seekTo(0); } catch (Exception e) { e.printStackTrace(); } } }
說明:由於調用stop()後,有時音樂並沒有馬上停止,所以我額外加了一個pause()來確保音樂停止播放。
同樣,離開功能實現放在了Quit按鈕中,主要實現整個應用的退出,具體應包括解除綁定Service,結束Activity等等:
private void quit() { musicService.animator.end(); handler.removeCallbacks(runnable); unbindService(sc); try { finish(); System.exit(0); } catch (Exception e) { e.printStackTrace(); } }
2. Service的應用
- Service即“服務” ,它與Activity屬於同一等級的應用程式組件,都代表可執行檔程式。不同的是Activity擁有前台啟動並執行使用者介面,而Service不能自己運行,需要通過某個Activity或者其他Context對象來調用。Service在後台運行,它不能與使用者直接進行互動。在預設情況下,Service運行在應用程式進程的主線程之中。可以通過Context.startService()和Context.bindService()兩種方式來啟動Service。
- 通過Service可以使程式在退出之後仍然能夠對事件或使用者操作做出反應,或者在後台繼續運行某些程式功能。
- Android賦予Services比處於不活動(inactivity)的Activities更高的優先順序,所以它們的進程不會輕易被系統殺掉。
- Activity與Service的互動為:
有了以上知識的積累,基本可以實現Service的必要部分,如下:
1.建立一個繼承於Service的MusicService類
public class MusicService extends Service { public final IBinder binder = new MyBinder(); public class MyBinder extends Binder { MusicService getService() { return MusicService.this; } }
/** * onBind 是 Service 的虛方法,因此我們不得不實現它。 * 返回 null,表示客服端不能建立到此服務的串連。 */ @Override public IBinder onBind(Intent intent) { return binder; }
2.並在Activity中綁定MusicService:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getOverflowMenu(); setContentView(R.layout.activity_main); bindServiceConnection(); musicService = new MusicService();
private ServiceConnection sc = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { musicService = ((MusicService.MyBinder) iBinder).getService(); } @Override public void onServiceDisconnected(ComponentName componentName) { musicService = null; } }; private void bindServiceConnection() { Intent intent = new Intent(this, MusicService.class); startService(intent); bindService(intent, sc, this.BIND_AUTO_CREATE); }
3. Handler更新UI介面
通過Handler來管理UI,最要需要用到post和postDelayed兩個函數:
1. post(Runnable r)
將r加入到訊息佇列中(其實就是利用UI主線程執行一段代碼,這樣可以隨時在其他線程中調整控制項)
2. postDelayed(Runnabled r,long delayMillis)
將r加入到訊息佇列中,並在指定時間之後觸發(單位為毫秒)
所以,為了實現音樂的播放顯示等功能,需要重寫Runnable的run函數,具體實現如下:
public Handler handler = new Handler(); public Runnable runnable = new Runnable() { @Override public void run() { isPlay.setOnClickListener(new myOnClickListener()); stop.setOnClickListener(new myOnClickListener()); quit.setOnClickListener(new myOnClickListener()); if(musicService.mediaPlayer.isPlaying()) { stateText.setText("Playing"); } else { if (musicService.which.equals("stop")) { stateText.setText("Stop"); } else if (musicService.which.equals("pause")){ stateText.setText("Pause"); } } playingTime.setText(time.format(musicService.mediaPlayer.getCurrentPosition())); totalTime.setText(time.format(musicService.mediaPlayer.getDuration())); seekBar.setProgress(musicService.mediaPlayer.getCurrentPosition()); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { musicService.mediaPlayer.seekTo(seekBar.getProgress()); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); handler.postDelayed(runnable, 100); } };
4. 實現圖片的旋轉
圖片的動畫效果實現需要用到ObjectAnimator類,ObjectAnimator類可用於圖片的平移、旋轉、縮放等動畫,此處我們只需要用到其旋轉功能,具體實現如下:
public void AnimatorAction() { if (mediaPlayer.isPlaying()) { animator.setDuration(5000); animator.setInterpolator(new LinearInterpolator()); // 均速旋轉 animator.setRepeatCount(ValueAnimator.INFINITE); // 無限迴圈 animator.setRepeatMode(ValueAnimator.INFINITE); animator.start(); } }
說明:animator是ObjectAnimator的一個執行個體對象,setDuration為5000表示旋轉一周需要的時間為5000,所以可用來設定旋轉的速度;同時設定為無線迴圈模式,並且添加一個插值器達到勻速旋轉的目的,最後調用pause()等函數動態控制動畫狀態,如下:
5. 進度條SeekBar功能實現
SeekBar的功能包括顯示歌曲播放進度以及拖動SeekBar至任意位置來改變播放進度,由於android已經封裝好了這些函數,所以直接調用就好了,也比較好理解,具體實現如下:
seekBar = (SeekBar) findViewById(R.id.seekBar); seekBar.setProgress(musicService.mediaPlayer.getCurrentPosition()); seekBar.setMax(musicService.mediaPlayer.getDuration());
seekBar.setProgress(musicService.mediaPlayer.getCurrentPosition()); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { musicService.mediaPlayer.seekTo(seekBar.getProgress()); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } });
6. 動態許可權申請
參見Android動態許可權申請
7. 判斷程式是否處於後台
由於音樂需要支援後台播放,再次由後台進入前台會對前台的事件功能等產生影響,所以可以添加一個後台判斷函數,並添加一個標誌來記錄應用是否進入後台。
private boolean isApplicationBroughtToBackground() { ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1); if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; if (!topActivity.getPackageName().equals(getPackageName())) { return true; } } return false; }
至此,基於MediaPlayer的簡單音樂播放器基本可以實現,如需要完整項目代碼,可留下郵箱。
Android開發---MediaPlayer簡單音樂播放器