<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 1.背景 ? ?音樂的播放,為了實現在后臺播放,將在Service 中進行音樂的基本控制,所以 MediaPlay 將在Service 中實現。 在這里使用了,簡單的 startService 方式,非 Ibind 方式操作服務,故在關閉Service 上還有些bug , 但并不影響使用; ? ?*Service 學習參考資料 :?[http://www.android-doc.com/guide/components/services.html](http://www.android-doc.com/guide/components/services.html)* ? ?*Service 生命周期 :?[http://blog.csdn.net/LABLENET/article/details/48073093](http://blog.csdn.net/LABLENET/article/details/48073093)* ? ?在這個播放器中,為了播放音樂方便,故在應用啟動后,當數據加載成功就啟動了MusicService 服務。后臺服務本身是不可見的,但是在這個為了使其可見就使用了通知(MusicNotification )來人性話,顯示服務當前的狀態和當前播放音樂的信息,通知下篇實現,這里的主角是Service.? ? MusicService 服務 : ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?![](https://box.kancloud.cn/2016-04-19_5715764bc7a84.jpg) ## 2.Service 實現 ? ? (1)實現MusicService? ? ? ? ? ? ? ? 如果直接看源碼的時候,十分頭疼這些是什么東西,我在這個簡單的說明的一下 : ? ? ? ? ? ? ? MusicService 實現的功能是對音樂的基本控制: ? ? ? ? ? ? ? ? ? ? 1.應用啟動 ?(隨著應用的啟動而啟動)?就啟動? ? ? ? ? ? ? ? ? ? ? 2.狀態欄顯示 :?notification? ? ? ? ? ? ? ? ? ? ? 3.注冊 : bordcastReceiver? ? ? ? ? ? ? ? ? ? ? 4.請求第1首歌 : 更新狀態欄? ? ? ? ? ? ? ? ? ? ? 5.實現上一曲,下一曲,播放,暫停控制 ? ? ? ? ? ? ? ? ? ? 6.初始化 MusicActivity 內容數據 ?(這個是歌詞/進度條顯示頁面) ? ? ? ? ? ? ? ?*MusicService 源碼 : 使用了斜杠進行了分類,應該是可以理解的,boradcastReceiver 的內容將在后面說明。* ~~~ package cn.labelnet.framework; import java.io.IOException; import java.io.Serializable; import java.util.List; import cn.labelnet.model.MusicModel; import android.app.NotificationManager; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnPreparedListener; import android.net.Uri; import android.os.IBinder; import android.widget.MediaController.MediaPlayerControl; import android.widget.Toast; public class MusicService extends Service implements OnPreparedListener, OnCompletionListener, OnErrorListener { /** * MusicService 音樂播放控制 : 隨著應用的啟動而啟動 基本步揍 : 1.應用啟動 : 就啟動 2.狀態欄顯示 : * notification 3.注冊 : bordcastReceiver 4.請求第1首歌 : 更新狀態欄 5.實現上一曲,下一曲,播放,暫停控制 */ // 常量 private final String MUSIC_INTENT_KEY = "musics"; private final int MUSIC_INTENT_FLAG = 20001; private final int MAIN_MUSIC_INTENT_FLAG = 20017; // 音樂列表 private List<MusicModel> musics = null; private int mmSize = 0; // 通知欄 private MusicNotification musicNotifi = null; private MusicModel mm = null; // MediaPlay private MediaPlayer mp = null; private int currentTime = 0; // Music廣播接收 private MusicBroadCast musicBroadCast = null; // MainActivity 來的 Action private final String MAIN_ACTIVIY_ACTION = "mainActivity.To.MusicService"; // 來自通知欄的Action private final String MUSIC_NOTIFICATION_ACTION_PLAY = "musicnotificaion.To.PLAY"; private final String MUSIC_NOTIFICATION_ACTION_NEXT = "musicnotificaion.To.NEXT"; private final String MUSIC_NOTIFICATION_ACTION_CLOSE = "musicnotificaion.To.CLOSE"; private final String MUSIC_NOTIFICAION_INTENT_KEY = "notify.music"; // MusicService 來的 Action private final String MUSIC_ACTIVITY_SERVICE_ACTION = "activity.to.musicservice"; private final String MUSIC_ACTIVITY_SERVICE_KEY = "musictype"; private final int MUSIC_ACTIVITY_SERVICE_REQUEST = 40001; // 給MusicActivity 的 Action private final String MUSIC_SERVICE_RECEIVER_ACTION = "service.to.musicactivity"; private Intent mActivityIntent = null; private final String MUSIC_SERVICE_TO_ACTIVITY_MODEL = "model"; private final String MUSIC_SERVICE_TO_ACTIVITY_ISPLAY = "isplay"; private final String MUSIC_SERVICE_TO_ACTIVITY_NOWTIME = "nowtime"; // 響應碼 : 41001 沒數據 , 41002 : 有數據 private final String MUSIC_SERVICE_TOACTIVITY_CODE = "mpcode"; // Intent keys private final String MAIN_MUSIC_INTENT_KEY = "mIntent"; @Override public void onCreate() { // 初始化MusicActivity 的 Intent ,給 MusicActivity 發送廣播 ,修改音樂播放界面 mActivityIntent = new Intent(); mActivityIntent.setAction(MUSIC_SERVICE_RECEIVER_ACTION); // 初始化通知欄 musicNotifi = MusicNotification.getMusicNotification(); musicNotifi.setContext(getApplicationContext()); musicNotifi .setManager((NotificationManager) getSystemService(NOTIFICATION_SERVICE)); musicNotifi.onCreateMusicNotifi(); // 初始化MediaPlay : 設置監聽事件 mp = new MediaPlayer(); mp.setOnPreparedListener(this); mp.setOnCompletionListener(this); mp.setOnErrorListener(this); // 注冊廣播 musicBroadCast = new MusicBroadCast(); IntentFilter filter = new IntentFilter(); filter.addAction(MAIN_ACTIVIY_ACTION); filter.addAction(MUSIC_ACTIVITY_SERVICE_ACTION); filter.addAction(MUSIC_NOTIFICATION_ACTION_PLAY); filter.addAction(MUSIC_NOTIFICATION_ACTION_NEXT); filter.addAction(MUSIC_NOTIFICATION_ACTION_CLOSE); registerReceiver(musicBroadCast, filter); super.onCreate(); } @Override public IBinder onBind(Intent intent) { return null; } @SuppressWarnings("unchecked") @Override public int onStartCommand(Intent intent, int flags, int startId) { try{ musics = (List<MusicModel>) intent .getSerializableExtra(MUSIC_INTENT_KEY); }catch(Exception e){ } if (musics != null) { mmSize = musics.size(); } // showToast("1." + musics.get(1).getSongname()); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { if (mp != null) { mp.stop(); mp.release(); mp = null; musics = null; } // 取消注冊的廣播 unregisterReceiver(musicBroadCast); } // //////////////////////////////Music Util////////////////////// // Toast private void showToast(String msg) { Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); } // 音樂播放 private void play(String musicUrl) { mp.reset(); try { mp.setDataSource(getApplicationContext(), Uri.parse(musicUrl)); mp.prepareAsync(); } catch (IOException e) { showToast("網絡錯誤,播放失敗"); } musicNotifi.onUpdataMusicNotifi(mm, true); } // 音樂暫停 private void pause() { if (mp.isPlaying()) { currentTime = mp.getCurrentPosition(); mp.pause(); } musicNotifi.onUpdataMusicNotifi(mm, false); } // 音樂繼續播放 private void resume() { mp.start(); if (currentTime > 0) { mp.seekTo(currentTime); } musicNotifi.onUpdataMusicNotifi(mm, true); } // 音樂停止 private void stop() { mp.stop(); try { mp.prepare(); } catch (IOException e) { showToast("音樂停止異常"); } musicNotifi.onUpdataMusicNotifi(mm, false); } // //////////////////////////////Music MediaPlayListener//////////// @Override public boolean onError(MediaPlayer mp, int what, int extra) { // 出錯的時候 return false; } @Override public void onCompletion(MediaPlayer mp) { // 播放完畢的時候 // showToast("播放完畢,準備播放下一首!"); currentTime = 0; // 改變通知欄 musicNotifi.onUpdataMusicNotifi(mm, false); //改變MusicActivity sendModelToMusicActivity(); } @Override public void onPrepared(MediaPlayer mp) { // 準備加載的時候 resume(); sendModelToMusicActivity(); } // ////////////////////////////其他工具方法////////////////////////////////// /** * 發送Model給MusicActivity */ private void sendModelToMusicActivity() { if (mm != null) { // 正在播放的歌曲實體 if(mm.getSeconds()==0){ mm.setSeconds(mp.getDuration()/1000); } mActivityIntent.putExtra(MUSIC_SERVICE_TOACTIVITY_CODE, 41002); mActivityIntent.putExtra(MUSIC_SERVICE_TO_ACTIVITY_ISPLAY, mp.isPlaying()); mActivityIntent.putExtra(MUSIC_SERVICE_TO_ACTIVITY_NOWTIME, mp.getDuration() - mp.getCurrentPosition()); mActivityIntent.putExtra(MUSIC_SERVICE_TO_ACTIVITY_MODEL, (Serializable) mm); } else { // 默認發送第一首歌信息 mm = musics.get(0); mActivityIntent.putExtra(MUSIC_SERVICE_TOACTIVITY_CODE, 41001); mActivityIntent.putExtra(MUSIC_SERVICE_TO_ACTIVITY_ISPLAY, mp.isPlaying()); mActivityIntent.putExtra(MUSIC_SERVICE_TO_ACTIVITY_MODEL, (Serializable) mm); } sendBroadcast(mActivityIntent); } // //////////////////////////////Music BroadCastReceiver//////////// // 接收廣播 private class MusicBroadCast extends BroadcastReceiver { private int flag = 0, position = -1, kzhi = 0, musictype = 0; @Override public void onReceive(Context context, Intent intent) { // 2.MainActivity 控制 flag = intent.getFlags(); mainToService(intent); // 3.MusicNotification控制 kzhi = intent.getIntExtra("type", -1); if (kzhi > 0) { musicNotificationService(kzhi); } // 4.MusicActivity 來的控制 musictype = intent.getIntExtra(MUSIC_ACTIVITY_SERVICE_KEY, 0); if (musictype > 0) { musicActivityService(musictype); } } /** * 來自 MusicActivity 的控制 * * @param musictype2 */ private void musicActivityService(int musictype2) { // showToast("musicActivityService 執行了 musictype2 :" + musictype2); switch (musictype2) { case 40001: sendModelToMusicActivity(); break; case 40002: //播放與暫停 playSong(); break; case 40003: //下一曲 nextSong(); break; case 40004: //上一曲 preSong(); break; } } /** * musicNotification 來的控制 * * @param intent */ private void musicNotificationService(int k) { switch (k) { case 30001: // 播放 playSong(); break; case 30002: // 下一首 nextSong(); break; case 30003: // 關閉通知欄 musicNotifi.onCancelMusicNotifi(); // 停止音樂 stop(); break; } } /** * 播放 */ private void playSong() { if (mp.isPlaying()) { pause(); } else { if (currentTime > 0) { resume(); } else { if (mm != null) { play(mm.getUrl()); } } } sendModelToMusicActivity(); } /** * 下一曲 */ private void nextSong() { currentTime=0; if(position<0){ position=0; } if (mmSize > 0) { position++; if (position < mmSize) { // 不超過長度 mm = musics.get(position); play(mm.getUrl()); } else { // 超過長度 播放第一首 mm = musics.get(0); play(mm.getUrl()); } } } /** * 上一曲 */ private void preSong(){ currentTime=0; if(position<0){ position=0; } if (mmSize > 0) { position--; if (position>=0) { //不小于0 mm = musics.get(position); play(mm.getUrl()); } else { // 超過長度 播放第一首,小于0 ,播放第一首 mm = musics.get(0); play(mm.getUrl()); } } } /** * MainActivity來的數據 * * @param intent */ private void mainToService(Intent intent) { if (MAIN_MUSIC_INTENT_FLAG == flag) { // 來自MainActivity 的操作 position = intent.getIntExtra(MAIN_MUSIC_INTENT_KEY, -1); // showToast("3.來自MainActivity 問候 : " + position); if (position > -1) { // 播放 if (musics != null) { mm = musics.get(position); } else { // showToast("4.MUSICS IS NULL"); } if (mm != null) { /** * 1.播放音樂 2.更新狀態欄 3.如果進度條運行的話,通知改變 */ play(mm.getUrl()); } else { // showToast("5.musics 數據去哪里了!"); } } else { // showToast("6.這怎么可能發生呢?!"); } } else { // showToast("不是MainActivity 來的數據"); } } } } ~~~ ? ? ? ?(2)注冊Service? ? ? ? ? ? ? ? ? ? 在AndroidMainfest.xml中注冊? ~~~ <service android:name="cn.labelnet.framework.MusicService" > </service> ~~~ ## (3)啟動服務 這里使用了 Serializable序列化進行了數據傳遞,不建議使用這個,效率低,可以使用Parcleable,效率高; 參考文章 : [Android - Parcelable接口用法 和 與 Serializable 的區別](http://blog.csdn.net/lablenet/article/details/50315349) ~~~ @Override public void getMusicModelList(List<MusicModel> models) { // 初始化 Service : 開啟MUSIC服務 Intent intent = new Intent(MainActivity.this, MusicService.class); intent.putExtra(MUSIC_INTENT_KEY, (Serializable) models); intent.addFlags(MUSIC_INTENT_FLAG); startService(intent); //關閉進度條 swiperefresh_wei.setRefreshing(false); isRefresh=false; } ~~~ ### 3.播放器控制 播放器控制主要實現是實現 play() , pause() , resume(),stop() 四個方法,進行播放,暫停,重新播放控制。同時實現onPrepaed() , onCompletion() , onError() 三個監聽,實現對播放器的控制,最基本的操作就在此了。后面的通知欄控制,歌詞/進度條頁面控制 均是使用 這幾個方法進行控制實現。 ~~~ <span style="font-family:Comic Sans MS;font-size:18px;">// 音樂播放 private void play(String musicUrl) { mp.reset(); try { mp.setDataSource(getApplicationContext(), Uri.parse(musicUrl)); mp.prepareAsync(); } catch (IOException e) { showToast("網絡錯誤,播放失敗"); } musicNotifi.onUpdataMusicNotifi(mm, true); } // 音樂暫停 private void pause() { if (mp.isPlaying()) { currentTime = mp.getCurrentPosition(); mp.pause(); } musicNotifi.onUpdataMusicNotifi(mm, false); } // 音樂繼續播放 private void resume() { mp.start(); if (currentTime > 0) { mp.seekTo(currentTime); } musicNotifi.onUpdataMusicNotifi(mm, true); } // 音樂停止 private void stop() { mp.stop(); try { mp.prepare(); } catch (IOException e) { showToast("音樂停止異常"); } musicNotifi.onUpdataMusicNotifi(mm, false); } // //////////////////////////////Music MediaPlayListener//////////// @Override public boolean onError(MediaPlayer mp, int what, int extra) { // 出錯的時候 return false; } @Override public void onCompletion(MediaPlayer mp) { // 播放完畢的時候 // showToast("播放完畢,準備播放下一首!"); currentTime = 0; // 改變通知欄 musicNotifi.onUpdataMusicNotifi(mm, false); //改變MusicActivity sendModelToMusicActivity(); } @Override public void onPrepared(MediaPlayer mp) { // 準備加載的時候 resume(); sendModelToMusicActivity(); }</span> ~~~ ### 4.總結 MusicService 的實現是整個播放器的核心,所以進步的音樂控制均在此實現,算是播放器的心臟。 下篇將實現通知欄實現- MusicSerivce 的臉;
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看