如何检测Android Auto是否与Android 12连接



在我的驾驶伴侣应用程序中,我需要检测Android Auto的状态。几年来,我一直在使用UiModeManager在启动时获取当前状态,并使用BroadcastReceiver在应用程序运行时检测状态变化。在安卓12之前,这一直都很完美。对于Android 12,UiModeManager始终报告UI_MODE_TYPE_NORMAL,即使Android Auto已连接并处于活动状态,并且在连接或断开连接后从未调用我的BroadcastReceiver。

这是我在启动时检测状态的代码:

inCarMode = uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR;

这是我的BroadcastReceiver设置:

IntentFilter carModeFilter = new IntentFilter();
carModeFilter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
carModeFilter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE);
registerReceiver(carModeReceiver, carModeFilter);

同样,这一直与安卓5到安卓11完美配合。这是安卓12中的一个错误,还是有一些新的方法可以检测安卓12中的安卓自动状态?

您需要使用此处介绍的CarConnectionAPI

Configuration.UI_MODE_TYPE_CAR未在小行星12上工作。正如@Pierre-Olivier-Dybman所说,您可以在androidx.car.app:app库中使用CarConnectionAPI。但是,如果您不需要其他功能,那么它太重了,无法仅为汽车连接导入整个库。

所以我在CarConnection上写了一段代码来检测Android Auto连接,如下所示:

class AutoConnectionDetector(val context: Context) {
companion object {
const val TAG = "AutoConnectionDetector"
// columnName for provider to query on connection status
const val CAR_CONNECTION_STATE = "CarConnectionState"
// auto app on your phone will send broadcast with this action when connection state changes
const val ACTION_CAR_CONNECTION_UPDATED = "androidx.car.app.connection.action.CAR_CONNECTION_UPDATED"
// phone is not connected to car
const val CONNECTION_TYPE_NOT_CONNECTED = 0
// phone is connected to Automotive OS
const val CONNECTION_TYPE_NATIVE = 1
// phone is connected to Android Auto
const val CONNECTION_TYPE_PROJECTION = 2
private const val QUERY_TOKEN = 42
private const val CAR_CONNECTION_AUTHORITY = "androidx.car.app.connection"
private val PROJECTION_HOST_URI = Uri.Builder().scheme("content").authority(CAR_CONNECTION_AUTHORITY).build()
}
private val carConnectionReceiver = CarConnectionBroadcastReceiver()
private val carConnectionQueryHandler = CarConnectionQueryHandler(context.contentResolver)
fun registerCarConnectionReceiver() {
context.registerReceiver(carConnectionReceiver, IntentFilter(ACTION_CAR_CONNECTION_UPDATED))
queryForState()
}
fun unRegisterCarConnectionReceiver() {
context.unregisterReceiver(carConnectionReceiver)
}
private fun queryForState() {
carConnectionQueryHandler.startQuery(
QUERY_TOKEN,
null,
PROJECTION_HOST_URI,
arrayOf(CAR_CONNECTION_STATE),
null,
null,
null
)
}
inner class CarConnectionBroadcastReceiver : BroadcastReceiver() {
// query for connection state every time the receiver receives the broadcast
override fun onReceive(context: Context?, intent: Intent?) {
queryForState()
}
}
internal class CarConnectionQueryHandler(resolver: ContentResolver?) : AsyncQueryHandler(resolver) {
// notify new queryed connection status when query complete
override fun onQueryComplete(token: Int, cookie: Any?, response: Cursor?) {
if (response == null) {
Log.w(TAG, "Null response from content provider when checking connection to the car, treating as disconnected")
notifyCarDisconnected()
return
}
val carConnectionTypeColumn = response.getColumnIndex(CAR_CONNECTION_STATE)
if (carConnectionTypeColumn < 0) {
Log.w(TAG, "Connection to car response is missing the connection type, treating as disconnected")
notifyCarDisconnected()
return
}
if (!response.moveToNext()) {
Log.w(TAG, "Connection to car response is empty, treating as disconnected")
notifyCarDisconnected()
return
}
val connectionState = response.getInt(carConnectionTypeColumn)
if (connectionState == CONNECTION_TYPE_NOT_CONNECTED) {
Log.i(TAG, "Android Auto disconnected")
notifyCarDisconnected()
} else {
Log.i(TAG, "Android Auto connected")
notifyCarConnected()
}
}
}
}

此解决方案适用于android 6~12。如果你需要在android 5上检测汽车连接状态,请使用Configuration.UI_MODE_TYPE_CAR解决方案。

最新更新