моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Для разработки BLE в Delphi перетащите TBlueToothLe на интерфейс и используйте этот элемент управления для разработки BLE, например для подключения браслета Bluetooth.
В демо-версии Delphi есть программа BLEScanner, которую можно использовать в качестве отправной точки для разработки.
Если вышеуказанная программа выполняется под Windows, то после сканирования устройства, если щелкнуть мышью по устройству, интерфейс может зависнуть и программа не будет реагировать. Если посмотреть на область управления задачами, то действительно, программа не отвечает и вышла из строя.
Щелкните мышью, чтобы сканировать службы выбранного устройства. Затем, когда службы устройства обнаруживаются, запускается событие OnServicesDiscovered TBluetoothLE. В этом случае несколько служб устройства считываются в цикле, а затем для определенной службы в цикле считывается ее имя символа. Сбой происходит там, где цикл читает символ.
Почему он разбился, я не знаю. Но я нашел решение, код такой:
- procedure TForm6.BluetoothLE1ServicesDiscovered(const Sender: TObject; const AServiceList: TBluetoothGattServiceList);
- var
- ServiceIndex: Integer;
- Service: TBluetoothGattService;
- CharacteristicIndex: Integer;
- Characteristic: TBluetoothGattCharacteristic;
- begin
- //以下代码如果不包到 TTask.Run 里面(原本的代码没有),在 WINDOWS 底下,执行到 for
- //CharacteristicIndex := 0 to Service.Characteristics.Count 会界面冻结,而且单步跟踪也停止
- //了,没有往下执行。
- TTask.Run(
- procedure
- var
- ServiceIndex: Integer;
- CharacteristicIndex: Integer;
- begin
- if AServiceList.Count > 0 then
- begin
- for ServiceIndex := 0 to AServiceList.Count - 1 do
- begin
- Service := AServiceList[ServiceIndex];
-
- TThread.Synchronize(nil,
- procedure
- begin
- Listbox2.Items.Add((ServiceIndex + 1).ToString + ' - ' + Service.UUIDName + ' - ' + Service.UUID.ToString);
- end
- );
-
-
- //以下代码会导致死机,如果断点跟踪,直接就是停在 for 这一行,不会继续往下执行。
- for CharacteristicIndex := 0 to Service.Characteristics.Count - 1 do
- begin
- Characteristic := Service.Characteristics[CharacteristicIndex];
-
- TThread.Synchronize(nil,
- procedure
- begin
- Listbox2.Items.Add(' - ' + Characteristic.UUIDName + ' - ' + Characteristic.UUID.ToString);
- end
- );
-
- end;
-
- end;
- end
- else
- TThread.Synchronize(nil,
- procedure
- begin
- Listbox2.Items.Add('- Access not allowed or no service available');
- end
- );
-
- end
- );
-
- //Listbox1.Enabled := True;
- end;
В приведенном выше коде TTask.Run был добавлен мной. TThread.Synchronize также был добавлен мной. Удалите TTask.Run и TThread.Synchronize, а оставшийся код — это исходный код демо-версии, поставляемой с Delphi.
Сначала поместите исходный код в TTask.Run, что означает помещение этих кодов в поток для выполнения. Вместо того, чтобы позволить выполнить поток, который первоначально вызвал событие OnServicesDiscovered. Возможная причина: поток, вызвавший OnServicesDiscovered, не может выполнить слишком много трудоемких задач.
Код выполняется в потоке. Когда вам нужно записать данные в элемент управления интерфейсом, например код Listbox2.Items.Add, вам необходимо выполнить синхронизацию потока. Поэтому добавьте TThread.Synchronize.
моя среда разработки
В разных средах явления могут быть разными. Итак, вот моя среда разработки:
Delphi 11 Community Edition;
Windows 11 Домашняя версия;
Целевая программа, которую необходимо скомпилировать и запустить, — это версия Win32.
Не существует проверки того, будут ли в этой демо-версии вышеуказанные проблемы под Android. Но я считаю, что под Android лучше будет добавить TTask.Run.
Упомянутая здесь демо-версия, после установки Delphi, если она установлена по умолчанию, демо-программа:
C:UsersPublicDocumentsEmbarcaderoStudio22.0SamplesObject PascalMulti-Device SamplesDevice Sensors and ServicesBluetoothBLEScanner
Нет проблем с использованием Delphi для разработки программ BLE, например для создания приложения для браслета. Однако следует отметить, что во многих событиях элемента управления TBluetoothLE лучше не выполнять слишком много кода. Если есть сложная бизнес-логика, лучше всего выполнить ее в отдельном потоке. В методе события просто запустите соответствующий поток.
В Delphi недавно добавленный TTask.Run позволяет нам запускать большой объем кода в выполнение потока. Метод написания кода стал намного проще, чем раньше, когда нам приходилось создавать класс потока.