Android Auto 应用从不调用 onGetRoot
Posted
技术标签:
【中文标题】Android Auto 应用从不调用 onGetRoot【英文标题】:Android Auto app never calls onGetRoot 【发布时间】:2016-07-26 23:07:16 【问题描述】:我正在为 android 开发音频流应用程序并集成 Android Auto。我一直在关注这两个教程。
Android Developer Training
PTR Android Blog
使用桌面主机,我可以从媒体应用程序列表中选择我的媒体应用程序,但从那里ProgressBar
停留而不是让位于“要播放某些内容,请打开左上角的菜单。”在Universal Music Player 中看到的消息。
经过检查,似乎从未调用过MediaBrowserServiceCompat
的onGetRoot()
,因此从未将我的MediaItemCompat
填充到Auto 应用的列表中。
我的清单包含以下内容。
<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>
我的automotive_app_desc.xml
很简单,只声明Media。
<?xml version="1.0" encoding="utf-8"?>
<automotiveApp>
<uses name="media"/>
</automotiveApp>
我的MediaService
扩展了MediaBrowserServiceCompat
。在onCreate()
中,我创建并设置了我的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);
最后,来自MediaBrowserServiceCompat
的两个被覆盖的方法,它们都没有被调用过。
@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);
据我所知,这就是启动 Android Auto 所需的一切,但是当我在桌面主机上打开应用程序时,只有一个 ProgressBar
问候我,当我打开屏幕外导航抽屉,还有一个。在我读过的任何材料中,我都没有听说过这种状态。有什么我错过的吗?
【问题讨论】:
【参考方案1】:最终,这个问题与我所描述的没有任何关系。前面提到的MediaService
还执行需要自定义Binder
的其他任务。此自定义 Binder
没有调用主机所需的 onGetRoot()
。作为一种解决方案,我检查了Intent
操作并在来自MediaBrowserServiceCompat
时返回super.onBind()
。
@Override
public IBinder onBind(Intent intent)
if (SERVICE_INTERFACE.equals(intent.getAction()))
return super.onBind(intent);
return new MediaBinder();
SERVICE_INTERFACE
是MediaBrowserServiceCompat
中的常量。
【讨论】:
非常感谢您发布此解决方案。我已经调试了好几个小时了。 好的,谢谢!顺便提一下,因为我的初始搜索没有结果,返回我自己的自定义 Binder 而不是 MediaBrowserServiceCompat 也导致记录错误:“[my.package.name]: oneway function results will be dropped but finished with status UNKNOWN_TRANSACTION and parcel size 0 ”。在我进行此处描述的更改后,这些都消失了(Android Auto 开始工作)。【参考方案2】:我正在开发一个 Android 自动,但我的这部分代码有一些问题,在服务的 Onbind
方法中:
public IBinder onBind(Intent arg0)
Log.i("TAG", "OnBind");
// TODO Auto-generated method stub
if (SERVICE_INTERFACE.equals(arg0.getAction()))
Log.i("TAG", "SERVICE_INTERFACE");
registerReceiver(receiver, filter);
return super.onBind(arg0);
else
Log.i("Musica Service", "musicBind");
return musicBind;
我通过musicBind IBinder
与我的服务绑定了其他活动,但另一方面,我已将所有内容设置为在 Android 自动界面中连接我的应用程序,但在将设备与 android auto 断开连接后关闭我的应用程序后,我可以不要阻止我的mediabrowserservice
兼容。我认为这是由于SERVICE_INTERFACE
一直绑定服务。如何从同一个 servicemediabrowserservicecompat
阻止或销毁它?
【讨论】:
欢迎来到 Stack Overflow。这不是问题的答案,而是评论/新问题。一旦您有足够的声誉 (50),您就可以对任何帖子发表评论。与此同时,您可以获得asking your own questions 或providing answers on subjects 的声誉。以上是关于Android Auto 应用从不调用 onGetRoot的主要内容,如果未能解决你的问题,请参考以下文章
Android 8.1 连接到调用 connectGatt 的 BLE 外围设备。回调总是说断开连接。从不连接
Razor Pages - 在所有 OnGet 处理程序之后从基类调用方法
适用于 Android 谷歌云消息 (GCM) 的 Azure 移动服务从不向设备发送通知