I'm having trouble with the Play [song] on [app] command; specifically the "app" is not being recognised by Android Auto.
I get an audio speech message back: "Not sure how to help with play song on app"
So the speech recognition is working perfectly (as song and app are as I spoke), however either the matching to the app isn't working or it is not obvious to Auto that my app can handle this.
In the simulator, search works from the Search menu option so I'm assuming my intent filters are correct.
My Manifest has the following:
<!-- - - - - - - - - - - - - - - - - - - - - -->
<!-- Auto -->
<!-- - - - - - - - - - - - - - - - - - - - - -->
<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/brand_icon_white" />
<service android:name=".library.service.auto.MyMediaBrowserService"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
I have tried putting the following into my service declaration or an Activity as shown in the YouTube DevByte but neither seems to work:
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
I would expect it to be in the Service as there are no Activities associated with the Service. I would like to know for sure where this should be.
I have probably missed something out or misunderstood something. One issue could be that the name of the application contains a number in it (eg. 1up).
Simply declare an intent-filter
for MEDIA_PLAY_FROM_SEARCH in an Activity declaration. It is not mandatory for Android Auto to actually handle the intent, since Android Auto will call the MediaSession.Callback.onPlayFromSearch
. The declaration in the manifest serves to flag your app as available to respond media voice commands. However, you might want to handle it properly, because other non-Auto environments, like Google Now, will submit voice searches via that intent.
The best way to handle the intent is by calling MediaController.TransportControls.playFromSearch
, so you handle it in a consistent way no matter how the voice search was triggered.
See this snippet from uAmp AndroidManifest.xml:
<!-- Main activity for music browsing on phone -->
<activity
android:name=".ui.MusicPlayerActivity"
android:label="@string/app_name">
[...]
<!-- Use this intent filter to get voice searches, like "Play The Beatles" -->
<intent-filter>
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
And this is how the intent is handled:
@Override
protected void onMediaControllerConnected() {
if (mVoiceSearchParams != null) {
String query = mVoiceSearchParams.getString(SearchManager.QUERY);
getMediaController().getTransportControls().playFromSearch(query, mVoiceSearchParams);
mVoiceSearchParams = null;
}
getBrowseFragment().onConnected();
}
One caveat: you need to publish your app with the intent-filter and wait a few days to get it flagged and indexed for the "Play [x] on [y]" type of query. It is not instantaneous.
As mangini's answer suggests, I got this working by adding only the intent filter to my main activity:
<activity
android:name=".LandingActivity"
android:label="@string/app_name"
android:noHistory="true"
android:launchMode="singleTop"
android:theme="@style/SplashTheme">
<!-- for the launcher -->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<!-- for media search (Play X in Y) -->
<intent-filter>
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
I didn't have to add any other code. androidx.media
just magically worked. When I say "Play X" while my app is running in the Android Auto foreground, my MediaSessionCompat.Callback
subclass got an onPlayFromSearch
callback, and when I tapped Search Results
in Android Auto, my MediaBrowserServiceCompat
subclass got an onSearch
callback.
I also tried adding this intent-filter
to my service
declaration in AndroidManifest.xml
, and that didn't work:
<service
android:name=".BackgroundAudioNotificationService"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
<action android:name="android.intent.action.MEDIA_BUTTON" />
<!-- Tried to do "Play X" while running in Android Auto, and this didn't work -->
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
</intent-filter>
</service>
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