Estado de condução de carro de consumo e restrições de experiência do usuário

Este artigo explica como os aplicativos podem fazer a transição sem problemas para interfaces de usuário otimizadas para distração (DO). Ele descreve como consumir o estado de condução de um carro, bem como as restrições de experiência do usuário correspondentes. Para obter mais informações sobre as regras de Restrições da experiência do usuário do carro (UX), consulte Restrições da experiência do usuário do carro , que detalha os três estados de direção: estacionado, em marcha lenta e em movimento.

Público

Este conteúdo é fornecido para aqueles que desejam projetar aplicativos que se adaptam às mudanças no estado de direção de um carro e às restrições de UX impostas.

Detalhes técnicos

CarDrivingStateManager

O estado de direção de um carro (estacionado, em marcha lenta ou em movimento) é derivado dos valores do sensor fornecidos pela camada de abstração de hardware do veículo (VHAL). Informações básicas do sensor, como velocidade do veículo e seleção de marcha atual, são usadas para derivar o estado atual de direção do veículo.

CarDrivingStateEvent .

que fornece @SystemApis, o que significa que apenas Platform Internals, APKs agrupados (como SysUI ou Settings) e APKs privilegiados (como) GMSCore podem acessar as APIs. As APIs são protegidas por permissões específicas para o estado de condução android.car.permission.CAR_DRIVING_STATE . Os clientes que precisam de acesso às informações do estado de direção devem solicitar essa permissão.

CarUxRestrictionsManager

Esses aplicativos que exibem uma interface de usuário dependente do estado de direção devem ouvir CarUxRestrictionsManager , que abstrai o mapeamento do estado de direção para as restrições de UX para que os aplicativos não precisem se ajustar a diferentes requisitos de segurança do mercado.

Observação : essas atividades devem ser marcadas como DistractionOptimized, conforme descrito nas Diretrizes de distração do motorista . Se as atividades não forem devidamente marcadas, serão bloqueadas.

Em vez disso, os aplicativos monitoram as restrições expostas pelo CarUxRestrictionsManager e não um estado de direção absoluto exposto pelo CarDrivingStateManager para qualquer coisa relacionada à interface do usuário ou à experiência do usuário.

Exemplo de código

O exemplo de código a seguir ilustra como um aplicativo monitora as restrições de UX:

  1. Importe os pacotes da biblioteca de carros:
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
    
  2. Implemente o CarUxRestrictionManager.OnUxRestrictionsChangedListener ( mUxRChangeListener ). Este listener, uma vez registrado no CarUxRestrictionsManager , será chamado quando ocorrer uma alteração nas restrições de UX. Lide com as alterações de restrição para ser otimizado para distração, conforme necessário:
    @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. Chame as APIs de carro para criar uma instância de carro chamada mCar e conecte-se ao serviço de carro:
    mCar = Car.createCar(context);
    if (mCar == null) {
    // handle car connection error
    }
    
  4. Chame mCar.getCarManager() - mCarUxRestrictionsManager para obter o CarUxRestrictionsManager :
    CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
    mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
    
  5. Para registrar mUxRChangeListener implementado na Etapa 2 acima com a chamada CarUxRestrictionsManager mCarUxRestrictionsManager.registerListener() :
    mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
    mUxrChangeListener.onUxRestrictionsChanged(
    mCarUxRestrictionsManager.getCurrentCarUxRestrictions());
    

O bloco completo de código de amostra (criado na Etapa 3 até a Etapa 5) resulta no ouvinte recebendo alterações de restrição quando o estado da unidade muda:

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

O objeto CarUxRestrictions fornece dois tipos de informações:

  1. Existe um requisito atual para ser otimizado para distração?
  2. Em caso afirmativo, quais restrições estão atualmente em vigor?

Depois que CarUxRestrictions é obtido de getCurrentUxRestrictions() ou do retorno de chamada do ouvinte, os aplicativos agora podem usar a API isRequiresDistractionOptimization() para determinar se a otimização de distração é necessária. Se retornar falso, não há necessidade de ser otimizado para distração e um aplicativo pode executar qualquer atividade com segurança.

Se a otimização for necessária, use a API getActiveRestrictions() para obter o conjunto de restrições em vigor. Essa API retorna um int, que é uma máscara de bits de todas as restrições atualmente em vigor. O conjunto de restrições atualmente notificado está listado em CarUxRestrictions .

Nota : Prevê-se que pequenas alterações no conjunto de restrições ocorram em um futuro próximo.

Por exemplo, se um aplicativo deseja determinar se existe uma restrição para reproduzir vídeo, ao obter o objeto CarUxRestrictions, o aplicativo deve verificar a restrição:

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

Driving State

CarDrivingStateManager apresenta o estado real de direção do veículo (estacionado, em marcha lenta ou em movimento). As APIs CarDrivingStateManager podem ser chamadas de forma semelhante ao CarUxRestrictionsManager. Os aplicativos podem registrar um ouvinte e/ou obter o estado de condução atual. O estado de direção é retornado como CarDrivingStateEvent.

CarDrivingStateEvent .

alterações, o método onDrivingStateChanged() será chamado com o novo 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();
   }
};

teste

Você pode imitar a mudança de marchas e velocidade para mudar o estado de condução. Use um comando shell ADB para injetar eventos de veículo. Isso pode ser útil para desenvolvimento e teste.

Para simular eventos de direção:

  1. Para definir a velocidade para 0:
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 0
    
  2. Para definir a marcha para Parked (para simular CarDrivingStateEvent apontando para PARKED):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 4
    
  3. Para definir a marcha para Drive, com a velocidade ainda em 0 (para simular CarDrivingStateEvent apontando para IDLING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 8
    
  4. Para definir a velocidade para 30 metros por segundo (para simular CarDrivingStateEvent apontando para MOVING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30