Jump to content
Sign in to follow this  
PDJ

TBluetoothLEDevice.Paired always false

Recommended Posts

Hello,

 

I have written an app for Android using Bluetooth LE to communicate with a ESP32.

Everything works fine, I have set up an encrypted BLE connection, I can send and receive data, however

TBluetoothLEDevice.Paired is always false, even after a successful pair it's still false, I need this because I want to write something after the application has been started, for a bonded device, I can send it right away after subscription to the Characteristic service, but if the device has not been paired, Android wants to pair first and the app is sending unencrypted data to the other device and gets ignored.

 

Here some parts of the code

procedure TMyForm.Button1Click(Sender: TObject);
var
  ABLEAdvertisedDataFilter: TBluetoothLEScanFilter;
  ABLEAdvertisedDataFilterList: TBluetoothLEScanFilterList;
const
permBatt = 'android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS';
permRead = 'android.permission.READ_EXTERNAL_STORAGE';
permWrite = 'android.permission.WRITE_EXTERNAL_STORAGE';
permBlue  = 'android.permission.BLUETOOTH';
permAccess = 'android.permission.ACCESS_FINE_LOCATION';
permCoarse = 'android.permission.ACCESS_COARSE_LOCATION';
begin
  {$IFDEF ANDROID}
   PermissionsService.RequestPermissions([permBatt,permRead, permWrite, permBlue, permAccess, permCoarse],
    procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray)
    begin
		// Some code to do for permissions
	end);
  {$ENDIF}
  ABLEAdvertisedDataFilter:= TBluetoothLEScanFilter.Create;
  ABLEAdvertisedDataFilterList:= TBluetoothLEScanFilterList.Create;
  ABLEAdvertisedDataFilter.ServiceUUID:= MyBLEServiceID;
  ABLEAdvertisedDataFilterList.Add(ABLEAdvertisedDataFilter);

  //ListBox1.Items.Add('Start Discover');
  BluetoothLE1.DiscoverDevices(2000,ABLEAdvertisedDataFilterList);
end;


procedure TMyForm.BluetoothLE1EndDiscoverDevices(const Sender: TObject;
  const ADeviceList: TBluetoothLEDeviceList);
begin
  if ADeviceList.Count > 0 then
  begin
    CaravanBT := BluetoothLE1.DiscoveredDevices.First;
    CaravanBT.Connect;
  end;
end;

procedure TTabbedForm.BluetoothLE1Connect(Sender: TObject);
begin
  BTConnectServices;
end;

procedure TMyForm.CaravanBTConnectServices();
begin
  CaravanBT.DiscoverServices;
  if BluetoothLE1.GetServices(CaravanBT).Count > 0 then
  begin
    CaravanBTGatt := nil;
    CaravanBTGattCharact := nil;
    CaravanBTGatt := BluetoothLE1.GetService(CaravanBT,CaravanBLEServiceID);
    if CaravanBTGatt <> nil then
    begin
      // got the service
      CaravanBTGatt.Characteristics;
      CaravanBTGattCharact := BluetoothLE1.GetCharacteristic(CaravanBTGatt,CaravanBLECHarID);
      if CaravanBTGattCharact <> nil then
      begin
        BluetoothLE1.SubscribeToCharacteristic(CaravanBT, CaravanBTGattCharact);
        BTFullyConnected := True;
		// HERE I CAN SEND SOME DATA, BUT ONLY WHEN THE DEVICE HAS BEEN BONDED
		BTSendTimer.Enabled := True;
      end;
    end
    else
    begin
      // No services found
      {$IFDEF ANDROID}
      Toast('No services found',2000);
      {$ENDIF}
    end;
  end;
end;

procedure TMyForm.BTSendTimerTimer(Sender: TObject);
begin
  if (CaravanBT.Paired = true) then
  begin
    BTSendTimer.Enabled := False;
    // SEND SOMETHING
  end
  else
  begin
    // Not Paired
	// ALWAYS
  end;

end;

 

 

Share this post


Link to post

Maybe adding

'android.permission.BLUETOOTH_ADMIN';

makes any difference for you.

 

Not sure how Pairing and Bonding differ in detail, and can be used under Delphi.

Do you have any simple example code of what you want to achieve in Java (Android) / Objective-C (iOS) ?

Maybe its possible to add and implement that in Delphi too

In the code above you don't do anything "bonding special", I would say.

 

https://medium.com/@martijn.van.welie/making-android-ble-work-part-4-72a0b85cb442

https://www.kynetics.com/docs/2018/BLE_Pairing_and_bonding/

 

Quote

Pairing: process where devices exchange the information necessary to establish an encrypted connection. It involves authenticating the identity of the two devices to be paired, encrypting the link, and distributing keys to allow security to be restarted on a reconnection.

 

Bonding: process where the information from the pairing process is stored on the devices, so that the pairing process does not have to be repeated every time the devices reconnect to each other.

 

 

 

 

 

Share this post


Link to post

Thank you for the reply.

This is the Delphi code that runs on Android.

Pairing and bonding works fine, on both ends (Android and ESP32) , I can send data back and forth, but on the Android side

CaravanBT.Paired

 stay false, even after a successful pairing.

 

P.S. Adding

 

android.permission.BLUETOOTH_ADMIN

 

did not help

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×