Android – How to programmatically pair a bluetooth device on Android

androidbluetooth

For my application I'm trying to programmatically pair a bluetooth device. I'm able to show the pairing dialog for the device I want to pair and I can enter a pincode. When I press "Pair" the dialog is removed and nothing happens.

I only need to support devices with Android 2.0 and newer.

Currently I am using the following code to start the pairing progress:


public void pairDevice(BluetoothDevice device) {
        String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
        Intent intent = new Intent(ACTION_PAIRING_REQUEST);
        String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
        intent.putExtra(EXTRA_DEVICE, device);
        String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT";
        int PAIRING_VARIANT_PIN = 0;
        intent.putExtra(EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

Before starting a pairing request I stop scanning for new devices.

My application has the following bluetooth permissions:

  • android.permission.BLUETOOTH_ADMIN
  • android.permission.BLUETOOTH

Best Answer

I managed to auto request a pairing procedure with keyboard featured devices through an app working as a service checking the presence of a specific kind of device and a modified version of the Settings app.

I have to say that I was working on a custom device running Android 4.0.3 without external controls (no back/Home/confirm buttons): pairing a controller on boot complete without any interaction until PIN request was mandatory.

First I created a service starting an activity on boot (with android.intent.action.BOOT_COMPLETED and android.permission.RECEIVE_BOOT_COMPLETED) that checks periodically the presence of a 1344 class device (a keyboard, the only way to input data on request) on the onReceive callback:

public void onReceive(Context context, Intent intent) 
...
    BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
...
if(dev.getBluetoothClass().getDeviceClass() == 1344){...}

Once filtered I choose the first keyboard available and then I pass the BT address to the Settings app:

Intent btSettingsIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
btSettingsIntent.putExtra("btcontroller", dev.getAddress());
startActivityForResult(btSettingsIntent, 1);

The tricky part was looking for the best position to call the pairing process. Using only the

intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);

led me to a paring dialog that once closed left me with the device paired, but unusable.

Digging into the classes of com.Android.settings.Bluetooth I found my way through the

createDevicePreference(CachedBluetoothDevice cachedDevice) 

in the DeviceListPreferenceFragment.

From there I did compare my previously selected BT address with those available coming up and once successfully matched I call

cachedDevice.startPairing();

I know, it's tricky and requires access to the Android source code, but in a custom environment it works.

I hope this could be helpful.