Consumir restricciones de estado de conducción de automóviles y UX

Esta página explica cómo las aplicaciones pueden realizar una transición elegante a interfaces de usuario optimizadas para distracciones (DO). Describe cómo consumir el estado de conducción de un automóvil, así como las restricciones de experiencia del usuario correspondientes. Para obtener más información sobre las restricciones de la experiencia del usuario del automóvil (UX), consulte Restricciones de la experiencia del usuario del automóvil , que detalla los tres estados de conducción: estacionado, inactivo y en movimiento.

Audiencia

Este contenido se proporciona para aquellos que quieran diseñar aplicaciones que se adapten a los cambios en el estado de conducción de un automóvil y las restricciones de UX impuestas correspondientemente.

Detalles técnicos

CocheConducciónEstadoManager

El estado de conducción de un automóvil (estacionado, inactivo o en movimiento) se deriva de los valores del sensor proporcionados por la capa de abstracción de hardware del vehículo (VHAL). La información básica del sensor, como la velocidad del vehículo y la selección de marcha actual, se utiliza para derivar el estado de conducción actual del vehículo.

CarDrivingStateEvent .

que proporciona @SystemApis, lo que significa que solo los elementos internos de la plataforma, los APK incluidos (como SysUI o Configuración) y los APK privilegiados (como) GMSCore pueden acceder a las API. Las API están protegidas por permisos específicos del estado de conducción android.car.permission.CAR_DRIVING_STATE . Los clientes que requieran acceso a información sobre el estado de conducción deben solicitar este permiso.

CarUxRestrictionsManager

Aquellas aplicaciones que muestran una interfaz de usuario que depende del estado de conducción deben escuchar CarUxRestrictionsManager , que abstrae el mapeo del estado de conducción a las restricciones de UX para que las aplicaciones no necesiten ajustarse a diferentes requisitos de seguridad del mercado.

Nota : Estas actividades deben marcarse como optimizadas para distracciones, como se describe en Pautas sobre distracciones para conductores . Si las actividades no están marcadas como corresponde, se bloquean.

En cambio, las aplicaciones monitorean las restricciones expuestas por CarUxRestrictionsManager y no un estado de conducción absoluto expuesto por CarDrivingStateManager para cualquier cosa relacionada con la interfaz de usuario o la experiencia del usuario.

Ejemplo de código

El siguiente código de muestra ilustra cómo una aplicación monitorea las restricciones de UX:

  1. Importe los paquetes de la biblioteca del automóvil:
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
    
  2. Implemente CarUxRestrictionManager.OnUxRestrictionsChangedListener ( mUxRChangeListener ). Este oyente, cuando se registra con CarUxRestrictionsManager , se llama cuando se produce un cambio en las restricciones de UX. Maneje los cambios de restricción para optimizar la distracción, según sea necesario:
    @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. Llame a las API del automóvil para crear una instancia de automóvil denominada mCar y conectarse al servicio de automóvil:
    mCar = Car.createCar(context);
    if (mCar == null) {
    // handle car connection error
    }
    
  4. Llame a mCar.getCarManager() - mCarUxRestrictionsManager para obtener CarUxRestrictionsManager :
    CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
    mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
    
  5. Para registrar mUxRChangeListener implementado en el Paso 2 anterior con CarUxRestrictionsManager llame a mCarUxRestrictionsManager.registerListener() :
    mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
    mUxrChangeListener.onUxRestrictionsChanged(
    mCarUxRestrictionsManager.getCurrentCarUxRestrictions());
    

El bloque completo de código de muestra (creado en el Paso 3 al Paso 5) da como resultado que el oyente reciba cambios de restricción cuando cambia el estado de la unidad:

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());

CarUxRestricciones

El objeto CarUxRestrictions proporciona dos tipos de información:

  1. ¿Existe actualmente un requisito para optimizar la distracción?
  2. Si es así, ¿qué restricciones existen actualmente?

Cuando CarUxRestrictions se obtiene de getCurrentUxRestrictions() o de la devolución de llamada del oyente, las aplicaciones ahora pueden usar la API isRequiresDistractionOptimization() para determinar si se requiere Distraction Optimized. Si esto devuelve false , no es necesario que esté optimizado para distracciones y una aplicación puede ejecutar cualquier actividad de forma segura.

Si se requiere optimización, utilice la API getActiveRestrictions() para obtener el conjunto de restricciones vigentes. Esta API devuelve un int , que es una máscara de bits de todas las restricciones actualmente vigentes. El conjunto de restricciones notificadas actualmente se enumera en CarUxRestrictions .

Nota: Se prevé que en un futuro próximo se produzcan cambios menores en el conjunto de restricciones.

Por ejemplo, si una aplicación quiere determinar si existe una restricción para reproducir video, al obtener el objeto CarUxRestrictions, la aplicación debe verificar la restricción:

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

Estado de conducción

CarDrivingStateManager presenta el estado de conducción real del vehículo (estacionado, inactivo o en movimiento). Las API de CarDrivingStateManager se pueden llamar de manera similar a CarUxRestrictionsManager. Las aplicaciones pueden registrar un oyente u obtener el estado de conducción actual. El estado de conducción se devuelve como CarDrivingStateEvent.

CarDrivingStateEvent .

cambios, se llama al método onDrivingStateChanged() con el nuevo 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();
   }
};

Pruebas

Puede imitar el cambio de marchas y velocidad para cambiar el estado de conducción. Utilice un comando de shell ADB para inyectar eventos de vehículos. Esto puede ser útil para el desarrollo y las pruebas.

Para simular eventos de conducción:

  1. Para establecer la velocidad en 0:
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 0
    
  2. Para configurar la marcha en Estacionado (para simular CarDrivingStateEvent que apunta a ESTACIONADO):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 4
    
  3. Para configurar la marcha en Conducir, con la velocidad aún en 0 (para simular CarDrivingStateEvent apuntando a IDLING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 8
    
  4. Para establecer la velocidad en 30 metros por segundo (para simular CarDrivingStateEvent que apunta a MOVING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30