使用车载驾驶状态和用户体验限制

本页面介绍了应用如何平稳过渡到分心优化 (DO) 用户界面。它介绍了如何使用汽车的驾驶状态以及相应的用户体验限制。如需详细了解车载用户体验 (UX) 限制,请参阅车载用户体验限制,其中详细介绍了停车、怠速和行驶这三种驾驶状态。

受众

此内容适用于想要设计能够适应汽车驾驶状态变化以及相应施加的用户体验限制的应用的设计人员。

技术细节

CarDrivingStateManager

汽车的驾驶状态(停车、怠速或行驶)源自车辆硬件抽象层 (VHAL) 提供的传感器值。基本传感器信息(例如车速和当前档位选择)用于推导车辆的当前驾驶状态。

CarDrivingStateEvent.

它提供 @SystemApis,这意味着只有平台内部组件、捆绑 APK(例如 SysUI 或设置)和特权 APK(例如 GMSCore)可以访问这些 API。这些 API 受驾驶状态特定权限 android.car.permission.CAR_DRIVING_STATE 保护。需要访问驾驶状态信息的客户端必须请求此权限。

CarUxRestrictionsManager

那些显示依赖于驾驶状态的用户界面的应用必须监听 CarUxRestrictionsManager,后者抽象了从驾驶状态到用户体验限制的映射,以便应用无需针对不同的市场安全要求进行调整。

注意:这些 Activity必须标记为分心优化,如驾驶员分心指南中所述。如果 Activity 未相应标记,则会被阻止。

相反,应用会监控 CarUxRestrictionsManager 公开的限制,而不是 CarDrivingStateManager 公开的绝对驾驶状态,以了解与用户界面或用户体验相关的任何信息。

代码示例

以下示例代码演示了应用如何监控用户体验限制

  1. 导入汽车库软件包
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
  2. 实现 CarUxRestrictionManager.OnUxRestrictionsChangedListener (mUxRChangeListener)。此监听器在 CarUxRestrictionsManager 中注册后,会在用户体验限制发生更改时调用。根据需要处理限制更改以实现分心优化
    @Nullable private CarUxRestrictionsManager mCarUxRestrictionsManager;
    private CarUxRestrictions mCurrentUxRestrictions;
    
    /* Implement the onUxRestrictionsChangedListener interface */
    private CarUxRestrictionsManager.OnUxRestrictionsChangedListener mUxrChangeListener =
                new CarUxRestrictionsManager.OnUxRestrictionsChangedListener()
        {
            @Override
            public void onUxRestrictionsChanged(CarUxRestrictions carUxRestrictions) {
            mCurrentUxRestrictions = carUxRestrictions;
            /* Handle the new restrictions */
            handleUxRestrictionsChanged(carUxRestrictions);
            }
        };
      
  3. 调用汽车 API 以创建名为 mCar 的汽车实例并连接到汽车服务
    mCar = Car.createCar(context);
    if (mCar == null) {
    // handle car connection error
    }
  4. 调用 mCar.getCarManager() - mCarUxRestrictionsManager 以获取 CarUxRestrictionsManager
    CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
    mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
  5. 要注册在上述步骤 2 中实现的 mUxRChangeListener,请调用 mCarUxRestrictionsManager.registerListener()
    mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
    mUxrChangeListener.onUxRestrictionsChanged(
    mCarUxRestrictionsManager.getCurrentCarUxRestrictions());

步骤 3 到步骤 5 中创建的完整示例代码块将使监听器在驾驶状态更改时接收限制更改

mCar = Car.createCar(context);
if (mCar == null) {
// handle car connection error
}

CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);

mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
mUxrChangeListener.onUxRestrictionsChanged(
mCarUxRestrictionsManager.getCurrentCarUxRestrictions());

CarUxRestrictions

CarUxRestrictions 对象提供两种类型的信息

  1. 当前是否需要进行分心优化?
  2. 如果是,当前有哪些限制?

当从 getCurrentUxRestrictions() 或监听器回调中获取 CarUxRestrictions 时,应用现在可以使用 isRequiresDistractionOptimization() API 来确定是否需要进行分心优化。如果此 API 返回 false,则无需进行分心优化,应用可以安全地运行任何 Activity。

如果需要优化,则使用 getActiveRestrictions() API 获取正在生效的限制集。此 API 返回一个整数,它是当前生效的所有限制的位掩码。当前通知的限制集在 CarUxRestrictions 下列出。

注意:预计在不久的将来,限制集会发生细微变化。

例如,如果应用想要确定是否存在播放视频的限制,则在获取 CarUxRestrictions 对象后,应用必须检查该限制

int activeUxR = mCurrentCarUxRestrictions.getActiveRestrictions();
if ((activeUxR & CarUxRestrictions.UX_RESTRICTIONS_NO_VIDEO) != 0) {
      handleStopPlayingVideo();
}

DrivingState

CarDrivingStateManager 表示车辆的实际驾驶状态(停车、怠速或行驶)。可以调用 CarDrivingStateManager API,类似于 CarUxRestrictionsManager。应用可以注册监听器或获取当前驾驶状态。驾驶状态作为 CarDrivingStateEvent 返回。

CarDrivingStateEvent.

发生更改时,将使用新的 CarDrivingStateEvent 调用 onDrivingStateChanged() 方法。

import android.car.Car;
/* For CarDrivingState */
import android.car.drivingstate.CarDrivingStateEvent;
import android.car.drivingstate.CarDrivingStateManager;

mDrivingStateManager = (CarDrivingStateManager) mCar.getCarManager(
       Car.CAR_DRIVING_STATE_SERVICE);
/* Register the listener (implemented below) */
mDrivingStateManager.registerListener(mDrivingStateEventListener);
/* While we wait for a change to be notified, query the current state */
mDrivingStateEvent = mDrivingStateManager.getCurrentCarDrivingState();

private final CarDrivingStateManager.CarDrivingStateEventListener
mDrivingStateEventListener =
       new CarDrivingStateManager.CarDrivingStateEventListener() {
   @Override
   public void onDrivingStateChanged(CarDrivingStateEvent event) {
       mDrivingStateEvent = event;
       /* handle the state change accordingly */
       handleDrivingStateChange();
   }
};

测试

您可以模拟换档和速度变化来更改驾驶状态。使用 ADB shell 命令注入车辆事件。这对于开发和测试非常有用。

要模拟驾驶事件

  1. 要将速度设置为 0
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 0
  2. 要将档位设置为停车档(以模拟指向停车状态的 CarDrivingStateEvent)
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 4
  3. 要将档位设置为行驶档,速度仍为 0(以模拟指向怠速状态的 CarDrivingStateEvent)
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 8
  4. 要将速度设置为 30 米/秒(以模拟指向行驶状态的 CarDrivingStateEvent)
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30