minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Para desenvolvimento BLE em Delphi, arraste um TBlueToothLe para a interface e use este controle para desenvolver BLE, como conectar uma pulseira Bluetooth.
Existe um programa BLEScanner na Demo que acompanha o Delphi, que pode ser usado como ponto de partida para o desenvolvimento.
Se o programa acima for executado no Windows, após a verificação do dispositivo, se o mouse clicar em um dispositivo, a interface poderá congelar e o programa não responderá. Olhando para a área de gerenciamento de tarefas, é verdade que o programa não responde e travou.
Clique com o mouse para verificar os serviços do dispositivo selecionado. Então, quando os serviços do dispositivo são descobertos, o evento OnServicesDiscovered do TBluetoothLE é acionado. Nesse caso, vários serviços do dispositivo são lidos em loop e, para um determinado serviço, seu nome de caractere é lido em loop. A falha é onde o loop lê Character.
Por que caiu, eu não sei. Mas encontrei uma solução, o código é o seguinte:
- 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;
No código acima, TTask.Run foi adicionado por mim. TThread.Synchronize também foi adicionado por mim. Remova TTask.Run e TThread.Synchronize e o código restante é o código original do Demo que vem com o Delphi.
Primeiro, coloque o código original em TTask.Run, o que significa colocar esses códigos em um thread para execução. Em vez de deixar o thread que originalmente gerou o evento OnServicesDiscovered ser executado. Razão possível: o thread que acionou OnServicesDiscovered não pode executar muitas tarefas demoradas.
O código é executado no thread. Quando você precisa gravar dados no controle de interface, como o código Listbox2.Items.Add, você precisa realizar a sincronização do thread. Então adicione TThread.Synchronize.
meu ambiente de desenvolvimento
Em ambientes diferentes, os fenômenos podem ser diferentes. Portanto, aqui está meu ambiente de desenvolvimento:
Delphi 11 Edição Comunitária;
Windows 11 Home Edition;
O programa alvo a ser compilado e executado é a versão Win32.
Não há teste se esta demonstração terá os problemas acima no Android. Mas acredito que no Android será melhor adicionar TTask.Run.
O Demo mencionado aqui, após a instalação do Delphi, se estiver instalado por padrão, o programa Demo é:
C:UsuáriosPúblicoDocumentosEmbarcaderoStudio22.0AmostrasObject PascalAmostras de vários dispositivosSensores e serviços de dispositivosBluetoothBLEScanner
Não há problema em usar Delphi para desenvolver programas BLE, como fazer um APP de pulseira. Porém, deve-se observar que em muitos eventos do controle TBluetoothLE, é melhor não executar muito código. Se houver uma lógica de negócios complexa, é melhor executá-la em um thread separado. No método de evento, basta iniciar o thread correspondente.
Para Delphi, o recém-adicionado TTask.Run nos permite colocar muito código na execução do thread. O método de escrita de código é muito mais simples do que antes, quando tínhamos que criar uma classe de thread.