1. 程式人生 > >實現音樂播放器後臺Service服務一直存在的解決思路

實現音樂播放器後臺Service服務一直存在的解決思路

最近實現一個音樂播放器的小專案,實現後臺播放歌曲的功能,即使退出程式也可以一直播放歌曲,服務不被停止。
實現這個功能的過程中遇到了有兩個問題:
問題1、退出程式之後,service播放歌曲的服務在後臺執行,但是當螢幕鎖屏之後,播放一段時間後,服務被停止,歌曲停止播放。控制檯列印輸出下面的字串“QCMediaPlayer mediaplayer NOT present”
問題2、鎖屏後,喚醒螢幕,此時歌曲會停止播放,而不是一直播放。

這兩個問題都有解決方案。

  • 第一個問題解決方法:

在啟動播放service的時候,獲取電源裝置鎖,等到停止服務的時候釋放電源裝置鎖。
這個方法需要許可權:
< uses-permission android:name=”android.permission.WAKE_LOCK”/>

例項程式碼如下:

@Override
    public void onCreate() {
        super.onCreate();
        acquireWakeLock();//獲取裝置電源鎖
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        MusicUtils.initMusicList();
        mPlayingPosition = (Integer) SpUtils.get(this, Constants.PLAY
_POS, 0); Uri uri = Uri.parse(MusicUtils.sMusicList.get( getPlayingPosition()).getUri()); mPlayer = MediaPlayer.create(PlayService.this,uri); mPlayer.setOnCompletionListener(this); // 開始更新進度的執行緒 mProgressUpdatedListener.execute(mPublishProgressRunnable);
}
// 申請裝置電源鎖
    private void acquireWakeLock() {
        L.l(TAG, "正在申請電源鎖");
        if (null == mWakeLock) {
            PowerManager pm = (PowerManager) this
                    .getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
                    | PowerManager.ON_AFTER_RELEASE, "");
            if (null != mWakeLock) {
                mWakeLock.acquire();
                L.l(TAG, "電源鎖申請成功");
            }
        }
    }

    // 釋放裝置電源鎖
    private void releaseWakeLock() {
        L.l(TAG, "正在釋放電源鎖");
        if (null != mWakeLock) {
            mWakeLock.release();
            mWakeLock = null;
            L.l(TAG, "電源鎖釋放成功");
        }
    }
  • 第二個問題解決方法:
/*這個問題是版本問題
4.0以上 不要new了
直接create*/
Uri uri = Uri.parse(MusicUtils.sMusicList.get(
    getPlayingPosition()).getUri());
  mPlayer = MediaPlayer.create(PlayService.this,uri);

解決方法就是:mplayer=new MediaPlayer();
改為:mPlayer = MediaPlayer.create(PlayService.this,uri);
即可。

另外值得一提同時,播放歌曲需要讀取SD卡資料,所以需要許可權:
< uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>

還有一點必須提醒,就是服務的開啟,我們知道服務有兩種方式啟動,一種是startservice()方式啟動,這種方式不隨著Context的銷燬而接觸繫結導致服務停止,另一種方式是bindservice()方式,這種方式隨著context的銷燬而unbindservice,導致服務停止。

我們可以在application類中使用startservice啟動所需的服務,然後到需要繫結該服務的Activity中使用bindservice再次繫結該服務,activity銷燬時再unbindservice服務,此時並不會stopservice,除非顯式呼叫stopservice方法才會導致服務停止。使用這中方法可以儘可能的提高服務的優先順序,使服務一直在後臺執行。

最後需要指出的是,以上措施並不能是服務很好的平穩執行,在我手機中採用了以上方法,但是,當我退出程式,app在後臺執行,歌曲會一直播放,但是等一段時間後歌曲會停止播放,但是後臺服務並沒有呼叫ondestory方法,也就是說服務沒有停止。

目前為止,本人瞭解到,一般開發者開發的app還不能做到一直在後臺執行的服務,還不能像QQ,微信這樣的APP做到服務一直在後臺,無法銷燬。這個原因是,一般開發的app並不是手機安全軟體所識別,手機安全軟體有白名單,這些白名單就是QQ,微信等應用,它的使用者量非常多,所以手機安全軟體是不會把這些app服務給銷燬掉的,而一般app並不是使用者所必須的,手機安全軟體當然把一般的app服務給銷燬掉,不然的話,一般開發者開發的app都能開發一直執行的服務在後臺執行的話,手機本身都受不了了!所以在此提醒大家,不要費勁開發service服務一直在後臺執行的了,能做到service服務在不清楚記憶體的情況下能夠執行就可以了,而上面的那些方法說明是可以做到的!

上面的解決措施是我親身測試過的,如果有什麼疑問,大家留言,相互交流學習!!^_^【握手】