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官方实例源码:
1 unit Unit1; 2 3 interface 4 5 uses 6 System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 7 FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Bluetooth, 8 FMX.Layouts, FMX.ListBox, FMX.StdCtrls, FMX.Memo, FMX.Controls.Presentation, 9 FMX.Edit, FMX.TabControl, FMX.ScrollBox; 10 11 type 12 //读取数据线程 13 TServerConnectionTH = class(TThread) 14 private 15 { Private declarations } 16 FServerSocket: TBluetoothServerSocket; 17 FSocket: TBluetoothSocket; 18 FData: TBytes; 19 protected 20 procedure Execute; override; 21 public 22 { Public declarations } 23 constructor Create(ACreateSuspended: Boolean); 24 destructor Destroy; override; 25 end; 26 27 TForm1 = class(TForm) 28 ButtonDiscover: TButton; 29 ButtonPair: TButton; 30 ButtonUnPair: TButton; 31 ButtonPairedDevices: TButton; 32 DisplayR: TMemo; 33 Edit1: TEdit; 34 Button2: TButton; 35 FreeSocket: TButton; 36 Labeldiscoverable: TLabel; 37 ComboBoxDevices: TComboBox; 38 ComboBoxPaired: TComboBox; 39 Panel1: TPanel; 40 TabControl1: TTabControl; 41 TabItem1: TTabItem; 42 TabItem2: TTabItem; 43 LabelNameSarver: TLabel; 44 ButtonServices: TButton; 45 ComboBoxServices: TComboBox; 46 PanelClient: TPanel; 47 LabelClient: TLabel; 48 ButtonConnectToRFCOMM: TButton; 49 PanelServer: TPanel; 50 ButtonCloseReadingSocket: TButton; 51 ButtonOpenReadingSocket: TButton; 52 LabelServer: TLabel; 53 Label1: TLabel; 54 procedure ButtonDiscoverClick(Sender: TObject); 55 procedure ButtonPairClick(Sender: TObject); 56 procedure ButtonUnPairClick(Sender: TObject); 57 procedure ButtonPairedDeviceClick(Sender: TObject); 58 procedure FormShow(Sender: TObject); 59 procedure ButtonOpenReadingSocketClick(Sender: TObject); 60 procedure ButtonConnectToRFCOMMClick(Sender: TObject); 61 procedure ButtonCloseReadingSocketClick(Sender: TObject); 62 procedure Button2Click(Sender: TObject); 63 procedure FormClose(Sender: TObject; var Action: TCloseAction); 64 procedure FreeSocketClick(Sender: TObject); 65 function ManagerConnected:Boolean; 66 function GetServiceName(GUID: string): string; 67 procedure ComboBoxPairedChange(Sender: TObject); 68 procedure ButtonServicesClick(Sender: TObject); 69 private 70 { Private declarations } 71 FBluetoothManager: TBluetoothManager; 72 FDiscoverDevices: TBluetoothDeviceList; 73 FPairedDevices: TBluetoothDeviceList; 74 FAdapter: TBluetoothAdapter; 75 FData: TBytes; 76 FSocket: TBluetoothSocket; 77 ItemIndex: Integer; 78 ServerConnectionTH: TServerConnectionTH; 79 procedure DevicesDiscoveryEnd(const Sender: TObject; const ADevices: TBluetoothDeviceList); 80 procedure PairedDevices; 81 procedure SendData; 82 public 83 { Public declarations } 84 end; 85 86 Const 87 ServiceName = 'Basic Text Server'; 88 ServiceGUI = '{B62C4E8D-62CC-404B-BBBF-BF3E3BBB1378}'; 89 var 90 Form1: TForm1; 91 92 implementation 93 94 {$R *.fmx} 95 {$R *.NmXhdpiPh.fmx ANDROID} 96 {$R *.LgXhdpiPh.fmx ANDROID} 97 {$R *.SmXhdpiPh.fmx ANDROID} 98 {$R *.Macintosh.fmx MACOS} 99 {$R *.iPhone4in.fmx IOS} 100 {$R *.Windows.fmx MSWINDOWS} 101 //配对(Pair) 102 procedure TForm1.ButtonPairClick(Sender: TObject); 103 begin 104 if ManagerConnected then 105 if ComboboxDevices.ItemIndex > -1 then 106 FAdapter.Pair(FDiscoverDevices[ComboboxDevices.ItemIndex]) 107 else 108 ShowMessage('没有选择的设备(No device selected)'); 109 end; 110 111 //取消配对(UnPair) 112 procedure TForm1.ButtonUnPairClick(Sender: TObject); 113 begin 114 if ManagerConnected then 115 if ComboboxPaired.ItemIndex > -1 then 116 FAdapter.UnPair(FPairedDevices[ComboboxPaired.ItemIndex]) 117 else 118 ShowMessage('未选择配对设备(No Paired device selected)'); 119 end; 120 121 procedure TForm1.ComboBoxPairedChange(Sender: TObject); 122 begin 123 LabelNameSarver.Text := ComboBoxPaired.Items[ComboBoxPaired.ItemIndex]; 124 end; 125 126 procedure TForm1.PairedDevices; 127 var 128 I: Integer; 129 begin 130 ComboboxPaired.Clear; 131 if ManagerConnected then 132 begin 133 FPairedDevices := FBluetoothManager.GetPairedDevices; 134 if FPairedDevices.Count > 0 then 135 for I:= 0 to FPairedDevices.Count - 1 do 136 ComboboxPaired.Items.Add(FPairedDevices[I].DeviceName) 137 else 138 ComboboxPaired.Items.Add('没有配对设备(No Paired Devices)'); 139 end; 140 end; 141 142 //配对设备(Paired Devices) 143 procedure TForm1.ButtonPairedDeviceClick(Sender: TObject); 144 begin 145 PairedDevices; 146 ComboboxPaired.DropDown; 147 end; 148 149 //服务(Services) 150 procedure TForm1.ButtonServicesClick(Sender: TObject); 151 var 152 LServices: TBluetoothServiceList; 153 LDevice: TBluetoothDevice; 154 I: Integer; 155 begin 156 ComboBoxServices.Clear; 157 if ManagerConnected then 158 if ComboboxPaired.ItemIndex > -1 then 159 begin 160 LDevice := FPairedDevices[ComboboxPaired.ItemIndex] as TBluetoothDevice; 161 LServices := LDevice.GetServices; 162 for I := 0 to LServices.Count - 1 do 163 ComboBoxServices.Items.Add(LServices[I].Name + ' --> ' + GUIDToString(LServices[I].UUID)); 164 ComboBoxServices.ItemIndex := 0; 165 ComboBoxServices.DropDown; 166 end 167 else 168 ShowMessage('未选择配对设备(No paired device selected)'); 169 end; 170 171 //释放客户套接字(Free Client Socket) 172 procedure TForm1.FreeSocketClick(Sender: TObject); 173 begin 174 FreeAndNil(FSocket); 175 DisplayR.Lines.Add('客户套接字释放(Client socket set free)'); 176 DisplayR.GoToLineEnd; 177 end; 178 179 //清空(Clear) 180 procedure TForm1.Button2Click(Sender: TObject); 181 begin 182 DisplayR.ReadOnly := False; 183 DisplayR.SelectAll; 184 DisplayR.DeleteSelection; 185 DisplayR.ReadOnly := True; 186 end; 187 188 function TForm1.GetServiceName(GUID: string): string; 189 var 190 LServices: TBluetoothServiceList; 191 LDevice: TBluetoothDevice; 192 I: Integer; 193 begin 194 LDevice := FPairedDevices[ComboboxPaired.ItemIndex] as TBluetoothDevice; 195 LServices := LDevice.GetServices; 196 for I := 0 to LServices.Count - 1 do 197 begin 198 if StringToGUID(GUID) = LServices[I].UUID then 199 begin 200 Result := LServices[I].Name; 201 break; 202 end; 203 end; 204 end; 205 206 //发送短信给 - >(Send text to ->) 207 procedure TForm1.ButtonConnectToRFCOMMClick(Sender: TObject); 208 begin 209 if ManagerConnected then 210 try 211 SendData; 212 except 213 on E : Exception do 214 begin 215 DisplayR.Lines.Add(E.Message); 216 DisplayR.GoToTextEnd; 217 FreeAndNil(FSocket); 218 end; 219 end; 220 end; 221 222 //判断蓝牙的状态 223 function TForm1.ManagerConnected:Boolean; 224 begin 225 if FBluetoothManager.ConnectionState = TBluetoothConnectionState.Connected then 226 begin 227 Labeldiscoverable.Text := FBluetoothManager.CurrentAdapter.AdapterName; 228 Result := True; 229 end 230 else 231 begin 232 Result := False; 233 DisplayR.Lines.Add('没有发现蓝牙设备(No Bluetooth device Found)'); 234 DisplayR.GoToTextEnd; 235 end 236 end; 237 238 //发送信息方法 239 procedure TForm1.SendData; 240 var 241 ToSend: TBytes; 242 LDevice: TBluetoothDevice; 243 begin 244 if (FSocket = nil) or (ItemIndex <> ComboboxPaired.ItemIndex) then 245 begin 246 if ComboboxPaired.ItemIndex > -1 then 247 begin 248 LDevice := FPairedDevices[ComboboxPaired.ItemIndex] as TBluetoothDevice; 249 DisplayR.Lines.Add(GetServiceName(ServiceGUI)); 250 DisplayR.GoToTextEnd; 251 FSocket := LDevice.CreateClientSocket(StringToGUID(ServiceGUI), False); 252 if FSocket <> nil then 253 begin 254 ItemIndex := ComboboxPaired.ItemIndex; 255 FSocket.Connect; 256 ToSend := TEncoding.UTF8.GetBytes(Edit1.Text); 257 FSocket.SendData(ToSend); 258 DisplayR.Lines.Add('短信已发送(Text Sent)'); 259 DisplayR.GoToTextEnd; 260 end 261 else 262 ShowMessage('Out of time -15s-'); 263 end 264 else 265 ShowMessage('未选择配对设备(No paired device selected)'); 266 end 267 else 268 begin 269 ToSend := TEncoding.UTF8.GetBytes(Edit1.Text); 270 FSocket.SendData(ToSend); 271 DisplayR.Lines.Add('短信已发送(Text Sent)'); 272 DisplayR.GoToTextEnd; 273 end; 274 end; 275 276 //发现设备(Discover devices) 277 procedure TForm1.ButtonDiscoverClick(Sender: TObject); 278 begin 279 ComboboxDevices.Clear; 280 if ManagerConnected then 281 begin 282 FAdapter := FBluetoothManager.CurrentAdapter; 283 FBluetoothManager.StartDiscovery(10000); 284 FBluetoothManager.OnDiscoveryEnd := DevicesDiscoveryEnd; 285 end; 286 end; 287 288 procedure TForm1.DevicesDiscoveryEnd(const Sender: TObject; const ADevices: TBluetoothDeviceList); 289 begin 290 TThread.Synchronize(nil, procedure 291 var 292 I: Integer; 293 begin 294 FDiscoverDevices := ADevices; 295 for I := 0 to ADevices.Count - 1 do 296 ComboboxDevices.Items.Add(ADevices[I].DeviceName + ' -> ' + ADevices[I].Address); 297 ComboboxDevices.ItemIndex := 0; 298 end); 299 end; 300 301 //创建文本服务(Create text service) 302 procedure TForm1.ButtonOpenReadingSocketClick(Sender: TObject); 303 begin 304 if (ServerConnectionTH = nil) and ManagerConnected then 305 begin 306 try 307 FAdapter := FBluetoothManager.CurrentAdapter; 308 ServerConnectionTH := TServerConnectionTH.Create(True); 309 ServerConnectionTH.FServerSocket := FAdapter.CreateServerSocket(ServiceName, StringToGUID(ServiceGUI), False); 310 ServerConnectionTH.Start; 311 DisplayR.Lines.Add(' - 创建服务(Service created): "'+ServiceName+'"'); 312 DisplayR.GoToTextEnd; 313 except 314 on E : Exception do 315 begin 316 DisplayR.Lines.Add(E.Message); 317 DisplayR.GoToTextEnd; 318 end; 319 end; 320 end; 321 end; 322 323 //删除文字服务(Remove text service) 324 procedure TForm1.ButtonCloseReadingSocketClick(Sender: TObject); 325 begin 326 if ServerConnectionTH <> nil then 327 begin 328 ServerConnectionTH.Terminate; 329 ServerConnectionTH.WaitFor; 330 FreeAndNil(ServerConnectionTH); 331 DisplayR.Lines.Add(' - 服务删除(Service removed) -'); 332 DisplayR.GoToTextEnd; 333 end 334 end; 335 336 //显示窗体时,建立蓝牙管理器,并检查是否开启 337 procedure TForm1.FormShow(Sender: TObject); 338 begin 339 try 340 LabelServer.Text := ServiceName; 341 LabelClient.Text := 'Client of '+ServiceName; 342 FBluetoothManager := TBluetoothManager.Current; 343 FAdapter := FBluetoothManager.CurrentAdapter; 344 if ManagerConnected then 345 begin 346 PairedDevices; 347 ComboboxPaired.ItemIndex := 0; 348 end; 349 except 350 on E : Exception do 351 begin 352 ShowMessage(E.Message); 353 end; 354 end; 355 end; 356 357 //关闭时,释放线程 358 procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); 359 begin 360 if ServerConnectionTH <> nil then 361 begin 362 ServerConnectionTH.Terminate; 363 ServerConnectionTH.WaitFor; 364 FreeAndNil(ServerConnectionTH); 365 end 366 end; 367 368 {TServerConnection} 369 constructor TServerConnectionTH.Create(ACreateSuspended: Boolean); 370 begin 371 inherited; 372 end; 373 374 //释放资源 375 destructor TServerConnectionTH.Destroy; 376 begin 377 FSocket.Free; 378 FServerSocket.Free; 379 inherited; 380 end; 381 382 //读取线程的读取数据方法 383 procedure TServerConnectionTH.execute; 384 var 385 ASocket: TBluetoothSocket; 386 Msg: string; 387 begin 388 while not Terminated do 389 try 390 ASocket := nil; 391 while not Terminated and (ASocket = nil) do 392 ASocket := FServerSocket.Accept(100); 393 if(ASocket <> nil) then 394 begin 395 FSocket := ASocket; 396 while not Terminated do 397 begin 398 FData := ASocket.ReadData; 399 if length(FData) > 0 then 400 Synchronize(procedure 401 begin 402 Form1.DisplayR.Lines.Add(TEncoding.UTF8.GetString(FData)); 403 Form1.DisplayR.GoToTextEnd; 404 end); 405 sleep(100); 406 end; 407 end; 408 except 409 on E : Exception do 410 begin 411 Msg := E.Message; 412 Synchronize(procedure 413 begin 414 Form1.DisplayR.Lines.Add('服务器关闭套接字(Server Socket closed): ' + Msg); 415 Form1.DisplayR.GoToTextEnd; 416 end); 417 end; 418 end; 419 end; 420 421 end.
欢迎关注我,一起进步!扫描下方二维码即可加我