(My apologies for this lengthy entry)
I have had some problems getting BLE to work according to my needs on both iOS and Android, but after some work arounds (see my comment and issues on quality.embarcadero.com: RSP 16891, 17763, and 17764) things have worked quite well (although BLE on iOS seems more stable than on Android).
Having switched to Tokyo, However, I have had to revise my handling of BLE device discovery, and I wonder if anyone else has noticed this change, if my original way of handling things (which was convenient) was fundamentally wrong, and/or if the behavior on Tokyo is as intended and by design or a bug.
In my application, I often need to "rediscover" a BLE device that was "defined" a long time ago (often in a previous app session). I handle this by storing the device name and MAC address so that I quickly can run discovery using a TBluetoothLEScanFilterList with the proper LocalName and DeviceAddress at some later point in time when I need to communicate with the device.
Using Berlin, I simply used a procedure like InitializeMyDevice below where BluetoothLE1 is a TBluetoothLE, FMyBleDevice is a TBluetoothLEDevice, and BluetoothLE1 has an OnDiscoverLEDevice = BluetoothLE1DiscoverLEDevice. Everything works fine: if the device is found, descovery stops immediately; if not, discovery times out.
Using Tokyo, however, the same code doesn't work:
1. during Application.ProcessMessages the bleMainDiscoverLEDeviceis never called and the discovery always times out;
2. after timeout and exit of InitializeMyDevice all calls to bleMainDiscoverLEDeviceis do occur, but this is "too late".
Of course, this issue can be circumvented using, e.g., a second procedure to capture the result, but the "Berlin" method was quite simple and convenient.
So, hopefully some of you can have a look at the code below and explain to me what's going on!
Thanks in advance /Per
Code:
procedure BluetoothLE1DiscoverLEDevice(...)
begin
// Double check
if ((ADevice.DeviceName = MyDeviceName) and (ADevice.Address = MyMacAddress)) then
begin
FMyBleDevice := ADevice;
BluetoothLE1.CancelDiscovery;
end;
end;
function InitializeMyDevice: Boolean;
var
LBleFilterList: TBluetoothLEScanFilterList;
LBleFilter: TBluetoothLEScanFilter;
begin
LBleFilterList := TBluetoothLEScanFilterList.Create;
LBleScanFilter := TBluetoothLEScanFilter.Create;
LBleScanFilter.LocalName := MyDeviceName;
LBleScanFilterList.Add(LBleScanFilter);
LBleScanFilter.DeviceAddress := MyMacAddress;
LBleScanFilterList.Add(LBleScanFilter);
try
FMyBleDevice := nil;
BluetoothLE1.DiscoverDevices(3000, LBleScanFilterList);
while (FMyBleDevice = nil) do
Application.ProcessMessages;
Result := (FMyBleDevice = nil);
finally
LBleScanFilterList.Free;
end;
end;