Bluetooth

Android menyediakan implementasi Bluetooth lengkap dengan dukungan untuk banyak profil Bluetooth umum di dalam mobil. Ada juga banyak peningkatan yang meningkatkan performa dan pengalaman dengan perangkat dan layanan lainnya.

Pengelolaan koneksi Bluetooth

Dalam Android, CarBluetoothService mempertahankan perangkat Bluetooth pengguna saat ini dan daftar prioritas untuk setiap koneksi profil ke IVI. Perangkat terhubung ke profil dalam urutan prioritas yang ditentukan. Waktu untuk mengaktifkan, menonaktifkan, dan menghubungkan perangkat ke profil ditentukan oleh kebijakan koneksi default yang dapat diganti dengan penggunaan overlay resource, jika diinginkan.

Mengonfigurasi pengelolaan koneksi otomotif

Menonaktifkan kebijakan telepon default

Stack Bluetooth Android mempertahankan kebijakan koneksi untuk ponsel yang diaktifkan secara default. Kebijakan ini harus dinonaktifkan di perangkat Anda agar tidak bertentangan dengan kebijakan otomotif yang diinginkan di CarBluetoothService. Meskipun overlay produk Mobil akan menanganinya untuk Anda, Anda dapat menonaktifkan kebijakan ponsel di overlay resource dengan menetapkan enable_phone_policy ke false di MAXIMUM_CONNECTED_DEVICES di /packages/apps/Bluetooth/res/values/config.xml.

Menggunakan kebijakan otomotif default

CarBluetoothService mempertahankan izin profil default. Daftar perangkat yang diketahui dan prioritas penyambungan ulang profilnya ada di service/src/com/android/car/BluetoothProfileDeviceManager.java.

Selain itu, kebijakan pengelolaan koneksi Bluetooth dapat ditemukan di service/src/com/android/car/BluetoothDeviceConnectionPolicy.java. Secara default, kebijakan ini menentukan instance saat Bluetooth harus terhubung ke dan terputus dari perangkat yang terikat. Fitur ini juga mengelola kasus khusus mobil untuk saat adaptor harus diaktifkan dan dinonaktifkan.

Membuat kebijakan pengelolaan koneksi otomotif kustom Anda sendiri

Jika kebijakan otomotif default tidak memadai untuk kebutuhan Anda, kebijakan tersebut juga dapat dinonaktifkan untuk mendukung kebijakan kustom Anda sendiri. Kebijakan kustom Anda, setidaknya, bertanggung jawab untuk menentukan kapan harus mengaktifkan dan menonaktifkan adaptor Bluetooth, serta kapan harus menghubungkan perangkat. Anda dapat menggunakan berbagai peristiwa untuk mengaktifkan/menonaktifkan adaptor Bluetooth dan memulai koneksi perangkat, termasuk peristiwa karena perubahan pada properti mobil tertentu.

Menonaktifkan kebijakan otomotif default

Pertama, untuk menggunakan kebijakan kustom, kebijakan otomotif default harus dinonaktifkan dengan menetapkan useDefaultBluetoothConnectionPolicy ke false di overlay resource. Resource ini awalnya ditentukan sebagai bagian dari MAXIMUM_CONNECTED_DEVICES di packages/services/Car/service/res/values/config.xml.

Mengaktifkan dan menonaktifkan adaptor Bluetooth

Salah satu fungsi inti kebijakan Anda adalah mengaktifkan dan menonaktifkan adaptor Bluetooth pada waktu yang tepat. Anda dapat menggunakan API framework BluetoothAdapter.enable() dan BluetoothAdapter.disable() untuk mengaktifkan dan menonaktifkan adaptor. Panggilan ini harus mematuhi status yang dipertahankan yang telah dipilih pengguna melalui Setelan atau cara lain. Salah satu cara untuk melakukannya adalah sebagai berikut:

/**
 * 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);
}

Menentukan kapan harus mengaktifkan dan menonaktifkan adaptor Bluetooth

Dengan kebijakan kustom, Anda bebas menentukan peristiwa mana yang menunjukkan waktu terbaik untuk mengaktifkan dan menonaktifkan adaptor. Salah satu cara untuk melakukannya adalah dengan menggunakan status daya MAXIMUM_CONNECTED_DEVICES di 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;
        }
    }
};

Menentukan kapan harus menghubungkan perangkat

Demikian pula, saat Anda menentukan peristiwa yang akan memicu koneksi perangkat untuk dimulai, CarBluetoothManager menyediakan panggilan API connectDevices() yang melanjutkan untuk menghubungkan perangkat berdasarkan daftar prioritas yang ditentukan untuk setiap profil Bluetooth.

Salah satu contoh saat Anda mungkin ingin melakukannya adalah setiap kali adaptor Bluetooth diaktifkan:

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();
            }
        }
    }
}

Memverifikasi pengelolaan koneksi otomotif

Cara termudah untuk memverifikasi perilaku kebijakan koneksi Anda adalah dengan mengaktifkan Bluetooth di IVI dan memvalidasi bahwa Bluetooth otomatis terhubung ke perangkat yang benar dalam urutan yang sesuai. Anda dapat mengalihkan adaptor Bluetooth melalui UI setelan, atau dengan perintah adb berikut:

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

Selain itu, output perintah berikut dapat digunakan untuk melihat informasi debug yang terkait dengan koneksi Bluetooth:

adb shell dumpsys car_service

Terakhir, jika Anda telah membuat kebijakan otomotif sendiri, memverifikasi perilaku koneksi kustom memerlukan kontrol peristiwa yang telah Anda pilih untuk memicu koneksi perangkat.

Profil Bluetooth otomotif

Di Android, IVI dapat mendukung beberapa perangkat yang terhubung secara bersamaan melalui Bluetooth. Layanan telepon Bluetooth multiperangkat memungkinkan pengguna menghubungkan perangkat terpisah secara serentak, seperti ponsel pribadi dan ponsel kerja, serta melakukan panggilan handsfree dari salah satu perangkat.

Batas koneksi diterapkan oleh setiap profil Bluetooth, biasanya dalam penerapan layanan profil itu sendiri. Secara default, CarBluetoothService tidak membuat penilaian lebih lanjut tentang jumlah maksimum perangkat yang terhubung yang diizinkan.

Profil Handsfree

Profil Handsfree Bluetooth (HFP) memungkinkan kendaraan melakukan dan menerima panggilan telepon melalui perangkat jarak jauh yang terhubung. Setiap koneksi perangkat mendaftarkan akun telepon terpisah dengan TelecomManager, yang mengiklankan akun telepon yang tersedia ke aplikasi IVI.

IVI dapat terhubung ke beberapa perangkat melalui HFP. MAX_STATE_MACHINES_POSSIBLE MAXIMUM_CONNECTED_DEVICES di HeadsetClientService menentukan jumlah maksimum koneksi HFP serentak.

Saat pengguna melakukan atau menerima panggilan telepon dari perangkat, akun telepon yang sesuai akan membuat objek HfpClientConnection. Aplikasi Telepon berinteraksi dengan objek HfpClientConnection untuk mengelola fitur panggilan, seperti menerima panggilan atau menutupnya.

Perlu diperhatikan bahwa aplikasi Telepon default tidak mendukung beberapa perangkat HFP yang terhubung secara bersamaan. Untuk menerapkan HFP multi-perangkat, penyesuaian diperlukan agar pengguna dapat memilih akun perangkat yang akan digunakan saat melakukan panggilan. Kemudian, aplikasi akan memanggil telecomManager.placeCall dengan akun yang benar. Anda juga harus memverifikasi bahwa fungsi multi-perangkat lainnya berfungsi sebagaimana mestinya.

Memverifikasi HFP multiperangkat

Untuk memeriksa apakah konektivitas multiperangkat berfungsi dengan benar melalui Bluetooth:

  1. Menggunakan Bluetooth, hubungkan perangkat ke IVI dan streaming audio dari perangkat.
  2. Hubungkan dua ponsel ke IVI melalui Bluetooth.
  3. Pilih satu ponsel. Melakukan panggilan keluar langsung dari ponsel, dan melakukan panggilan keluar menggunakan IVI.
    1. Pada kedua waktu tersebut, pastikan audio yang di-streaming dijeda dan audio ponsel diputar melalui speaker yang terhubung ke IVI.
  4. Menggunakan ponsel yang sama, terima panggilan masuk langsung di ponsel, dan terima panggilan masuk menggunakan IVI.
    1. Pada kedua waktu tersebut, pastikan audio streaming dijeda dan audio ponsel diputar melalui speaker yang terhubung ke IVI.
  5. Ulangi langkah 3 dan 4 dengan ponsel lain yang terhubung.

Panggilan darurat

Kemampuan untuk melakukan panggilan darurat adalah aspek penting dari fungsi telepon dan Bluetooth di mobil. Ada sejumlah cara untuk memulai panggilan darurat dari IVI, termasuk:

  • Solusi eCall mandiri
  • Solusi eCall yang terintegrasi ke dalam IVI
  • Mengandalkan ponsel Bluetooth yang terhubung saat tidak ada sistem bawaan yang tersedia

Menghubungkan panggilan darurat

Meskipun peralatan eCall sangat penting untuk keselamatan, saat ini peralatan tersebut tidak terintegrasi ke dalam Android. Anda dapat menggunakan ConnectionService untuk mengekspos fitur panggilan darurat melalui Android, yang juga memiliki manfaat untuk memperkenalkan opsi aksesibilitas untuk panggilan darurat. Untuk mempelajari lebih lanjut, lihat Mem-build aplikasi panggilan.

Berikut adalah contoh cara membuat ConnectionService darurat:

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);
    }
}

Mengaktifkan Bluetooth untuk panggilan darurat

Menelepon layanan darurat sebelum Android 10 melibatkan panggilan langsung dari ponsel dan memanggil peralatan khusus jika tersedia (misalnya, pemicu otomatis saat mendeteksi bahaya atau tindakan pengguna). Di Android 10 dan yang lebih baru, Telepon di mobil dapat langsung memanggil nomor darurat, dengan menyediakan MAXIMUM_CONNECTED_DEVICES ini di 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>

Dengan menerapkan panggilan darurat dengan cara ini, aplikasi lain, seperti pengenalan suara, juga dapat menelepon nomor darurat.

Profil Akses Buku Telepon

Profil Akses Buku Telepon Bluetooth (PBAP) mendownload kontak dan histori panggilan dari perangkat jarak jauh yang terhubung. PBAP mempertahankan daftar kontak gabungan yang dapat ditelusuri yang diperbarui oleh mesin status klien PBAP. Setiap perangkat yang terhubung berinteraksi dengan mesin status klien PBAP terpisah, sehingga kontak dikaitkan dengan perangkat yang tepat saat melakukan panggilan.

PBAP bersifat satu arah dan oleh karena itu memerlukan IVI untuk membuat instance koneksi ke MAXIMUM_CONNECTED_DEVICES di PbapClientService menentukan jumlah maksimum koneksi perangkat PBAP serentak yang diizinkan dengan IVI. Klien PBAP menyimpan kontak untuk setiap perangkat yang terhubung di Penyedia Kontak yang kemudian dapat diakses oleh aplikasi untuk mendapatkan buku telepon untuk setiap perangkat.

Selain itu, koneksi profil harus diotorisasi oleh IVI dan perangkat seluler agar koneksi dapat dibuat. Saat klien PBAP terputus, database internal akan menghapus semua kontak dan histori panggilan yang terkait dengan perangkat yang sebelumnya terhubung.

Profil Akses Pesan

Profil Akses Pesan (MAP) Bluetooth memungkinkan kendaraan mengirim dan menerima pesan SMS melalui perangkat jarak jauh yang terhubung. Saat ini, pesan tidak disimpan secara lokal di IVI. Sebagai gantinya, setiap kali perangkat jarak jauh yang terhubung menerima pesan, IVI akan menerima dan mengurai pesan serta menyiarkan kontennya dalam instance Intent, yang kemudian dapat diterima oleh aplikasi.

Untuk terhubung ke perangkat seluler guna mengirim dan menerima pesan, IVI harus memulai koneksi MAP. MAXIMUM_CONNECTED_DEVICES di MapClientService menentukan jumlah maksimum koneksi perangkat MAP serentak yang diizinkan dengan IVI. Setiap koneksi harus diotorisasi oleh IVI dan perangkat seluler sebelum pesan dapat ditransfer.

Advanced Audio Distribution Profile

Advanced Audio Distribution Profile (A2DP) Bluetooth memungkinkan kendaraan menerima streaming audio dari perangkat jarak jauh yang terhubung.

Tidak seperti profil lainnya, jumlah maksimum perangkat A2DP yang terhubung diterapkan di stack native, bukan di Java. Nilai saat ini di-hardcode ke 1 menggunakan variabel kDefaultMaxConnectedAudioDevices di packages/modules/Bluetooth/system/btif/src/btif_av.cc.

Audio/Video Remote Control Profile

Profil Remote Control Audio/Video Bluetooth (AVRCP) memungkinkan kendaraan mengontrol dan menjelajahi pemutar media di perangkat jarak jauh yang terhubung. Karena IVI berperan sebagai pengontrol AVRCP, setiap kontrol yang dipicu yang memengaruhi pemutaran audio mengandalkan koneksi A2DP ke perangkat target.

Agar pemutar media tertentu di ponsel Android dapat dijelajahi oleh IVI melalui AVRCP, aplikasi media di ponsel harus menyediakan MediaBrowserService dan mengizinkan akses com.android.bluetooth ke layanan tersebut. Membuat layanan browser media menjelaskan cara melakukannya secara mendetail.