- Status: Fixed
- Priority: Normal
- Resolution: Fixed
- Platform: Android
- Affects version: 1.18.12.0
Delphi 12.3, компонент BluetoothLE1. Работаю с устройством по BLE.
1. Обнаруживаю доступные устройства, 2. Подключаюсь к сервисам устройства, 3. Получаю характеристики, 4. Подписываюсь на характеристику для чтения.
5. Пишу команду в характеристику для записи, ответ от устройства в событии "OnCharacteristicRead" не приходит.
Делал по стандартному FMX примеру "HeartRateMonitor". Работает.
Создал новый проект на FGX 1.18.11.0, разместил компонент BluetoothLE1. Устройство обнаруживается, сервисы, характеристики доступны,
подписка на характеристику для чтения проходит с результатом True. Но вот когда идёт передача от устройства, событие "OnCharacteristicRead" не срабатывает.
Подключены System.Bluetooth, System.Bluetooth.Components. Пробовал добавлять заголовочный файл Android.Api.Hardware.Bluetooth.
Что можно попробовать ещё, RTL, мосты?
FGX проект:
unit Form.Main; interface {$SCOPEDENUMS ON} uses System.Types, System.Classes, FGX.Forms, FGX.Forms.Types, FGX.Controls, FGX.Controls.Types, FGX.Layout, FGX.Layout.Types, FGX.NavigationBar.Types, FGX.NavigationBar, FGX.DrawerLayout, FGX.StaticLabel, System.Bluetooth, System.Bluetooth.Components, System.Permissions, FGX.Button.Types, FGX.Button, FGX.Switch; type TFormMain = class(TfgForm) fgDrawerLayout1: TfgDrawerLayout; fgNavigationBar: TfgNavigationBar; fgLabel2: TfgLabel; BluetoothLE1: TBluetoothLE; btDevices: TfgButton; loDevice: TfgLayout; loDeviceName: TfgLayout; lbDeviceName: TfgLabel; loDeviceSwitch: TfgLayout; fgSwitch: TfgSwitch; fgSend: TfgButton; procedure btDevicesTap(Sender: TObject); procedure BluetoothLE1EndDiscoverDevices(const Sender: TObject; const ADeviceList: TBluetoothLEDeviceList); procedure fgSendTap(Sender: TObject); procedure BluetoothLE1CharacteristicWrite(const Sender: TObject; const ACharacteristic: TBluetoothGattCharacteristic; AGattStatus: TBluetoothGattStatus); procedure BluetoothLE1CharacteristicRead(const Sender: TObject; const ACharacteristic: TBluetoothGattCharacteristic; AGattStatus: TBluetoothGattStatus); private const LOCATION_PERMISSION = 'android.permission.ACCESS_FINE_LOCATION'; BLUETOOTH_SCAN_PERMISSION = 'android.permission.BLUETOOTH_SCAN'; BLUETOOTH_CONNECT_PERMISSION = 'android.permission.BLUETOOTH_CONNECT'; private { Private declarations } FBLEDevice: TBluetoothLEDevice; FGattService: TBluetoothGattService; FCharacteristic_UUID_RX: TBluetoothGattCharacteristic; FCharacteristic_UUID_TX: TBluetoothGattCharacteristic; procedure GetServiceAndCharacteristics; public { Public declarations } end; const SERVICE_UUID : TGUID = '{6E400001-B5A3-F393-E0A9-E50E24DCCA9E}'; { UUID для BLE } CHARACTERISTIC_UUID_TX : TGUID = '{6E400003-B5A3-F393-E0A9-E50E24DCCA9E}'; CHARACTERISTIC_UUID_RX : TGUID = '{6E400002-B5A3-F393-E0A9-E50E24DCCA9E}'; var FormMain: TFormMain; implementation {$R *.xfm} uses System.SysUtils, FGX.Application, FGX.Dialogs, FGX.Toasts, FGX.Log, Android.Api.Hardware.Bluetooth; {******************************************************************************} procedure TFormMain.btDevicesTap(Sender: TObject); var Permissions: TArray<string>; begin if TOSVersion.Check(12) then Permissions := [LOCATION_PERMISSION, BLUETOOTH_SCAN_PERMISSION, BLUETOOTH_CONNECT_PERMISSION] else Permissions := [LOCATION_PERMISSION]; PermissionsService.RequestPermissions(Permissions, procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray) begin if ((Length(AGrantResults) = 3) and (AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted) and (AGrantResults[2] = TPermissionStatus.Granted)) or ((Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted)) then BluetoothLE1.DiscoverDevices(2500) { Запускаем поиск устройств } else TfgDialogs.ShowMessage('Cannot start BLE scan because not all required permissions have been granted!'); end); end; {******************************************************************************} procedure TFormMain.BluetoothLE1EndDiscoverDevices(const Sender: TObject; const ADeviceList: TBluetoothLEDeviceList); var i: Integer; begin for i := 0 to ADeviceList.Count - 1 do if Pos('CLMASTER', ADeviceList[i].DeviceName) > 0 then begin lbDeviceName.Text := ADeviceList[i].DeviceName; { Отображаем Имя устройства } fgSwitch.Visible := True; FBLEDevice := BluetoothLE1.DiscoveredDevices[I]; FBLEDevice.Connect; FBLEDevice.DiscoverServices; if BluetoothLE1.GetServices(FBLEDevice).Count = 0 then TfgToastFactory.Show('No services found!') else GetServiceAndCharacteristics; end; end; {******************************************************************************} procedure TFormMain.GetServiceAndCharacteristics; var i, j, k: Integer; begin for i := 0 to FBLEDevice.Services.Count - 1 do begin fgNavigationBar.Title := FBLEDevice.Services[I].UUIDName + ' : ' + FBLEDevice.Services[I].UUID.ToString; for j := 0 to FBLEDevice.Services[I].Characteristics.Count - 1 do begin fgNavigationBar.Title := '--> ' + FBLEDevice.Services[I].Characteristics[J].UUIDName + ' : ' + FBLEDevice.Services[I].Characteristics[J].UUID.ToString; for k := 0 to FBLEDevice.Services[I].Characteristics[J].Descriptors.Count - 1 do begin fgNavigationBar.Title := '----> ' + FBLEDevice.Services[I].Characteristics[J].Descriptors[K].UUIDName + ' : ' + FBLEDevice.Services[I].Characteristics[J].Descriptors[K].UUID.ToString; end; end; end; FGattService := nil; FCharacteristic_UUID_RX := nil; FCharacteristic_UUID_TX := nil; FGattService := BluetoothLE1.GetService(FBLEDevice, SERVICE_UUID); if FGattService <> nil then begin FCharacteristic_UUID_TX := BluetoothLE1.GetCharacteristic(FGattService, CHARACTERISTIC_UUID_TX); FCharacteristic_UUID_RX := BluetoothLE1.GetCharacteristic(FGattService, CHARACTERISTIC_UUID_RX); fgSwitch.Enabled := True; fgSwitch.IsChecked := True; end else TfgToastFactory.Show('Service not found!'); if FCharacteristic_UUID_TX <> nil then begin if BluetoothLE1.SubscribeToCharacteristic(FBLEDevice, FCharacteristic_UUID_TX) = True then fgNavigationBar.Title := 'Подписались UUID_TX' end; end; {******************************************************************************} procedure TFormMain.fgSendTap(Sender: TObject); var LBytes : TArray<byte>; begin { $ C I R } LBytes := TArray<byte>.Create($24, $43, $49, $52, $0D, $0A); BluetoothLE1.GetCharacteristic(FGattService, Characteristic_UUID_RX).SetValueAsString(TEncoding.ANSI.GetString(LBytes)); FBLEDevice.WriteCharacteristic(BluetoothLE1.GetCharacteristic(FGattService, Characteristic_UUID_RX)); end; {******************************************************************************} procedure TFormMain.BluetoothLE1CharacteristicWrite(const Sender: TObject; const ACharacteristic: TBluetoothGattCharacteristic; AGattStatus: TBluetoothGattStatus); begin if FBLEDevice.RequestMtu(517) = True then fgNavigationBar.Title := 'RequestMtu = 517'; end; {******************************************************************************} procedure TFormMain.BluetoothLE1CharacteristicRead(const Sender: TObject; const ACharacteristic: TBluetoothGattCharacteristic; AGattStatus: TBluetoothGattStatus); begin fgNavigationBar.Title := 'Read!!!'; if AGattStatus = TBluetoothGattStatus.Success then fgNavigationBar.Title := 'Read Success!!!'; end; {******************************************************************************} end.
Работающий пример на FMX:
Recommended Comments
Create an account or sign in to comment