Consumo de automóviles Estado de conducción y restricciones de UX

Este artículo explica cómo las aplicaciones pueden hacer una transición elegante a las 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 reglas de restricciones de la experiencia del usuario (UX) del automóvil, 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 desean diseñar aplicaciones que se adapten a los cambios en el estado de conducción de un automóvil y las restricciones de UX correspondientes impuestas.

Detalles técnicos

CocheConducirEstadoAdministrador

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.

Esta información está expuesta a clientes privilegiados por medio de CarDrivingStateManager , que proporciona @SystemApis, lo que significa que solo Platform Internals, Bundles APK (como SysUI o Settings) y Privileged APK (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 la información del 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 tengan que ajustarse a los diferentes requisitos de seguridad del mercado.

Nota : estas actividades deben estar marcadas como DistractionOptimized, como se describe en Pautas de distracción del conductor . Si las actividades no están debidamente marcadas, se bloquearán.

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 ejemplo ilustra cómo una aplicación supervisa las restricciones de UX:

  1. Importe los paquetes de la biblioteca de automóviles:
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
    
  2. Implemente CarUxRestrictionManager.OnUxRestrictionsChangedListener ( mUxRChangeListener ). Este oyente, una vez registrado con CarUxRestrictionsManager , será llamado cuando ocurra un cambio en las restricciones de UX. Manejar 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 de automóviles para crear una instancia de automóvil denominada mCar y conéctese al servicio de automóviles:
    mCar = Car.createCar(context);
    if (mCar == null) {
    // handle car connection error
    }
    
  4. Llame 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 un requisito actual para optimizar la distracción?
  2. Si es así, ¿qué restricciones existen actualmente?

Una vez que 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 falso, no hay ningún requisito para optimizar la distracción y una aplicación puede ejecutar cualquier actividad de manera segura.

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

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

Por ejemplo, si una aplicación desea 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 y/o obtener el estado de conducción actual. El estado de conducción se devuelve como CarDrivingStateEvent.

Al igual que las API de CarUxRestrictionsManager, los clientes pueden registrar un agente de escucha para el estado de conducción mediante registerListener() y pasar una implementación de CarDrivingStateEventListener . En los cambios de estado de conducción, se llamará 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 la velocidad para cambiar el estado de conducción. Use 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 el engranaje en Estacionado (para simular CarDrivingStateEvent apuntando 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 un evento de estado de conducción de automóvil que apunte a RALENTÍ):
    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 apuntando a MOVING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30