Android Service- 播放音樂 建國科技大學資管系 饒瑞佶 2013/7 V1
Android Service Service 是跟 Activity 並行 一個音樂播放程式若沒使用 Service, 即使按 home 鍵畫面離開之後, 音樂還是照播 如果再執行一次程式, 新撥放的音樂會跟先前撥放的一起撥, 最後程式就會出錯 執行中的程式完全看不到! 但是, 寫成 Service 就不同了 Activity 只負責顯示, 撥放的任務則是交給 service, Service 是沒有 UI 的, 在 trace 的時候可以用 System.out.println 來測試是否有成功呼叫 Service 就像是一個代理人, 將可以背景執行的程序 ( 像是 MediaPlayer()) 交給他就對了
先試試不用 Service 撥放音樂 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/ res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/play" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text=" 開始播放 "/> <Button android:id="@+id/stop" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text=" 停止播放 "/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>
先試試不用 Service 撥放音樂 res 中加入 raw/test.mp3
先試試不用 Service 撥放音樂
@Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); // 對應 layout 物件 buttonstart = (Button) findviewbyid(r.id.play); buttoncontinueplay = (Button) findviewbyid(r.id.continueplay); buttonpause = (Button) findviewbyid(r.id.pause); buttonstop = (Button) findviewbyid(r.id.stop); textstate = (TextView)findViewById(R.id.tv1); // 設定 onclick 事件 buttonstart.setonclicklistener(this); buttonstop.setonclicklistener(this); buttonpause.setonclicklistener(this); buttoncontinueplay.setonclicklistener(this); // 設定物件是否可用 buttonstart.setenabled(true); buttoncontinueplay.setenabled(false); buttonpause.setenabled(false); buttonstop.setenabled(false); // 建立 mediplayer 物件 mediaplayer = new MediaPlayer();
Play
Play public void onclick(view src) { switch (src.getid()) { case R.id.Play: mediaplayer = MediaPlayer.create(MediaController2.this, R.raw.test); try { mediaplayer.start(); textstate.settext("- Playing -"); buttonstart.setenabled(false); buttoncontinueplay.setenabled(false); buttonpause.setenabled(true); buttonstop.setenabled(true); catch (IllegalStateException e) { // TODO Auto-generated catch block e.printstacktrace();
Play // 播放完成 mediaplayer.setoncompletionlistener(new MediaPlayer.OnCompletionListener() { public void oncompletion(mediaplayer arg0) { try { // 釋放 mediaplayer mediaplayer.release(); textstate.settext("play end!"); // 設定物件是否可用 buttonstart.setenabled(true); buttoncontinueplay.setenabled(false); buttonpause.setenabled(false); buttonstop.setenabled(false); catch (Exception e) { textstate.settext(e.tostring()); e.printstacktrace(); );
Play // 播放錯誤 mediaplayer.setonerrorlistener(new MediaPlayer.OnErrorListener() { public boolean onerror(mediaplayer arg0, int arg1, int arg2) { try { // 釋放 mediaplayer mediaplayer.release(); textstate.settext("play ERROR!"); catch (Exception e) { textstate.settext(e.tostring()); e.printstacktrace(); return false; ); break;
ContinuePlay case R.id.ContinuePlay: try { mediaplayer.start(); textstate.settext("- Playing -"); buttonstart.setenabled(false); buttoncontinueplay.setenabled(false); buttonpause.setenabled(true); buttonstop.setenabled(true); catch (IllegalStateException e) { // TODO Auto-generated catch block e.printstacktrace(); break;
Pause case R.id.Pause: try { mediaplayer.pause(); textstate.settext("- Pause -"); buttonstart.setenabled(true); buttoncontinueplay.setenabled(true); buttonpause.setenabled(false); buttonstop.setenabled(true); catch (IllegalStateException e) { // TODO Auto-generated catch block e.printstacktrace(); break;
Stop case R.id.Stop: try { mediaplayer.stop(); textstate.settext("- Stop -"); buttonstart.setenabled(true); buttoncontinueplay.setenabled(false); buttonpause.setenabled(false); buttonstop.setenabled(false); catch (IllegalStateException e) { // TODO Auto-generated catch block e.printstacktrace(); break; Switch 的結束 onclick 的結束
問題 產生重複撥放 無法從執行中程序停止
Service 流程
改用 Service 撥放音樂
改用 Service 撥放音樂
改用 Service 撥放音樂
改用 Service 撥放音樂
改用 Service 撥放音樂 public class MusicService extends Service { MediaPlayer player; @Override public IBinder onbind(intent arg0) { // TODO Auto-generated method stub return null; @Override public void oncreate() { //Service 首先啟動 super.oncreate(); player = new MediaPlayer();
改用 Service 撥放音樂 @Override public void onstart(intent intent, int startid) { // 完成 oncreate() 後啟動 if (intent!= null) { Bundle bundle = intent.getextras(); if (bundle!= null) { int op = bundle.getint("op"); switch (op) { case 1: //play player=mediaplayer.create(this, R.raw.test) ; player.start(); break; case 2: //replay player.start(); break; case 3: //pause player.pause(); break; case 4: //stop if (player!= null) { player.stop(); break;
改用 Service 撥放音樂 @Override public void ondestroy() { super.ondestroy(); if(player!=null){ player.stop(); player.release();
修正 AndroidManifest.xml 加入到 <application> 中 <service android:enabled="true" android:name=".musicservice"> <action android:name="ccc.android.musicservice" /> </service>
問題是否還在? 產生重複撥放? 無法從執行中程序停止?
背景音樂
MyBackVoice.java
public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.main); mmediaplayer = MediaPlayer.create(this,R.raw.test); mmediaplayer.start(); @Override protected void onpause() { super.onpause(); mmediaplayer.pause(); // 記得現在的位置 length = mmediaplayer.getcurrentposition();
@Override protected void onresume() { // TODO Auto-generated method stub super.onresume(); mmediaplayer.seekto(length); mmediaplayer.start(); @Override protected void ondestroy() { // TODO Auto-generated method stub super.ondestroy(); mmediaplayer.stop();
@Override public void onbackpressed() { return; // 讓按鍵失效, 使 resume 後可以繼續撥放 @Override protected void onresume() { // TODO Auto-generated method stub super.onresume(); mmediaplayer.seekto(length); mmediaplayer.start(); @Override protected void ondestroy() { // TODO Auto-generated method stub super.ondestroy(); mmediaplayer.stop();
小補充 public void oncreate(bundle savedinstancestate){ super.oncreate(savedinstancestate); setcontentview(r.layout.main); // 透過 sdcard mmediaplayer = new MediaPlayer(); try { mmediaplayer.setdatasource("/sdcard/test.mp3"); mmediaplayer.prepare(); catch (IllegalArgumentException e) { // TODO 自動產生的 catch 區塊 e.printstacktrace(); catch (IllegalStateException e) { // TODO 自動產生的 catch 區塊 e.printstacktrace(); catch (IOException e) { // TODO 自動產生的 catch 區塊 e.printstacktrace(); // 透過資源檔 //mmediaplayer = MediaPlayer.create(this,R.raw.tt); mmediaplayer.start();