Esta página explica como os apps podem fazer a transição para interfaces do usuário otimizadas para distração (DO, na sigla em inglês). Ele descreve como consumir o estado de direção de um carro, bem como as restrições de experiência do usuário correspondentes. Para mais informações sobre as restrições de experiência do usuário (UX) do carro, consulte Restrições de 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-alvo
Este conteúdo é fornecido para quem quer projetar apps que se adaptam a 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 (estacionada, em marcha lenta ou em movimento) é derivado dos valores do sensor fornecidos pela camada de abstração de hardware do veículo (VHAL, na sigla em inglês). Informações básicas do sensor, como a velocidade do veículo e a seleção de marcha atual, são usadas para derivar o estado de direção atual do veículo.
CarDrivingStateEvent
.
que fornece @SystemApis, o que significa que apenas plataformas internas, 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 direção android.car.permission.CAR_DRIVING_STATE
. Os clientes
que precisam de acesso às informações do estado de direção precisam solicitar essa permissão.
CarUxRestrictionsManager
Os apps que mostram uma interface do usuário dependente do estado de direção precisam detectar
CarUxRestrictionsManager
,
que abstrai o mapeamento do estado de direção para restrições de UX para que os apps não precisem
se ajustar a diferentes requisitos de segurança do mercado.
Observação: essas atividades precisam ser marcadas como otimizadas para distração, conforme descrito nas diretrizes de 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 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 abaixo ilustra como um app monitora as restrições de UX:
- Importe os pacotes da biblioteca de carros:
import android.car.Car; /* For CarUxRestrictions */ import android.car.drivingstate.CarUxRestrictions; import android.car.drivingstate.CarUxRestrictionsManager;
- Implemente
CarUxRestrictionManager.OnUxRestrictionsChangedListener
(mUxRChangeListener
). Esse listener, quando registrado com o CarUxRestrictionsManager, é chamado quando ocorre uma mudança nas restrições de UX. Processe 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); } };
- Chame as APIs do carro para criar uma instância de carro chamada mCar e se conectar ao serviço de carro:
mCar = Car.createCar(context); if (mCar == null) { // handle car connection error }
- Chame
mCar.getCarManager() - mCarUxRestrictionsManager
para receber oCarUxRestrictionsManager
:CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager) mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
- Para registrar
mUxRChangeListener
implementado na Etapa 2 acima com a chamadaCarUxRestrictionsManager
mCarUxRestrictionsManager.registerListener()
:mCarUxRestrictionsManager.registerListener(mUxrChangeListener); mUxrChangeListener.onUxRestrictionsChanged( mCarUxRestrictionsManager.getCurrentCarUxRestrictions());
O bloco de código de exemplo concluído (criado nas etapas 3 a 5) faz com que o listener receba mudanças de restrição quando o estado do drive 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:
- Há algum requisito atual para otimização de distrações?
- Em caso afirmativo, quais restrições estão em vigor?
Quando CarUxRestrictions é recebido de
getCurrentUxRestrictions()
ou do callback do listener, os apps agora podem usar
a API isRequiresDistractionOptimization()
para determinar se a otimização
de distração
é necessária. Se ele retornar false
, não há requisito para ser otimizado
para distração, e um app pode 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. Essa
API retorna um int, que é uma máscara de bits de todas as restrições em vigor. O
conjunto de restrições atualmente notificado está listado em CarUxRestrictions
.
Observação:mudanças menores no conjunto de restrições devem ocorrer em breve.
Por exemplo, se um app quiser determinar se existe uma restrição para reproduzir vídeos, ao receber o objeto CarUxRestrictions, ele precisará verificar a restrição:
int activeUxR = mCurrentCarUxRestrictions.getActiveRestrictions(); if ((activeUxR & CarUxRestrictions.UX_RESTRICTIONS_NO_VIDEO) != 0) { handleStopPlayingVideo(); }
DrivingState
O CarDrivingStateManager apresenta o estado de direção real do veículo (estacionado, em marcha lenta ou em movimento). As APIs CarDrivingStateManager podem ser chamadas de forma semelhante ao CarUxRestrictionsManager. Os apps podem registrar um listener ou receber o estado de direção atual. O estado de direção é retornado como CarDrivingStateEvent.
CarDrivingStateEvent
.
muda, 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 simular a mudança de marchas e a velocidade para mudar o estado de condução. Use um comando de shell do ADB para injetar eventos do veículo. Isso pode ser útil para desenvolvimento e testes.
Para simular eventos de direção:
- Para definir a velocidade como 0:
adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 0
- Para definir a marcha como "Estacionado" (para simular o CarDrivingStateEvent apontando para "PARKED"):
adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 4
- Para definir a engrenagem como "Drive", com a velocidade ainda em 0 (para simular o CarDrivingStateEvent apontando
para IDLING):
adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 8
- Para definir a velocidade em 30 metros por segundo (para simular o CarDrivingStateEvent apontando para MOVING):
adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30