Fix android auto resume on reconnect issues (#7156)

Previously the MediaSession object created in PlaybackService in onCreate would
be completely empty. This seemed to confuse Android Auto, and prevented it from
restarting playback.

Filling the MediaSession object using the data from the player state at
onCreate resolves this problem.

This is documented in Android Auto docs[1], albeit indirectly and somewhat
confusingly.

Also move the setSessionToken call to the end of onCreate handler to ensure
that the media session has already been completely filled by the time the
session token is made available to the framework. There is no evidence that
this is required; however intuitively, this is likely the trigger for the
framework to start querying the media session.

The change was tested both with Desktop Head Unit and with a real vehicle.

[1] https://developer.android.com/training/cars/media/#initial-playback-state
This commit is contained in:
hades 2024-05-18 19:34:36 +02:00 committed by GitHub
parent dd8bf381c4
commit 84b6f442fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 2 additions and 26 deletions

View File

@ -238,8 +238,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
};
androidAutoConnectionState.observeForever(androidAutoConnectionObserver);
ContextCompat.registerReceiver(this, autoStateUpdated,
new IntentFilter("com.google.android.gms.car.media.STATUS"), ContextCompat.RECEIVER_EXPORTED);
ContextCompat.registerReceiver(this, shutdownReceiver,
new IntentFilter(PlaybackServiceInterface.ACTION_SHUTDOWN_PLAYBACK_SERVICE),
ContextCompat.RECEIVER_NOT_EXPORTED);
@ -274,11 +272,11 @@ public class PlaybackService extends MediaBrowserServiceCompat {
PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= 31 ? PendingIntent.FLAG_MUTABLE : 0));
mediaSession = new MediaSessionCompat(getApplicationContext(), TAG, eventReceiver, buttonReceiverIntent);
setSessionToken(mediaSession.getSessionToken());
mediaSession.setCallback(sessionCallback);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
recreateMediaPlayer();
mediaSession.setActive(true);
setSessionToken(mediaSession.getSessionToken());
}
void recreateMediaPlayer() {
@ -298,6 +296,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
mediaPlayer.playMediaObject(media, !media.localFileAvailable(), wasPlaying, true);
}
isCasting = mediaPlayer.isCasting();
updateMediaSession(mediaPlayer.getPlayerStatus());
}
@Override
@ -324,7 +323,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
mediaSession.release();
mediaSession = null;
}
unregisterReceiver(autoStateUpdated);
unregisterReceiver(headsetDisconnected);
unregisterReceiver(shutdownReceiver);
unregisterReceiver(bluetoothStateUpdated);
@ -1491,28 +1489,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
}
private final BroadcastReceiver autoStateUpdated = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String status = intent.getStringExtra("media_connection_status");
boolean isConnectedToCar = "media_connected".equals(status);
Log.d(TAG, "Received Auto Connection update: " + status);
if (!isConnectedToCar) {
Log.d(TAG, "Car was unplugged during playback.");
} else {
PlayerStatus playerStatus = mediaPlayer.getPlayerStatus();
if (playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PREPARED) {
mediaPlayer.resume();
} else if (playerStatus == PlayerStatus.PREPARING) {
mediaPlayer.setStartWhenPrepared(!mediaPlayer.isStartWhenPrepared());
} else if (playerStatus == PlayerStatus.INITIALIZED) {
mediaPlayer.setStartWhenPrepared(true);
mediaPlayer.prepare();
}
}
}
};
/**
* Pauses playback when the headset is disconnected and the preference is
* set