2016-09-27 29 views
2

觸發onPlaybackStateChanged我有這樣的媒體播放器和其他一切工作正常,我開始播放歌曲,它就會通過2個狀態,最後一個是PlaybackStateCompat.STATE_PLAYINGSeekTo不MediaControllerCompat

因此,我們可以說,回調被註冊。問題是每當我觸發SeekBar偵聽器,方法seekTo不會觸發onPlaybackStateChanged,因爲這沒有發生,我不能更新SeekBar到其新的進展。這隻涉及UI。在修改SeekBar進度後,音樂實際上是從進度播放。更重要的是,trackDurationTextView也不會更新。當我在搜索欄上拖動我的拇指時,它會改變它的值,但是一旦我釋放它,它會轉到它的初始進度,與搜索欄相同。

這裏是回調註冊的地方。

@Override 
    public void onServiceConnected(ComponentName componentName, IBinder service) { 
     if (service instanceof MediaPlayerService.ServiceBinder) { 
      try { 
       mediaController = new MediaControllerCompat(this, ((MediaPlayerService.ServiceBinder) service).getService().getMediaSessionToken()); 
      } catch (RemoteException e) { 
       e.printStackTrace(); 
      } 
      mediaController.registerCallback(mMediaControllerCallback); 
     } 
    } 

這是回調如何初始化:

private MediaControllerCompat.Callback mMediaControllerCallback = new MediaControllerCompat.Callback() { 
     @Override 
     public void onPlaybackStateChanged(@NonNull PlaybackStateCompat state) { 
      updatePlaybackState(state); 
     } 

     @Override 
     public void onMetadataChanged(MediaMetadataCompat metadata) { 
      if (metadata != null) { 
       updateMediaDescription(metadata.getDescription()); 
       updateDuration(metadata); 
      } 
     } 
    }; 

這是OnSeekBarChangeListener

trackSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
      @Override 
      public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
       trackDurationTextView.setText(DateUtils.formatElapsedTime(progress/1000)); 
      } 

      @Override 
      public void onStartTrackingTouch(SeekBar seekBar) { 
       stopSeekbarUpdate(); 
      } 

      @Override 
      public void onStopTrackingTouch(SeekBar seekBar) { 
       //TODO: look here! the seek bar position is not kept when the user slides it! 
       mediaController.getTransportControls().seekTo(seekBar.getProgress()); 
       scheduleSeekBarUpdate(); 
      } 
     }); 


private void updateProgress() { 
     if (mLastPlaybackState == null) { 
      return; 
     } 
     long currentPosition = mLastPlaybackState.getPosition(); 
     if (mLastPlaybackState.getState() != PlaybackStateCompat.STATE_PAUSED) { 
      // Calculate the elapsed time between the last position update and now and unless 
      // paused, we can assume (delta * speed) + current position is approximately the 
      // latest position. This ensure that we do not repeatedly call the getPlaybackState() 
      // on MediaControllerCompat. 
      long timeDelta = SystemClock.elapsedRealtime() - 
        mLastPlaybackState.getLastPositionUpdateTime(); 

      currentPosition += (int) timeDelta * mLastPlaybackState.getPlaybackSpeed(); 
     } 
     trackSeekBar.setProgress((int) currentPosition); 
    } 

這是mLastPlayBackState.getPosition應搜索欄後返回新值的地方被更新,但它總是返回0,因爲onPlaybackStateChanged永遠不會被調用。任何想法爲什麼?

+0

你能找到解決方案嗎?我正在面對一個類似的問題,即seekTo開始播放但狀態未更新。 – mobiledev

+0

「Callback.onSeekTo」中的代碼是什麼?你在哪裏調用'mediaSession.setState()'? – ianhanniballake

回答

0

看起來MediaControllerCompat.Callback.onPlaybackStateChanged(PlaybackStateCompat state)只有在MediaSessionCompatPlaybackStateCompatstate發生變化時才被調用。如果PlaybackStateCompatposition更改,而state保持不變,onPlaybackStateChanged(...)永遠不會被調用。所以我通過「onPlaybackStateChanged」假設,API更具體地指的是PlaybackStateCompatstate而不是PlaybackStateCompat本身。

要解決這個問題,我暫時更新PlaybackStateCompatstatePlaybackStateCompat.STATE_REWINDINGPlaybackStateCompat.STATE_FAST_FORWARDING尋道命令後觸發onPlaybackStateChanged(...)在UI上,這樣我就可以更新SeekBar的位置和經過時間TextView的文本到新的播放位置。

UPDATE:我不能再重現此問題。我不確定我改變了什麼來修復它。我的第一個建議是驗證您在mediaSession對象上調用setState(state),其中statePlaybackStateCompat,其中包含更新的position值。這不是我的解決方案,但它是我首先看的地方。

+0

我仍然面臨着這個問題。有沒有一個萬無一失的答案? –

+0

你能幫我嗎?我的MediaControllerCompat.getMediaController(getActivity())。getPlaybackState()。getState()總是返回STATE_NONE –

相關問題