实现Android和PC之间的蓝牙通信
?????? 這兩天想實(shí)現(xiàn)PC和安卓手機(jī)的通信,限于水平,知道的方法大概有兩種:基于數(shù)據(jù)包的socket和藍(lán)牙。雖然看起來(lái)簡(jiǎn)單,但調(diào)也調(diào)了兩天多。自己測(cè)試了下socket,在室內(nèi)WIFI環(huán)境下時(shí)延大概是0.1s。而在3G網(wǎng)絡(luò)下時(shí)延居然達(dá)3s之多,而且只要不發(fā)數(shù)據(jù),端口貌似就會(huì)斷掉,總之,很不爽。于是,便考慮了藍(lán)牙的方法。
實(shí)現(xiàn)手機(jī)和PC的藍(lán)牙通信,一種是最常用的藍(lán)牙虛擬串口,這種方法可以通過(guò)配置非常簡(jiǎn)單地實(shí)現(xiàn),很多外置藍(lán)牙GPS都用這種做法。但大名鼎鼎的安卓卻不支持,因此對(duì)大部分外置GPS都不提供支持(可能安卓手機(jī)大部分包含內(nèi)置GPS,覺(jué)得外置的太雞肋了)。因此必須采用第二種,藍(lán)牙socket。
????? 在電腦上,實(shí)在不想去在C++下開(kāi)發(fā),于是便尋找.NET組件,但實(shí)際上微軟的NET庫(kù)中不支持藍(lán)牙,因此必須采用第三方的控件,名字叫inthehand.
????? 這篇文章中詳細(xì)的介紹了inthehan
d組件,http://www.cnblogs.com/procoder/archive/2009/09/22/1571580.html。由于它討論了實(shí)現(xiàn)文件傳輸?shù)乃悸?#xff0c;我們?cè)谶@篇文章中就只討論簡(jiǎn)單的字符傳輸。
???????它的官方網(wǎng)站是inthehand.net,其中多數(shù)的類(lèi)庫(kù)和方法都能找到。
下面是手機(jī)端的初始化代碼。其中的具體含義可參照http://android.tgbus.com/Android/tutorial/201103/346657.shtml。
private PrintStream mPrintStream = null;private BufferedReader mBufferedReader = null;
BluetoothAdapter myBluetoothAdapter = null;
BluetoothServerSocket mBThServer = null;
BluetoothSocket mBTHSocket = null;
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
myBluetoothAdapter.enable();//open bth
Intent discoverableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//使得藍(lán)牙處于可發(fā)現(xiàn)模式,持續(xù)時(shí)間150s
discoverableIntent.putExtra(
BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 150);
下面是PC上的初始化核心代碼:PC是作為客戶(hù)端出現(xiàn)的。它需要通過(guò)搜索獲取手機(jī)的藍(lán)牙MAC地址,實(shí)現(xiàn)通信。GUID又名UUID,是標(biāo)記硬件地址的一種方法。
?? /// <summary>
??????? /// 打開(kāi)端口
??????? /// </summary>
??????? /// <param name="Name">端口名稱(chēng)</param>
??????? /// <returns>成功否</returns>
??????? public bool OpenPort(string Name)
??????? {
??????????? InTheHand.Net.Bluetooth.BluetoothRadio.PrimaryRadio.Mode = InTheHand.Net.Bluetooth.RadioMode.Connectable;
??????????? InTheHand.Net.Sockets.BluetoothClient cli = new InTheHand.Net.Sockets.BluetoothClient();
??????????? InTheHand.Net.Sockets.BluetoothDeviceInfo[] devices = cli.DiscoverDevices();
??????????? foreach (InTheHand.Net.Sockets.BluetoothDeviceInfo device in devices)//設(shè)備搜尋
??????????? {
??????????????? device.Update();
??????????????? device.Refresh();
??????????????? MessageBox.Show("設(shè)備已找到");
??????????????? break;
??????????? }
?
??????????? BluetoothDeviceInfo bd = new BluetoothDeviceInfo(devices[0].DeviceAddress);
??????????? bluetoothClient = new BluetoothClient();
??????????? Guid mGUID = Guid.Parse("fa87c0d0-afac-11de-8a39-0800200c9a66");
??????????? bluetoothClient.Connect(devices[0].DeviceAddress, mGUID);//客戶(hù)端對(duì)地址實(shí)現(xiàn)連接,這是一個(gè)阻塞線程,需要服務(wù)器端的回應(yīng)
??????????? ReceiveThread = new Thread(ReceiveMethod);
??????????? ReceiveThread.Start();
?
??????????? return true;
??????? }
????????下面是手機(jī)接受PC端連接請(qǐng)求的方法:
View Code 1 if (connected)2 {
3 return;
4 }
5 try
6 {
7 mBThServer = myBluetoothAdapter
8 .listenUsingRfcommWithServiceRecord(NAME_SECURE,
9 MY_UUID_SECURE);
10 } catch (IOException e)
11 {
12 // TODO Auto-generated catch block
13 e.printStackTrace();
14 }
15
16 try
17 {
18 mBTHSocket = mBThServer.accept();
19 } catch (IOException e)
20 {
21 // TODO Auto-generated catch block
22 e.printStackTrace();
23 }
24 try
25 {
26 mBufferedReader = new BufferedReader(new InputStreamReader(
27 mBTHSocket.getInputStream()));
28 } catch (IOException e1)
29 {
30 // TODO Auto-generated catch block
31 e1.printStackTrace();
32 }// 取得輸入、輸出流
33 try
34 {
35 mPrintStream = new PrintStream(
36 mBTHSocket.getOutputStream(), true);
37 connected = true;
38 } catch (IOException e)
39 {
40 // TODO Auto-generated catch block
41 e.printStackTrace();
42 }
?? 要通過(guò)手機(jī)發(fā)送數(shù)據(jù),執(zhí)行以下代碼即可:
mPrintStream.write(buff);} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}// 發(fā)送給服務(wù)器
mPrintStream.flush();
????PC端的接受代碼:
while (isConnecting){
try
{
Stream peerStream = bluetoothClient.GetStream();
peerStream.Read(buffer, 0, PACKETLENGTH);
//dataprocess();
}
catch (Exception ex)
{
isConnecting = false;
MessageBox.Show(ex.ToString());
}
這里要注意以下幾個(gè)小問(wèn)題,但也就是這幾個(gè)問(wèn)題,耽誤了我很久時(shí)間:
????? inthehand.net.personal是PC端上一定要用得到的庫(kù),但注意這個(gè)庫(kù)函數(shù)的版本,我一開(kāi)始用了的dll是600K左右的,編譯沒(méi)問(wèn)題,運(yùn)行就會(huì)報(bào)錯(cuò),提示找不到dll。但后來(lái)左思右想,才發(fā)現(xiàn)還有另外的一個(gè)同名dll,150K左右,換過(guò)來(lái)以后一切OK,太坑爹了!
??????? 手機(jī)設(shè)備的藍(lán)牙硬件權(quán)限要打開(kāi),否則就沒(méi)法運(yùn)行。
??????? 還有我特想將手機(jī)做個(gè)藍(lán)牙HID設(shè)備,但這樣貌似是不行的。因?yàn)檫@個(gè)庫(kù)本身提供的方法不夠底層...總之還想再研究下。
??????? 有任何問(wèn)題歡迎討論
????????
??????
總結(jié)
以上是生活随笔為你收集整理的实现Android和PC之间的蓝牙通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: winform datagridview
- 下一篇: wow64简介