Join us on the livestream at Android Dev Summit on 7-8 November 2018, starting at 10AM PDT!

Companion device pairing

On devices running Android 8.0 (API level 26) and higher, you can customize the pairing request dialog when trying to pair with companion devices over Bluetooth, BLE, and Wi-Fi.

In your app, you can specify whether users see a list of possible companion devices or only one suggestion for a companion device. You can also filter the items that appear in the pairing request dialog, such as by type (Bluetooth, BLE, and Wi-Fi) or by device name.

The following code snippet demonstrates how to display a dialog asking whether the user wants to pair a handheld device with a single, Bluetooth-connected companion device named "My device":

Kotlin

class MyDeviceSelectionActivity : Activity() {

    private val mDeviceManager: CompanionDeviceManager by lazy(LazyThreadSafetyMode.NONE) {
        getSystemService(CompanionDeviceManager::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...

        // To skip filtering based on name and supported feature flags (UUIDs),
        // don't include calls to setNamePattern() and addServiceUuid(),
        // respectively. This example uses Bluetooth.
        val deviceFilter: BluetoothDeviceFilter = BluetoothDeviceFilter.Builder()
                .setNamePattern(Pattern.compile("My device"))
                .addServiceUuid(ParcelUuid(UUID(0x123abcL, -1L)), null)
                .build()

        // The argument provided in setSingleDevice() determines whether a single
        // device name or a list of device names is presented to the user as
        // pairing options.
        val pairingRequest: AssociationRequest = AssociationRequest.Builder()
                .addDeviceFilter(deviceFilter)
                .setSingleDevice(true)
                .build()

        // When the app tries to pair with the Bluetooth device, show the
        // appropriate pairing request dialog to the user.
        mDeviceManager.associate(pairingRequest,
                object : CompanionDeviceManager.Callback() {

                    override fun onDeviceFound(chooserLauncher: IntentSender) {
                        startIntentSenderForResult(chooserLauncher,
                                SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0)
                    }

                    override fun onFailure(error: CharSequence?) {
                        // Handle failure
                    }
                }, null)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        when (requestCode) {
            SELECT_DEVICE_REQUEST_CODE -> when(resultCode) {
                Activity.RESULT_OK -> {
                    // User has chosen to pair with the Bluetooth device.
                    val deviceToPair: BluetoothDevice = 
                            data.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE)
                    deviceToPair.createBond()
                    // ... Continue interacting with the paired device.
                }
            }
        }
    }
}

Java

public class MyDeviceSelectionActivity extends Activity {
    private CompanionDeviceManager mDeviceManager;
    private AssociationRequest mPairingRequest;
    private BluetoothDeviceFilter mDeviceFilter;

    private static final int SELECT_DEVICE_REQUEST_CODE = 42;

    @override
    public void onCreate() {
        // ...
        mDeviceManager = getSystemService(CompanionDeviceManager.class);

        // To skip filtering based on name and supported feature flags (UUIDs),
        // don't include calls to setNamePattern() and addServiceUuid(),
        // respectively. This example uses Bluetooth.
        mDeviceFilter = new BluetoothDeviceFilter.Builder()
                .setNamePattern(Pattern.compile("My device"), null)
                .addServiceUuid(new ParcelUuid(new UUID(0x123abcL, -1L)))
                .build();

        // The argument provided in setSingleDevice() determines whether a single
        // device name or a list of device names is presented to the user as
        // pairing options.
        mPairingRequest = new AssociationRequest.Builder()
                .addDeviceFilter(mDeviceFilter)
                .setSingleDevice(true)
                .build();

        // When the app tries to pair with the Bluetooth device, show the
        // appropriate pairing request dialog to the user.
        mDeviceManager.associate(mPairingRequest,
                new CompanionDeviceManager.Callback() {
                    @Override
                    public void onDeviceFound(IntentSender chooserLauncher) {
                        startIntentSenderForResult(chooserLauncher,
                                SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0);
                    }
                },
                null);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == SELECT_DEVICE_REQUEST_CODE &&
                resultCode == Activity.RESULT_OK) {
            // User has chosen to pair with the Bluetooth device.
            BluetoothDevice deviceToPair =
                    data.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE);
            deviceToPair.createBond();

            // ... Continue interacting with the paired device.
        }
    }
}