I'm curious if anyone has ran into this problem or has any suggestions. I'm writing a media player in which I'm utilizing the MediaSessionCompat API. Every so often I determine the current position of the playing media and raise a change event. I re-set the playback state as seen below. However, since the STATE_PLAYING
state does not change, Android does not raise the notification that the position value changed. In particular, when I have a Bluetooth device connected that displays the current position, the Bluetooth device only receives the position when the state changes from STATE_PLAYING
to STATE_PAUSED
, or vice versa. See code below:
public void setup() {
mediaSession = new MediaSessionCompat(context, Schema.TAG, component, pendingIntent);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setActive(true);
updatePlaybackState();
}
public void updatePlaybackState() {
int state = isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED;
int ms = getCurrentPosition();
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(state, ms, 1f)
.build());
}
In this example, I call updatePlaybackState
when the current position changes. If I change the updatePlaybackState
method as follows, then it works as expected; though, I'm not sure if I should be doing it this way.
public void updatePlaybackState() {
int state = isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED;
int ms = getCurrentPosition();
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_NONE, ms, 1f)
.build());
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(state, ms, 1f)
.build());
}
As you can see, I set the state to STATE_NONE
and then I re-set the state back to STATE_PLAYING
to cause Android to notice that the state changed, which re-publishes the current position to the connected Bluetooth device.
How does the bluetooth device read the position? I'm assuming some code constantly monitors the playbackstate to get the current position?
To prevent you from constantly having to update the PlaybackState
, the playback state contains the necessary values to compute the approximate current position of the stream.
When setting the playbackState, you provide values such as speed, current position and the update time.
PlaybackState.Buider.setState(int state, long position, float playbackSpeed, long updateTime)
Given the assertion that unless the playback state changes and it is currently playing, you can calculate the currentPosition from the lastUpdate time, speed and the previousPosition.
long timeDelta = SystemClock.elapsedRealtime() - lastPlaybackState.getLastPositionUpdateTime();
long currentPosition = (int) timeDelta * lastPlaybackState.getPlaybackSpeed();
You can take a look at how uAmp does this in FullScreenPlayerActivity. The specific method is updateProgress(..)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With