Android 自动 - 语音 - 无法执行 "Play [x] on [y]"

Android Auto - Voice - Cannot perform "Play [x] on [y]"

我在 [app] 上播放 [song] 命令时遇到问题;具体来说,"app" 未被 Android 自动识别。

我收到一条音频语音消息: "Not sure how to help with play song on app"

所以语音识别工作完美(就像我所说的歌曲和应用程序一样),但是与应用程序的匹配不起作用或者 Auto 并不明显我的应用程序可以处理这个问题。

在模拟器中,搜索是通过“搜索”菜单选项进行的,所以我假设我的意图过滤器是正确的。

我的清单有以下内容:

    <!-- - - - - - - - - - - - - - - - - - - - - -->
    <!-- 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>

我已经尝试将以下内容放入我的服务声明或 Activity 中,如 YouTube DevByte 中所示,但似乎都不起作用:

    <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
    <category android:name="android.intent.category.DEFAULT" />

我希望它在服务中,因为没有与服务关联的活动。我想确定它应该在哪里。

我可能漏掉了什么或者误解了什么。一个问题可能是应用程序的名称中包含一个数字(例如 1up)。

只需在 Activity 声明中为 MEDIA_PLAY_FROM_SEARCH 声明一个 intent-filter。 Android Auto 并不强制实际处理意图,因为 Android Auto 将调用 MediaSession.Callback.onPlayFromSearch。清单中的声明用于将您的应用标记为可用于响应媒体语音命令。但是,您可能希望正确处理它,因为其他非自动环境,如 Google Now,将通过该意图提交语音搜索。

处理意图的最佳方式是调用 MediaController.TransportControls.playFromSearch,这样无论语音搜索是如何触发的,您都可以以一致的方式处理它。

请参阅 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>

this is how意图处理:

@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.

正如 所建议的那样,我通过仅将意图过滤器添加到我的主 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>

我不需要添加任何其他代码。 androidx.media 神奇地起作用了。当我在 Android 自动前景中 运行 时说“播放 X”时,我的 MediaSessionCompat.Callback 子类收到 onPlayFromSearch 回调,当我点击 Search Results 在 Android Auto 中,我的 MediaBrowserServiceCompat 子类得到了一个 onSearch 回调。

我也尝试将此 intent-filter 添加到我在 AndroidManifest.xml 中的 service 声明中,但没有成功:

<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>