Bluetooth

O Android fornece uma conexão Bluetooth de código aberto com suporte a vários perfis Bluetooth comuns em veículos. Há também muitas melhorias que melhoram o desempenho e a experiência com outros dispositivos e serviços.

Gerenciamento de conexão Bluetooth

No Android, CarBluetoothService mantém os dispositivos Bluetooth do usuário atual e a prioridade listas para cada conexão de perfil ao IVI. Os dispositivos estão conectados a perfis em um ou em ordem de prioridade definida. Quando ativar, desativar e conectar dispositivos a um perfil por uma política de conexão padrão, que pode ser substituída com o uso de uma sobreposição de recurso, se quiser.

Configurar o gerenciamento de conexões automotivas

Desativar a política de telefone padrão

A pilha Bluetooth do Android mantém uma política de conexão para smartphones que é ativada pelo padrão. Esta política deve ser desativada no seu dispositivo para que não entre em conflito com o a política automotiva pretendida CarBluetoothService. Embora a sobreposição de produtos para carros cuide disso para você, você pode desativar a política de telefone em um sobreposição de recursos ao definir enable_phone_policy como false MAXIMUM_CONNECTED_DEVICES em /packages/apps/Bluetooth/res/values/config.xml.

Usar a política automotiva padrão

CarBluetoothService mantém as permissões de perfil padrão. A lista de objetos e as prioridades de reconexão de perfil service/src/com/android/car/BluetoothProfileDeviceManager.java:

A política de gerenciamento de conexão Bluetooth também pode ser encontrada em service/src/com/android/car/BluetoothDeviceConnectionPolicy.java. Por padrão, Esta política define instâncias em que o Bluetooth deve se conectar e desconectar da conexão dispositivos. Ele também gerencia casos específicos do carro em que o adaptador deve ser ativado e

Criar sua própria política personalizada de gerenciamento de conexões automotivas

Se a política automotiva padrão não for suficiente para suas necessidades, ela poderá ser desativada em favor de sua própria política personalizada. Sua política personalizada, no mínimo, é responsável para determinar quando ativar e desativar o adaptador Bluetooth e e conectar dispositivos. É possível utilizar diversos eventos para ativar/desativar o Bluetooth e para iniciar conexões de dispositivos, incluindo eventos devido a alterações em propriedades de carros.

Desativar a política automotiva padrão

Primeiro, para usar uma política automotiva personalizada, a política automotiva padrão deve ser desativada por definindo useDefaultBluetoothConnectionPolicy como false em uma de recursos. Esse recurso é definido originalmente como parte de MAXIMUM_CONNECTED_DEVICES em packages/services/Car/service/res/values/config.xml.

Ativar e desativar o adaptador Bluetooth

Uma das principais funções da sua política é ativar e desativar o adaptador Bluetooth em nos momentos apropriados. É possível usar as APIs BluetoothAdapter.enable() e APIs do framework BluetoothAdapter.disable() para ativar e desativar o adaptador. Essas chamadas devem respeitar o estado persistente selecionado pelo usuário em "Configurações" ou por outros meios. Uma maneira de fazer isso é:

/**
 * Turn on the Bluetooth adapter.
 */
private void enableBluetooth() {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (bluetoothAdapter == null) {
        return;
    }
    bluetoothAdapter.enable();
}

/**
 * Turn off the Bluetooth adapter.
 */
private void disableBluetooth() {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (bluetoothAdapter == null) {
        return;
    }
    // Will shut down _without_ persisting the off state as the desired state
    // of the Bluetooth adapter for next start up. This does nothing if the adapter
    // is already off, keeping the existing saved desired state for next reboot.
    bluetoothAdapter.disable(false);
}

Determinar quando ativar e desativar o adaptador Bluetooth

Com a política personalizada, você é livre para determinar quais eventos indicam os melhores horários para para ativar e desativar o adaptador. Uma maneira de fazer isso é usando os estados de potência MAXIMUM_CONNECTED_DEVICES pol. CarPowerManager:

private final CarPowerStateListenerWithCompletion mCarPowerStateListener =
        new CarPowerStateListenerWithCompletion() {
    @Override
    public void onStateChanged(int state, CompletableFuture<Void> future) {
        if (state == CarPowerManager.CarPowerStateListener.ON) {
            if (isBluetoothPersistedOn()) {
                enableBluetooth();
            }
            return;
        }

        // "Shutdown Prepare" is when the user perceives the car as off
        // This is a good time to turn off Bluetooth
        if (state == CarPowerManager.CarPowerStateListener.SHUTDOWN_PREPARE) {
            disableBluetooth();

            // Let CarPowerManagerService know we're ready to shut down
            if (future != null) {
                future.complete(null);
            }
            return;
        }
    }
};

Determinar quando conectar dispositivos

Da mesma forma, ao determinar os eventos que acionam conexões de dispositivos para começar, O CarBluetoothManager fornece a chamada de API connectDevices() que conecta os dispositivos com base nas listas de prioridade definidas para cada perfil Bluetooth.

Um exemplo de quando você pode querer fazer isso é sempre que o adaptador Bluetooth for ativado:

private class BluetoothBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            if (state == BluetoothAdapter.STATE_ON) {
                // mContext should be your app's context
                Car car = Car.createCar(mContext);
                CarBluetoothManager carBluetoothManager =
                        (CarBluetoothManager) car.getCarManager(Car.BLUETOOTH_SERVICE);
                carBluetoothManager.connectDevices();
            }
        }
    }
}

Verificar o gerenciamento de conexões automotivas

A maneira mais fácil de verificar o comportamento da sua política de conexão é ativar o Bluetooth seu IVI e confirmar que ele se conecta automaticamente aos dispositivos corretos no ordem apropriada. É possível alternar o adaptador Bluetooth pela interface de configurações ou estes comandos adb:

adb shell su u$(adb shell am get-current-user)_system svc bluetooth disable
adb shell su u$(adb shell am get-current-user)_system svc bluetooth enable

Além disso, a saída do comando a seguir pode ser usada para ver informações de depuração relacionadas às conexões Bluetooth:

adb shell dumpsys car_service

Por fim, se você criou sua própria política automotiva, verificar qualquer conexão personalizada requer o controle dos eventos que você escolheu para acionar o dispositivo conexões de rede.

Perfis Bluetooth automotivos

No Android, o IVI pode oferecer suporte a vários dispositivos conectados simultaneamente por Bluetooth. Os serviços de telefonia Bluetooth multidispositivo permitem que os usuários se conectem separar dispositivos ao mesmo tempo, como um telefone pessoal e um telefone de trabalho, e fazer chamadas por viva-voz de qualquer um dos dispositivos.

Os limites de conexão são aplicados por cada perfil Bluetooth individual, geralmente dentro do implementação do próprio serviço de perfil. Por padrão, CarBluetoothService não julgará o número máximo de dispositivos permitidos.

Perfil de viva-voz

O perfil de viva-voz (HFP, na sigla em inglês) Bluetooth permite que o veículo faça e receba por um dispositivo remoto conectado. Cada conexão de dispositivo registra um smartphone separado conta com TelecomManager, que anuncia todas as contas de telefone disponíveis para os apps IVI.

O IVI pode se conectar a vários dispositivos via HFP. MAX_STATE_MACHINES_POSSIBLE MAXIMUM_CONNECTED_DEVICES em HeadsetClientService define o número máximo de HFP simultâneos conexões de rede.

Quando um usuário faz ou recebe uma chamada telefônica de um dispositivo, o a conta do smartphone cria um objeto HfpClientConnection. O aplicativo Telefone interage com o objeto HfpClientConnection para gerenciar a chamada como aceitar uma chamada ou desligar.

O aplicativo Telefone padrão não oferece suporte a várias chamadas dispositivos HFP conectados. Para implementar o HFP em vários dispositivos, a personalização é necessária. para permitir que os usuários selecionem a conta do dispositivo que será usada ao fazer uma chamada. Em seguida, o app chama telecomManager.placeCall com a conta correta. Você precisa verificar se outras funcionalidades para vários dispositivos também funcionam conforme o esperado.

Verificar o HFP em vários dispositivos

Para verificar se a conectividade com vários dispositivos funciona corretamente por Bluetooth:

  1. Usando Bluetooth, conecte um dispositivo ao IVI e transmita áudio do dispositivo.
  2. Conecte dois smartphones ao IVI por Bluetooth.
  3. Escolha um smartphone. Faça uma chamada diretamente do telefone. e faça uma chamada usando o IVI.
    1. Nas duas vezes, verifique se o áudio de stream é pausado e o áudio do telefone é reproduzido nos alto-falantes IVI conectados.
  4. Usando o mesmo telefone, receber uma chamada diretamente no telefone e receber uma ligação usando o IVI.
    1. Nos dois momentos, verifique se o streaming de áudio é pausado e se o áudio do smartphone toca nos alto-falantes conectados ao IVI.
  5. Repita as etapas 3 e 4 com o outro smartphone conectado.

Chamadas de emergência

A capacidade de fazer chamadas de emergência é um aspecto importante da telefonia e Funções do Bluetooth no carro. Uma chamada de emergência pode ser iniciados a partir do IVI, incluindo:

  • Solução de chamada eletrônica independente
  • Solução de chamada eletrônica integrada ao IVI
  • Usar um telefone Bluetooth conectado quando nenhum sistema integrado estiver disponível

Conectar uma chamada de emergência

Embora o equipamento de chamada eletrônica seja essencial para a segurança, ele não está integrado ao Android no momento. É possível usar ConnectionService para expor recursos de chamada de emergência pelo Android, que também tem a vantagem de introduzir opções de acessibilidade para chamadas de emergência. Para saber mais, consulte Como criar um app de chamadas.

Este é um exemplo de como estabelecer uma emergência ConnectionService:

public class YourEmergencyConnectionService extends ConnectionService {

    @Override
    public Connection onCreateOutgoingConnection(
            PhoneAccountHandle connectionManagerAccount,
            ConnectionRequest request) {
        // Your equipment specific procedure to make ecall
        // ...
    }

    private void onYourEcallEquipmentReady() {

        PhoneAccountHandle handle =
            new PhoneAccountHandle(new ComponentName(context, YourEmergencyConnectionService),
                    YourEmergencyConnectionId);
        PhoneAccount account =
            new PhoneAccount.Builder(handle, eCallOnlyAccount)
            .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL))
            .setCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS
                    | PhoneAccount.CAPABILITY_MULTI_USER)
            .build():
        mTelecomManager.registerPhoneAccount(account);
        mTelecomManager.enablePhoneAccount(account.getAccountHandle(), true);
    }
}

Ativar o Bluetooth para chamadas de emergência

Ligar para a emergência antes do Android 10 envolvia discagem direta de um telefone e invocação equipamento especial, se disponível (por exemplo, acionamento automático após detecção de perigo ou ação do usuário). No Android 10 e versões mais recentes, o Telefone no carro pode chamar diretamente um número de emergência, desde que este MAXIMUM_CONNECTED_DEVICES em apps/Bluetooth/res/values/config.xml:

<!-- For supporting emergency call through the hfp client connection service --> <bool name=”hfp_client_connection_service_support_emergency_call”>true</bool>

Ao implementar a chamada de emergência dessa forma, outros aplicativos, como o reconhecimento de voz, podem ligar para um número de emergência.

Perfil de acesso à agenda de contatos

O Perfil de acesso à agenda de contatos (PBAP, na sigla em inglês) Bluetooth faz o download de contatos e históricos de ligações de um dispositivo remoto conectado. O PBAP mantém uma lista agregada e pesquisável de contatos atualizados pela máquina de estado do cliente PBAP. Cada dispositivo conectado interage com uma máquina de estado do cliente PBAP separada, resultando na associada ao dispositivo correto ao fazer uma chamada.

O PBAP é unidirecional e, portanto, exige que o IVI instancie conexões com qualquer MAXIMUM_CONNECTED_DEVICES pol. PbapClientService define o número máximo de dispositivos PBAP simultâneos conexões permitidas com o IVI. O cliente PBAP armazena os contatos de cada dispositivo conectado na Provedor de contatos, que pode ser acessado por um app para derivar o smartphone livro para cada dispositivo.

Além disso, a conexão do perfil deve ser autorizada pelo IVI e pelo dispositivo móvel para que a conexão seja feita. Quando um cliente PBAP se desconecta, o banco de dados interno remove todos os contatos e o histórico de chamadas associados à do dispositivo conectado anteriormente.

Perfil de acesso a mensagens

O perfil de acesso a mensagens por Bluetooth (MAP) permite que o veículo envie e receba SMS mensagens por um dispositivo remoto conectado. No momento, as mensagens não são armazenadas do IVI. Em vez disso, sempre que o dispositivo remoto conectado receber uma mensagem, o IVI recebe e analisa a mensagem e transmite o conteúdo dela em um Intent, que podem ser recebidas por um app.

Para se conectar a um dispositivo móvel para enviar e receber o IVI precisa iniciar a conexão MAP. MAXIMUM_CONNECTED_DEVICES em MapClientService define o número máximo de dispositivos MAP simultâneos conexões permitidas com o IVI. Cada conexão deve ser autorizada pelo IVI e pelo no dispositivo móvel antes de transferir as mensagens.

Perfil avançado de distribuição de áudio

O perfil de distribuição de áudio avançado (A2DP, na sigla em inglês) do Bluetooth permite que o veículo receba streams de áudio de um dispositivo remoto conectado.

Ao contrário de outros perfis, o número máximo de dispositivos A2DP conectados é aplicado no uma pilha nativa e não em Java. No momento, o valor está fixado no código de 1 usando a variável kDefaultMaxConnectedAudioDevices na packages/modules/Bluetooth/system/btif/src/btif_av.cc

Perfil de controle remoto de áudio/vídeo

O perfil de controle remoto de áudio/vídeo Bluetooth (AVRCP, na sigla em inglês) permite que o veículo controle e navegar por players de mídia em um dispositivo remoto conectado. Como o IVI desempenha o papel de um controlador AVRCP, qualquer controle acionado que afete a reprodução de áudio depende de um A2DP ao dispositivo de destino.

Para que um player de mídia específico em um smartphone Android possa ser visualizado pelo IVI via AVRCP, o app de música do telefone deve fornecer uma MediaBrowserService e permitir o acesso de com.android.bluetooth a esse serviço. Como criar um serviço de navegador de mídia explica como fazer isso em detalhes.