I'm developing an audio streaming application for Android and integrating Android Auto. I've been following these two tutorials.
Using the Desktop Head Unit, I'm able to select my media app from the media app list, but from there a ProgressBar
stays instead of giving way to the "To play something, open the menu at the top left." message seen in the Universal Music Player.
On inspection, it seems that the MediaBrowserServiceCompat
's onGetRoot()
is never invoked and thus never populating my MediaItemCompat
into the Auto app's list.
My manifest contains the following.
<manifest package="com.app.audio"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name="com.app.audio.AudioApp"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.app.audio.presentation.home.HomeActivity"
android:label="@string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="com.app.audio.presentation.weather.WeatherActivity"
android:screenOrientation="userPortrait"/>
<activity android:name="com.app.audio.presentation.settings.SettingsActivity"/>
<activity android:name="com.app.audio.presentation.alarm.AlarmActivity"/>
<activity android:name="com.app.audio.presentation.sleep.SleepActivity"/>
<receiver android:name="com.app.audio.audio.AudioIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON"/>
<action android:name="android.media.AUDIO_BECOMING_NOISY"/>
</intent-filter>
</receiver>
<receiver android:name="com.app.audio.presentation.alarm.AlarmReceiver"></receiver>
<receiver android:name="com.app.audio.presentation.sleep.SleepReceiver"></receiver>
<service
android:name="com.app.audio.data.service.media.MediaService"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<meta-data
android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
<meta-data
android:name="com.google.android.gms.car.notification.SmallIcon"
android:resource="@drawable/ic_launcher"/>
</application>
My automotive_app_desc.xml
is very simple, only declaring Media.
<?xml version="1.0" encoding="utf-8"?>
<automotiveApp>
<uses name="media"/>
</automotiveApp>
My MediaService
extends MediaBrowserServiceCompat
. In the onCreate()
I create and set my MediaSessionCompat
.
@Override
public void onCreate() {
super.onCreate();
//...
mediaSession = new MediaSessionCompat(
this,
SESSION_TAG,
mediaIntentReceiver,
null
);
mediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setCallback(new MediaSessionCompat.Callback() {
@Override
public void onPlay() {
super.onPlay();
play(selectedStream);
}
@Override
public void onPause() {
super.onPause();
pause();
}
@Override
public void onStop() {
super.onStop();
stop();
}
@Override
public void onSkipToNext() {
super.onSkipToNext();
playNextStation();
}
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
playPreviousStation();
}
});
mediaSession.setActive(true);
setSessionToken(mediaSession.getSessionToken());
updatePlaybackState(ACTION_STOP);
}
Finally, the two overridden methods from MediaBrowserServiceCompat
, of which neither is ever called.
@Nullable
@Override
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) {
return new BrowserRoot(ROOT_ID, null);
}
@Override
public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
List<MediaBrowserCompat.MediaItem> items = getMediaItemsById(parentId);
if (items != null) {
result.sendResult(items);
}
}
As far as I can tell, that's everything required to get an Android Auto started, yet when I open the app on my desktop head unit, there is only a ProgressBar
greeting me, and when I open the off-screen nav drawer, there's another one. I haven't heard of that state in any material I've read. Is there something I missed?