2016-09-27 128 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 –

相关问题