• Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)


    Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)

    相关资料:
    1.http://blog.csdn.net/laorenshen/article/details/41149803
    2.http://www.cnblogs.com/findumars/p/5149128.html

    一、理清概念
    1.蓝牙设备:是指代有蓝牙通信的手机、电脑、平板、打印机、耳机等。
    2.设备名称:是指设备打开蓝牙功能后,在其他设备中显示的名字,如图1用的A、B、C等。
    3.蓝牙关态:如果A手机没有打开蓝牙功能,A手机是不能使用搜索的。就算A打开蓝牙,其他的设备没打开,A也是搜索不到的,如E。
    4.服务名称:每一个设备上打开蓝牙时,都会提供不同的服务,服务的名称是在其他设备上显示的。
    5.服务是从哪里来的?其实打开蓝牙功能,只是设备开启此功能,但没有实际的应用功能。必须由某个程序或应用建立相关的服务,其他设备才能与此设备通信。

    二、Delphi中提供了什么?
    1.蓝牙相关功能在System.Bluetooth.pas单元。
    2.Bluetooth.pas提供的对像
    TBluetoothManager:蓝牙管理器。用于蓝牙设备管理,包括发现蓝牙设备,获取配对设备,处理远程配对请求等功能。
    TBluetoothDeviceList:是蓝牙设备列表。可以通过TBluetoothManager.GetPairedDevices获得配对设备列表
    TBluetoothAdapter:本机蓝牙设备,实现配对、取消配对等功能,可通过
    TBluetoothDevice:远端蓝牙设备,每个远端设备可以提供若干个服务
    TBluetoothService:远端蓝牙设备服务,包括服务名和UUID
    TBluetoothServiceList:服务列表。可通过TBluetoothDevice.GetServices获得远端设备服务列表
    TBluetoothSocket:蓝牙通讯套接字。

    三、实例解析 

    小米手机2
    1.打开蓝牙
    2.点击“发现设备”,过一会就会在下面的列表中显示出所有搜索到的蓝牙设备。
    3.在出现的蓝牙设备列表中,选一个。比如“小米手机5”。
    4.点击“配对”,这时小米手机5会收到配对信息。
    5.这时配对设备列表中就会出现小米手机5,选中它。
    6.点击“服务”,出现N个服务,但这时你不知道怎么与小米手机5通信。对的还少个服务。
    7.操作小米手机5中的第三步。
    8.在服务列表中选中最下方的(晕,不知道为什么名字是个空串)。
    9.进入服务演示页面。
    10.点“发送短信给”不好意思,我不小心点了二下,所以小米手机5收到二次。
    11.这时小米手机5就收到了信息。 

    小米手机5
    1.打开蓝牙
    2.接受小米手机2的配对请求。
    3.点击“创建文本服务” 

    PS:
    1.同一个程序里包括了发送信息,与接收信息。所以程序可以在二个手机上测试。
    2.现在只能小米手机2给小米手机5发信息,为什么呢?因为小米手机2没有建服务呀。
    3.如果小米手机5的程序退出,你会发现小米手机2上查看服务,刚才小米手机5建立的服务不见了。
    4.图片本来很清楚,但为了文章的大小,就成了现在的惨不忍睹了。望大家见谅。

    Delphi官方实例源码:

    unit Unit1;
    
    interface
    
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Bluetooth,
      FMX.Layouts, FMX.ListBox, FMX.StdCtrls, FMX.Memo, FMX.Controls.Presentation,
      FMX.Edit, FMX.TabControl, FMX.ScrollBox;
    
    type
      //读取数据线程
      TServerConnectionTH = class(TThread)
      private
        { Private declarations }
        FServerSocket: TBluetoothServerSocket;
        FSocket: TBluetoothSocket;
        FData: TBytes;
      protected
        procedure Execute; override;
      public
        { Public declarations }
        constructor Create(ACreateSuspended: Boolean);
        destructor Destroy; override;
      end;
    
      TForm1 = class(TForm)
        ButtonDiscover: TButton;
        ButtonPair: TButton;
        ButtonUnPair: TButton;
        ButtonPairedDevices: TButton;
        DisplayR: TMemo;
        Edit1: TEdit;
        Button2: TButton;
        FreeSocket: TButton;
        Labeldiscoverable: TLabel;
        ComboBoxDevices: TComboBox;
        ComboBoxPaired: TComboBox;
        Panel1: TPanel;
        TabControl1: TTabControl;
        TabItem1: TTabItem;
        TabItem2: TTabItem;
        LabelNameSarver: TLabel;
        ButtonServices: TButton;
        ComboBoxServices: TComboBox;
        PanelClient: TPanel;
        LabelClient: TLabel;
        ButtonConnectToRFCOMM: TButton;
        PanelServer: TPanel;
        ButtonCloseReadingSocket: TButton;
        ButtonOpenReadingSocket: TButton;
        LabelServer: TLabel;
        Label1: TLabel;
        procedure ButtonDiscoverClick(Sender: TObject);
        procedure ButtonPairClick(Sender: TObject);
        procedure ButtonUnPairClick(Sender: TObject);
        procedure ButtonPairedDeviceClick(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure ButtonOpenReadingSocketClick(Sender: TObject);
        procedure ButtonConnectToRFCOMMClick(Sender: TObject);
        procedure ButtonCloseReadingSocketClick(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure FreeSocketClick(Sender: TObject);
        function ManagerConnected:Boolean;
        function GetServiceName(GUID: string): string;
        procedure ComboBoxPairedChange(Sender: TObject);
        procedure ButtonServicesClick(Sender: TObject);
      private
        { Private declarations }
        FBluetoothManager: TBluetoothManager;
        FDiscoverDevices: TBluetoothDeviceList;
        FPairedDevices: TBluetoothDeviceList;
        FAdapter: TBluetoothAdapter;
        FData: TBytes;
        FSocket: TBluetoothSocket;
        ItemIndex: Integer;
        ServerConnectionTH: TServerConnectionTH;
        procedure DevicesDiscoveryEnd(const Sender: TObject; const ADevices: TBluetoothDeviceList);
        procedure PairedDevices;
        procedure SendData;
      public
        { Public declarations }
      end;
    
    Const
      ServiceName = 'Basic Text Server';
      ServiceGUI = '{B62C4E8D-62CC-404B-BBBF-BF3E3BBB1378}';
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    {$R *.NmXhdpiPh.fmx ANDROID}
    {$R *.LgXhdpiPh.fmx ANDROID}
    {$R *.SmXhdpiPh.fmx ANDROID}
    {$R *.Macintosh.fmx MACOS}
    {$R *.iPhone4in.fmx IOS}
    {$R *.Windows.fmx MSWINDOWS}
    //配对(Pair)
    procedure TForm1.ButtonPairClick(Sender: TObject);
    begin
      if ManagerConnected then
        if ComboboxDevices.ItemIndex > -1 then
          FAdapter.Pair(FDiscoverDevices[ComboboxDevices.ItemIndex])
        else
          ShowMessage('没有选择的设备(No device selected)');
    end;
    
    //取消配对(UnPair)
    procedure TForm1.ButtonUnPairClick(Sender: TObject);
    begin
      if ManagerConnected then
        if ComboboxPaired.ItemIndex > -1 then
          FAdapter.UnPair(FPairedDevices[ComboboxPaired.ItemIndex])
        else
          ShowMessage('未选择配对设备(No Paired device selected)');
    end;
    
    procedure TForm1.ComboBoxPairedChange(Sender: TObject);
    begin
      LabelNameSarver.Text := ComboBoxPaired.Items[ComboBoxPaired.ItemIndex];
    end;
    
    procedure TForm1.PairedDevices;
    var
      I: Integer;
    begin
      ComboboxPaired.Clear;
      if ManagerConnected then
      begin
      FPairedDevices := FBluetoothManager.GetPairedDevices;
      if FPairedDevices.Count > 0 then
        for I:= 0 to FPairedDevices.Count - 1 do
          ComboboxPaired.Items.Add(FPairedDevices[I].DeviceName)
      else
        ComboboxPaired.Items.Add('没有配对设备(No Paired Devices)');
      end;
    end;
    
    //配对设备(Paired Devices)
    procedure TForm1.ButtonPairedDeviceClick(Sender: TObject);
    begin
      PairedDevices;
      ComboboxPaired.DropDown;
    end;
    
    //服务(Services)
    procedure TForm1.ButtonServicesClick(Sender: TObject);
    var
      LServices: TBluetoothServiceList;
      LDevice: TBluetoothDevice;
      I: Integer;
    begin
      ComboBoxServices.Clear;
      if ManagerConnected then
        if ComboboxPaired.ItemIndex > -1 then
        begin
          LDevice := FPairedDevices[ComboboxPaired.ItemIndex] as TBluetoothDevice;
          LServices := LDevice.GetServices;
          for I := 0 to LServices.Count - 1 do
            ComboBoxServices.Items.Add(LServices[I].Name + ' --> ' + GUIDToString(LServices[I].UUID));
          ComboBoxServices.ItemIndex := 0;
          ComboBoxServices.DropDown;
        end
        else
          ShowMessage('未选择配对设备(No paired device selected)');
    end;
    
    //释放客户套接字(Free Client Socket)
    procedure TForm1.FreeSocketClick(Sender: TObject);
    begin
      FreeAndNil(FSocket);
      DisplayR.Lines.Add('客户套接字释放(Client socket set free)');
      DisplayR.GoToLineEnd;
    end;
    
    //清空(Clear)
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      DisplayR.ReadOnly := False;
      DisplayR.SelectAll;
      DisplayR.DeleteSelection;
      DisplayR.ReadOnly := True;
    end;
    
    function TForm1.GetServiceName(GUID: string): string;
    var
      LServices: TBluetoothServiceList;
      LDevice: TBluetoothDevice;
      I: Integer;
    begin
      LDevice := FPairedDevices[ComboboxPaired.ItemIndex] as TBluetoothDevice;
      LServices := LDevice.GetServices;
      for I := 0 to LServices.Count - 1 do
      begin
        if StringToGUID(GUID) = LServices[I].UUID then
        begin
          Result := LServices[I].Name;
          break;
        end;
      end;
    end;
    
    //发送短信给 - >(Send text to ->)
    procedure TForm1.ButtonConnectToRFCOMMClick(Sender: TObject);
    begin
      if ManagerConnected then
        try
          SendData;
        except
          on E : Exception do
          begin
            DisplayR.Lines.Add(E.Message);
            DisplayR.GoToTextEnd;
            FreeAndNil(FSocket);
          end;
        end;
    end;
    
    //判断蓝牙的状态
    function TForm1.ManagerConnected:Boolean;
    begin
      if FBluetoothManager.ConnectionState = TBluetoothConnectionState.Connected then
      begin
        Labeldiscoverable.Text := FBluetoothManager.CurrentAdapter.AdapterName;
        Result := True;
      end
      else
      begin
        Result := False;
        DisplayR.Lines.Add('没有发现蓝牙设备(No Bluetooth device Found)');
        DisplayR.GoToTextEnd;
      end
    end;
    
    //发送信息方法
    procedure TForm1.SendData;
    var
      ToSend: TBytes;
      LDevice: TBluetoothDevice;
    begin
      if (FSocket = nil) or (ItemIndex <> ComboboxPaired.ItemIndex) then
      begin
        if ComboboxPaired.ItemIndex > -1 then
        begin
          LDevice := FPairedDevices[ComboboxPaired.ItemIndex] as TBluetoothDevice;
          DisplayR.Lines.Add(GetServiceName(ServiceGUI));
          DisplayR.GoToTextEnd;
          FSocket := LDevice.CreateClientSocket(StringToGUID(ServiceGUI), False);
          if FSocket <> nil then
          begin
            ItemIndex := ComboboxPaired.ItemIndex;
            FSocket.Connect;
            ToSend := TEncoding.UTF8.GetBytes(Edit1.Text);
            FSocket.SendData(ToSend);
            DisplayR.Lines.Add('短信已发送(Text Sent)');
            DisplayR.GoToTextEnd;
          end
          else
            ShowMessage('Out of time -15s-');
        end
        else
          ShowMessage('未选择配对设备(No paired device selected)');
      end
      else
      begin
        ToSend := TEncoding.UTF8.GetBytes(Edit1.Text);
        FSocket.SendData(ToSend);
        DisplayR.Lines.Add('短信已发送(Text Sent)');
        DisplayR.GoToTextEnd;
      end;
    end;
    
    //发现设备(Discover devices)
    procedure TForm1.ButtonDiscoverClick(Sender: TObject);
    begin
      ComboboxDevices.Clear;
      if ManagerConnected then
      begin
        FAdapter := FBluetoothManager.CurrentAdapter;
        FBluetoothManager.StartDiscovery(10000);
        FBluetoothManager.OnDiscoveryEnd := DevicesDiscoveryEnd;
      end;
    end;
    
    procedure TForm1.DevicesDiscoveryEnd(const Sender: TObject; const ADevices: TBluetoothDeviceList);
    begin
      TThread.Synchronize(nil, procedure
      var
        I: Integer;
      begin
        FDiscoverDevices := ADevices;
        for I := 0 to ADevices.Count - 1 do
          ComboboxDevices.Items.Add(ADevices[I].DeviceName + '  -> ' + ADevices[I].Address);
        ComboboxDevices.ItemIndex := 0;
      end);
    end;
    
    //创建文本服务(Create text service)
    procedure TForm1.ButtonOpenReadingSocketClick(Sender: TObject);
    begin
      if (ServerConnectionTH = nil) and ManagerConnected then
      begin
        try
          FAdapter := FBluetoothManager.CurrentAdapter;
          ServerConnectionTH := TServerConnectionTH.Create(True);
          ServerConnectionTH.FServerSocket := FAdapter.CreateServerSocket(ServiceName, StringToGUID(ServiceGUI), False);
          ServerConnectionTH.Start;
          DisplayR.Lines.Add(' - 创建服务(Service created): "'+ServiceName+'"');
          DisplayR.GoToTextEnd;
        except
          on E : Exception do
          begin
            DisplayR.Lines.Add(E.Message);
            DisplayR.GoToTextEnd;
          end;
        end;
      end;
    end;
    
    //删除文字服务(Remove text service)
    procedure TForm1.ButtonCloseReadingSocketClick(Sender: TObject);
    begin
      if ServerConnectionTH <> nil then
      begin
        ServerConnectionTH.Terminate;
        ServerConnectionTH.WaitFor;
        FreeAndNil(ServerConnectionTH);
        DisplayR.Lines.Add(' - 服务删除(Service removed) -');
        DisplayR.GoToTextEnd;
      end
    end;
    
    //显示窗体时,建立蓝牙管理器,并检查是否开启
    procedure TForm1.FormShow(Sender: TObject);
    begin
      try
        LabelServer.Text := ServiceName;
        LabelClient.Text := 'Client of '+ServiceName;
        FBluetoothManager := TBluetoothManager.Current;
        FAdapter := FBluetoothManager.CurrentAdapter;
        if ManagerConnected then
        begin
          PairedDevices;
          ComboboxPaired.ItemIndex := 0;
        end;
      except
        on E : Exception do
        begin
          ShowMessage(E.Message);
        end;
      end;
    end;
    
    //关闭时,释放线程
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      if ServerConnectionTH <> nil then
      begin
        ServerConnectionTH.Terminate;
        ServerConnectionTH.WaitFor;
        FreeAndNil(ServerConnectionTH);
      end
    end;
    
    {TServerConnection}
    constructor TServerConnectionTH.Create(ACreateSuspended: Boolean);
    begin
      inherited;
    end;
    
    //释放资源
    destructor TServerConnectionTH.Destroy;
    begin
      FSocket.Free;
      FServerSocket.Free;
      inherited;
    end;
    
    //读取线程的读取数据方法
    procedure TServerConnectionTH.execute;
    var
      ASocket: TBluetoothSocket;
      Msg: string;
    begin
      while not Terminated do
        try
          ASocket := nil;
          while not Terminated and (ASocket = nil) do
            ASocket := FServerSocket.Accept(100);
          if(ASocket <> nil) then
          begin
            FSocket := ASocket;
            while not Terminated do
            begin
              FData := ASocket.ReadData;
              if length(FData) > 0 then
                Synchronize(procedure
                  begin
                    Form1.DisplayR.Lines.Add(TEncoding.UTF8.GetString(FData));
                    Form1.DisplayR.GoToTextEnd;
                  end);
              sleep(100);
            end;
          end;
        except
          on E : Exception do
          begin
            Msg := E.Message;
            Synchronize(procedure
              begin
                Form1.DisplayR.Lines.Add('服务器关闭套接字(Server Socket closed): ' + Msg);
                Form1.DisplayR.GoToTextEnd;
              end);
          end;
        end;
    end;
    
    end.
    

      

  • 相关阅读:
    用python实现average()函数,使得当可变参数长度为0的时候,也能正确返回结果。
    请用python实现函数func,当参数类型为list时,返回list中所有数字类型元素的和,当参数类型为tuple时,返回tuple中所有数字类型元素的乘积。
    用python实现循环和递归的形式定义函数,求出1~100的和。
    python实现0~100的平方和,用sum()函数接收一个list作为参数,并返回list所有元素之和。请计算 1*1 + 2*2 + 3*3 + ... + 100*100。
    用python实现线性回归
    IE11用JS检测判断
    Google Chrome的CSS hack写法
    javascript间窗口互相通信,window.open新建窗口保存父窗口对象
    解决IE6不支持css min-width与min-height
    CSS实现兼容性的渐变背景(gradient)效果(转)
  • 原文地址:https://www.cnblogs.com/westsoft/p/8437617.html
Copyright © 2020-2023  润新知