2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Ziehen Sie für die BLE-Entwicklung in Delphi ein TBlueToothLe auf die Schnittstelle und verwenden Sie dieses Steuerelement, um BLE zu entwickeln, z. B. zum Anschließen eines Bluetooth-Armbands.
In der mit Delphi gelieferten Demo gibt es ein BLEScanner-Programm, das als Ausgangspunkt für die Entwicklung verwendet werden kann.
Wenn das obige Programm unter Windows ausgeführt wird, nachdem das Gerät gescannt wurde und die Maus auf ein Gerät klickt, kann es sein, dass die Schnittstelle einfriert und das Programm nicht reagiert. Ein Blick in den Aufgabenverwaltungsbereich zeigt, dass das Programm nicht reagiert und abgestürzt ist.
Klicken Sie mit der Maus, um die Dienste des ausgewählten Geräts zu scannen. Wenn dann die Dienste des Geräts erkannt werden, wird das OnServicesDiscovered-Ereignis von TBluetoothLE ausgelöst. In diesem Fall werden mehrere Dienste des Geräts in einer Schleife gelesen, und dann wird für einen bestimmten Dienst sein Zeichenname in einer Schleife gelesen. Beim Absturz lautet die Schleife „Character“.
Warum es abgestürzt ist, weiß ich nicht. Aber ich habe eine Lösung gefunden, der Code lautet wie folgt:
- 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;
Im obigen Code wurde TTask.Run von mir hinzugefügt. TThread.Synchronize wurde auch von mir hinzugefügt. Entfernen Sie TTask.Run und TThread.Synchronize und der verbleibende Code ist der Originalcode der Demo, die mit Delphi geliefert wird.
Fügen Sie zunächst den Originalcode in TTask.Run ein, was bedeutet, dass diese Codes zur Ausführung in einen Thread eingefügt werden. Anstatt den Thread, der ursprünglich das OnServicesDiscovered-Ereignis ausgelöst hat, ausführen zu lassen. Möglicher Grund: Der Thread, der OnServicesDiscovered ausgelöst hat, kann nicht zu viele zeitaufwändige Aufgaben ausführen.
Der Code wird im Thread ausgeführt, wenn Sie Daten in das Schnittstellensteuerelement schreiben müssen, z. B. Listbox2.Items.Add-Code, müssen Sie eine Thread-Synchronisierung durchführen. Fügen Sie also TThread.Synchronize hinzu.
meine Entwicklungsumgebung
In verschiedenen Umgebungen können die Phänomene unterschiedlich sein. Daher hier meine Entwicklungsumgebung:
Delphi 11 Community Edition;
Windows 11 Home Edition;
Das zu kompilierende und auszuführende Zielprogramm ist die Win32-Version.
Es gibt keinen Test, ob diese Demo unter Android die oben genannten Probleme haben wird. Aber ich glaube, dass es unter Android besser ist, TTask.Run hinzuzufügen.
Die hier erwähnte Demo lautet nach der Installation von Delphi, wenn sie standardmäßig installiert ist, das Demo-Programm:
C:\Benutzer\Öffentliche Dokumente\EmbarcaderoStudio22.0\Beispiele\Object Pascal\Beispiele für mehrere Geräte\Gerätesensoren und -dienste\Bluetooth\BLEScanner
Es ist kein Problem, Delphi zum Entwickeln von BLE-Programmen zu verwenden, beispielsweise zum Erstellen einer Armband-APP. Es ist jedoch zu beachten, dass es bei vielen Ereignissen des TBluetoothLE-Steuerelements am besten ist, nicht zu viel Code auszuführen. Wenn eine komplexe Geschäftslogik vorliegt, ist es am besten, diese in einem separaten Thread auszuführen. Starten Sie in der Ereignismethode einfach den entsprechenden Thread.
Für Delphi ermöglicht uns das neu hinzugefügte TTask.Run, viel Code in die Thread-Ausführung zu werfen. Die Code-Schreibmethode ist viel einfacher als zuvor, als wir eine Thread-Klasse erstellen mussten.