Programmatically bonding to BLE device on Android
Asked Answered
W

3

6

I'm writing an Android application in which I'd like to programmatically bond to a custom BLE device. I have the manual bonding working in which the user enters the PIN using the standard Android Bluetooth pairing dialog, but I have not been able to find any information on how to automatically bond a BLE device programatically, without user intervention. Is that possible? If so, what's the process?

Weapon answered 6/8, 2015 at 14:42 Comment(0)
W
3

I was able to make this work MOST OF THE TIME by registering a BroadcastReceiver to receive the BluetoothDevice.ACTION_BOND_STATE_CHANGED intent and then calling BluetoothDevice.setPin after receiving the BluetoothDevice.BOND_BONDING message. As is the case with most BLE things in Android, this seems to act slightly differently depending on the device and Android version. Unfortunately, I can't seem to stop Android from also receiving the bluetooth intent, so the PIN entry screen still pops up for a second before the bonding is completed.

   private final BroadcastReceiver mReceiver = new BroadcastReceiver()
   {
       @Override
       public void onReceive(Context context, Intent intent)
       {
           final String action = intent.getAction();
           Logger("Broadcast Receiver:" + action);

           if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED))
           {
               final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);

               if(state == BluetoothDevice.BOND_BONDING)
               {
                   Logger("Bonding...");
                    if (mDevice != null) {
                        mDevice.setPin(BONDING_CODE.getBytes());
                        Logger("Setting bonding code = " + BONDING_CODE);
                    }
               }
               else if(state == BluetoothDevice.BOND_BONDED)
               {
                   Logger("Bonded!!!");
                   mOwner.unregisterReceiver(mReceiver);
               }
               else if(state == BluetoothDevice.BOND_NONE)
               {
                   Logger("Not Bonded");
               }
           }
       }
   };
Weapon answered 26/8, 2015 at 15:39 Comment(1)
Turns out you don't want ACTION_BOND_STATE_CHANGE. See my other answer.Precipitancy
P
3

I managed to do this - see my answer here.

The TL;DR is: forget about ACTION_BOND_STATE_CHANGED; you don't need it. Instead listen to ACTION_PAIRING_REQUEST, and set the priority high. In the broadcast receiver when you get ACTION_PAIRING_REQUEST, call setPin() with your PIN and then abortBroadcast() to prevent the system showing the notification.

Precipitancy answered 19/7, 2016 at 13:23 Comment(0)
D
-2

All you can do to avoid user interaction is to force Just Works pairing. To do that, program the peripheral to accept pairing with NoInputNoOutput IO Capability.

Drunkard answered 6/8, 2015 at 16:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.