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

Esta página explica como os apps podem fazer a transição tranquila para distrações do usuário otimizadas (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 saber mais sobre as restrições da experiência do usuário (UX) do carro, consulte Restrições de experiência do usuário de carro, que detalha os três estados de direção: estacionado, inativo e em movimento.

Público-alvo

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

Detalhes técnicos

CarDrivingStateManager

O estado de condução de um carro (Estacionado, inativo ou em movimento) é derivado dos valores do sensor fornecidos pelo a camada de abstração de hardware do veículo (VHAL, na sigla em inglês). Informações básicas do sensor, como velocidade do veículo e a seleção atual da marcha, é usada 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 em pacote (como SysUI ou Configurações) e os APKs privilegiados (como) do GMSCore podem acessar as APIs. As APIs são protegidas pela permissões específicas para o estado de direção android.car.permission.CAR_DRIVING_STATE. Clientes que precisam de acesso a informações sobre o estado de condução precisam solicitar essa permissão.

CarUxRestrictionsManager

Esses apps que exibem uma interface do usuário dependente do estado de condução precisam detectar CarUxRestrictionsManager, que abstrai o mapeamento do estado de condução para restrições de UX para que os apps não precisem se ajustar a diferentes requisitos de segurança de mercado.

Observação: essas atividades precisam ser marcadas como otimizados para distração, conforme descrito consulte as diretrizes para distração do motorista. Se as atividades não forem marcadas corretamente, elas serão bloqueadas.

Em vez disso, os apps monitoram as restrições expostas pelo CarUxRestrictionsManager, e não por um estado de direção absoluto exposto pelo CarDrivingStateManager para tudo relacionado ao usuário. ou na experiência do usuário.

Exemplo de código

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

  1. Importe os pacotes da biblioteca do carro:
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
    
  2. Implementar CarUxRestrictionManager.OnUxRestrictionsChangedListener mUxRChangeListener). Esse listener, quando registrado com o CarUxRestrictionsManager, é chamado quando uma mudança nas restrições de UX. de segurança. Faça as mudanças 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 de carro para criar uma instância de carro chamada mCar e se conectar ao serviço do carro:
    mCar = Car.createCar(context);
    if (mCar == null) {
    // handle car connection error
    }
    
  4. Chame mCar.getCarManager() - mCarUxRestrictionsManager para receber CarUxRestrictionsManager:
    CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
    mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
    
  5. Para registrar o mUxRChangeListener implementado na etapa 2 acima com o Chamada do CarUxRestrictionsManager para mCarUxRestrictionsManager.registerListener():
    mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
    mUxrChangeListener.onUxRestrictionsChanged(
    mCarUxRestrictionsManager.getCurrentCarUxRestrictions());
    

O bloco completo do exemplo de código (criado da Etapa 3 até a Etapa 5) resulta no listener de recebimento de mudanças 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 algum requisito atual para otimizar a distração?
  2. Em caso afirmativo, quais restrições estão em vigor atualmente?

Quando CarUxRestrictions é obtida de getCurrentUxRestrictions() ou o callback do listener, os apps agora podem usar a API isRequiresDistractionOptimization() para determinar se há distrações Otimizado é obrigatório. Se isso retornar false, não é necessário haver Distração. Otimizado para que um app possa executar qualquer atividade com segurança.

Se a otimização for necessária, use a API getActiveRestrictions() para receber o conjunto de restrições em vigor. Isso A API retorna um int, que é uma bitmask de todas as restrições em vigor no momento. A conjunto de restrições atualmente notificado está listado em CarUxRestrictions.

Observação:estima-se que pequenas mudanças no conjunto de restrições ocorrer em um futuro próximo.

Por exemplo, se um aplicativo deseja determinar se existe uma restrição para a reprodução de vídeos, obtendo o objeto CarUxRestrictions, o app precisa 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 direção do veículo (Estacionado, Inativo ou em movimento). As APIs CarDrivingStateManager podem ser chamadas de maneira semelhante à CarUxRestrictionsManager. Os apps podem registrar um listener ou receber o estado atual de direção. O estado de condução é retornado como CarDrivingStateEvent.

CarDrivingStateEvent.

mudar, o método onDrivingStateChanged() será chamado com a nova 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

É possível imitar a mudança de marcha e velocidade para mudar o estado de direção. Usar um shell ADB para injetar eventos do veículo. Isso pode ser útil durante o desenvolvimento e os testes.

Para simular eventos de direção:

  1. Para definir a velocidade como 0:
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 0
    
  2. Para definir o equipamento como "Estacionado" (para simular CarDrivingStateEvent apontando para ESTACIONADO):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 4
    
  3. Para definir a marcha como "Drive", com velocidade ainda em 0 (para simular o direcionamento de CarDrivingStateEvent para INÍCIO):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 8
    
  4. Para definir a velocidade como 30 metros por segundo (para simular CarDrivingStateEvent apontando para MOVING):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30