Consumir estado de condução de carro e restrições de UX

Esta página explica como os aplicativos podem fazer uma transição tranquila para interfaces de usuário otimizadas para distração (DO). Ele descreve como consumir o estado de direção de um carro, bem como as restrições correspondentes à experiência do usuário. Para obter mais informações sobre restrições de experiência do usuário de carro (UX), consulte Restrições de experiência do usuário de carro , que detalha os três estados de condução: Estacionado, Ocioso e Em Movimento.

Público

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

Detalhes técnicos

CarDrivingStateManager

O estado de conduçã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 componentes internos da plataforma, APKs agrupados (como SysUI ou configurações) 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 necessitam de acesso às informações do estado de condução devem solicitar esta permissão.

CarUxRestrictionsManager

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

Observação : essas atividades devem ser marcadas como otimizadas para distração, conforme descrito em Diretrizes para distração do motorista . Se as atividades não forem marcadas adequadamente, elas serão bloqueadas.

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

Amostra de código

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

  1. Importe os pacotes da biblioteca automotiva:
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
    
  2. Implemente CarUxRestrictionManager.OnUxRestrictionsChangedListener ( mUxRChangeListener ). Este ouvinte, quando registrado no CarUxRestrictionsManager , é chamado quando ocorre uma alteração nas restrições de UX. Lide com as alterações de restrição para otimizar a 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 do carro para criar uma instância de carro chamada mCar e conectar-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 da Etapa 3 até a Etapa 5) faz com que o ouvinte receba 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());

Restrições CarUx

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

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

Quando CarUxRestrictions é obtido de getCurrentUxRestrictions() ou do retorno de chamada do listener, os aplicativos agora podem usar a API isRequiresDistractionOptimization() para determinar se Distraction Optimized é necessário. Se retornar false , 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. Esta API retorna um int , que é uma máscara de bits de todas as restrições atualmente em vigor. O conjunto de restrições notificadas atualmente está listado em CarUxRestrictions .

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

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

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

Estado de condução

CarDrivingStateManager apresenta o estado real de condução do veículo (Estacionado, Ocioso ou Em Movimento). As APIs CarDrivingStateManager podem ser chamadas de forma semelhante ao CarUxRestrictionsManager. Os aplicativos podem registrar um ouvinte ou obter o estado atual da direção. O estado de condução é retornado como CarDrivingStateEvent.

CarDrivingStateEvent .

alterações, o método onDrivingStateChanged() é 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 marcha e velocidade para alterar o estado de direção. Use um comando shell ADB para injetar eventos de veículo. Isso pode ser um desenvolvimento e teste úteis.

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 como Parked (para simular CarDrivingStateEvent apontando para PARKED):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 4
    
  3. Para colocar a marcha em 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