Использование состояния вождения автомобиля и ограничений UX

В этой статье объясняется, как приложения могут плавно переходить на пользовательские интерфейсы, оптимизированные для отвлечения внимания (DO). В нем описывается, как потреблять состояние вождения автомобиля, а также соответствующие ограничения взаимодействия с пользователем. Дополнительные сведения о правилах ограничений для пользователей автомобилей (UX) см. в разделе Ограничения для пользователей автомобилей , в котором подробно описаны три состояния вождения: «Припарковано», «Холостой ход» и «В движении».

Аудитория

Этот контент предназначен для тех, кто хочет разрабатывать приложения, адаптирующиеся к изменениям режима вождения автомобиля и соответствующим ограничениям UX.

Технические подробности

CarDriveingStateManager

Состояние вождения автомобиля (припарковано, на холостом ходу или в движении) определяется на основе значений датчиков, предоставляемых уровнем абстракции аппаратного обеспечения транспортного средства (VHAL). Основная информация датчика, такая как скорость автомобиля и текущий выбор передачи, используется для определения текущего состояния движения автомобиля.

Эта информация предоставляется привилегированным клиентам с помощью CarDrivingStateManager , который предоставляет @SystemApis, что означает, что только внутренние компоненты платформы, связанные APK (например, SysUI или Settings) и привилегированные APK (например, GMSCore) могут получить доступ к API. API-интерфейсы защищены разрешениями, специфичными для состояния вождения android.car.permission.CAR_DRIVING_STATE . Клиенты, которым требуется доступ к информации о состоянии вождения, должны запросить это разрешение.

CarUxRestrictionsManager

Те приложения, которые отображают пользовательский интерфейс в зависимости от состояния вождения, должны прослушивать CarUxRestrictionsManager , который абстрагирует сопоставление состояния вождения с ограничениями UX, чтобы приложениям не нужно было подстраиваться под различные требования безопасности рынка.

Примечание . Эти действия должны быть помечены как DistractionOptimized, как описано в Руководстве по отвлечению внимания водителя . Если действия не отмечены соответствующим образом, они будут заблокированы.

Вместо этого приложения отслеживают ограничения, предоставляемые CarUxRestrictionsManager, а не абсолютное состояние вождения, предоставляемое CarDrivingStateManager для чего-либо, связанного с пользовательским интерфейсом или взаимодействием с пользователем.

Пример кода

В следующем примере кода показано, как приложение отслеживает ограничения UX:

  1. Импортируйте пакеты автомобильной библиотеки:
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
    
  2. CarUxRestrictionManager.OnUxRestrictionsChangedListener ( mUxRChangeListener ). Этот прослушиватель, зарегистрированный в CarUxRestrictionsManager , будет вызываться при изменении ограничений UX. При необходимости обработайте изменения ограничений, чтобы они были оптимизированы для отвлечения внимания:
    @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. Чтобы зарегистрировать mUxRChangeListener реализованный на шаге 2 выше, с помощью CarUxRestrictionsManager вызовите 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());

CarUxОграничения

Объект CarUxRestrictions предоставляет два типа информации:

  1. Есть ли в настоящее время требование быть оптимизированным для отвлечения внимания?
  2. Если да, то какие ограничения действуют в настоящее время?

Как только CarUxRestrictions получен либо из getCurrentUxRestrictions() , либо из обратного вызова прослушивателя, приложения теперь могут использовать API isRequiresDistractionOptimization() , чтобы определить, требуется ли Distraction Optimization. Если это возвращает false, нет необходимости быть оптимизированным для отвлечения внимания, и приложение может безопасно выполнять любую деятельность.

Если требуется оптимизация, используйте API getActiveRestrictions() , чтобы получить набор действующих ограничений. Этот API возвращает целое число , которое представляет собой битовую маску всех действующих ограничений. Набор ограничений, о которых в настоящее время сообщается, указан в разделе CarUxRestrictions .

Примечание . Ожидается, что в ближайшем будущем будут внесены незначительные изменения в набор ограничений.

Например, если приложение хочет определить, существует ли ограничение на воспроизведение видео, после получения объекта CarUxRestrictions приложение должно проверить наличие ограничения:

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

состояние вождения

CarDrivingStateManager представляет фактическое состояние движения автомобиля (припарковано, на холостом ходу или в движении). API-интерфейсы CarDrivingStateManager можно вызывать аналогично CarUxRestrictionsManager. Приложения могут зарегистрировать слушателя и/или получить текущее состояние вождения. Состояние вождения возвращается как CarDrivingStateEvent.

Подобно API-интерфейсам CarUxRestrictionsManager, клиенты могут зарегистрировать прослушиватель состояния вождения с помощью registerListener() и передать реализацию CarDrivingStateEventListener . При изменении состояния вождения метод onDrivingStateChanged() будет вызываться с новым CarDrivingStateEvent .

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 для внедрения событий транспортного средства. Это может быть полезно для разработки и тестирования.

Чтобы имитировать события вождения:

  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, указывающего на IDLING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 8
    
  4. Чтобы установить скорость 30 метров в секунду (для имитации CarDrivingStateEvent, указывающего на MOVING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30