public static boolean isCarUiMode(Context c) {
UiModeManager uiModeManager = (UiModeManager) c.getSystemService(Context.UI_MODE_SERVICE);
if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
LogHelper.d(TAG, "Running in Car mode");
return true;
} else {
LogHelper.d(TAG, "Running on a non-Car mode");
return false;
}
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()
}
}
}
}
public class AutoConnectionDetector {
private final Context context;
private static String TAG = "AutoConnectionDetector";
private final CarConnectionBroadcastReceiver carConnectionReceiver = new CarConnectionBroadcastReceiver();
private final CarConnectionQueryHandler carConnectionQueryHandler;
// columnName for provider to query on connection status
private static final String CAR_CONNECTION_STATE = "CarConnectionState";
// auto app on your phone will send broadcast with this action when connection state changes
private final String ACTION_CAR_CONNECTION_UPDATED = "androidx.car.app.connection.action.CAR_CONNECTION_UPDATED";
// phone is not connected to car
private static final int CONNECTION_TYPE_NOT_CONNECTED = 0;
// phone is connected to Automotive OS
private final int CONNECTION_TYPE_NATIVE = 1;
// phone is connected to Android Auto
private final int CONNECTION_TYPE_PROJECTION = 2;
private final int QUERY_TOKEN = 42;
private final String CAR_CONNECTION_AUTHORITY = "androidx.car.app.connection";
private final Uri PROJECTION_HOST_URI = new Uri.Builder().scheme("content").authority(CAR_CONNECTION_AUTHORITY).build();
public interface OnCarConnectionStateListener {
void onCarConnected();
void onCarDisconnected();
}
private static OnCarConnectionStateListener listener;
public void setListener(OnCarConnectionStateListener listener) {
AutoConnectionDetector.listener = listener;
}
public AutoConnectionDetector(Context context) {
this.context = context;
carConnectionQueryHandler = new CarConnectionQueryHandler(context.getContentResolver());
}
public void registerCarConnectionReceiver() {
context.registerReceiver(carConnectionReceiver, new IntentFilter(ACTION_CAR_CONNECTION_UPDATED));
queryForState();
Log.i(TAG, "registerCarConnectionReceiver: ");
}
public void unRegisterCarConnectionReceiver() {
context.unregisterReceiver(carConnectionReceiver);
Log.i(TAG, "unRegisterCarConnectionReceiver: ");
}
private void queryForState() {
String[] projection = {CAR_CONNECTION_STATE};
carConnectionQueryHandler.startQuery(
QUERY_TOKEN,
null,
PROJECTION_HOST_URI,
projection,
null,
null,
null
);
}
private static void notifyCarConnected() {
listener.onCarConnected();
}
private static void notifyCarDisconnected() {
listener.onCarDisconnected();
}
class CarConnectionBroadcastReceiver extends BroadcastReceiver {
// query for connection state every time the receiver receives the broadcast
@Override
public void onReceive(Context context, Intent intent) {
queryForState();
}
}
private static class CarConnectionQueryHandler extends AsyncQueryHandler {
public CarConnectionQueryHandler(ContentResolver contentResolver) {
super(contentResolver);
}
@Override
protected void onQueryComplete(int token, Object cookie, Cursor response) {
if (response == null) {
Log.w(TAG, "Null response from content provider when checking connection to the car, treating as disconnected");
notifyCarDisconnected();
return;
}
int 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;
}
int connectionState = response.getInt(carConnectionTypeColumn);
if (connectionState == CONNECTION_TYPE_NOT_CONNECTED) {
Log.i(TAG, "Android Auto disconnected");
notifyCarDisconnected();
} else {
Log.i(TAG, "Android Auto connected");
Log.i(TAG, "onQueryComplete: " + connectionState);
notifyCarConnected();
}
}
}
}
5条答案
按热度按时间falq053o1#
编辑:在Android 12中,该解决方案不再起作用,相反,最好使用此处记录的
CarConnection
API我知道这是一个老线索,但由于它首先出现在谷歌,here is the answer from another question
}
nkcskrwz2#
Configuration.UI_MODE_TYPE_CAR
在Anroid 12上不起作用。您可以在androidx.car.app:app
库中使用CarConnection
API。但如果您不需要其他功能,则无法仅为汽车连接导入整个库。所以我写了一段代码的基础上
CarConnection
检测Android自动连接,如下:此解决方案适用于android 6~12,如果需要在android 5上检测汽车连接状态,请使用
Configuration.UI_MODE_TYPE_CAR
解决方案。6kkfgxo03#
推荐G.Zxuan工作完美,但我们必须在build.gradle中添加依赖项“androidx.car.app:app-projected:1.1.0”
yvfmudvl4#
请参见https://developer.android.com/training/cars/apps#car-connection
app/build.gradle
:kcrjzv8t5#
@G.Zxuan的Kotlin解决方案很好用,我把它转成了Java,还加了监听器接口,在安卓12上测试