安卓蓝牙通讯
需要說明的是,該通訊是安卓手機(jī)與藍(lán)牙模塊之間的通訊。
通訊的步驟如下
通過得到的BluetoothSocket對(duì)象,進(jìn)行數(shù)據(jù)的讀寫。
下面我就分別寫下這幾個(gè)步驟。
1,得到本地的藍(lán)牙適配器并且打開藍(lán)牙
1.1得到本地藍(lán)牙適配器:
1.2打開藍(lán)牙
// 如果藍(lán)牙沒有打開,通過這個(gè)Activity打開if (!adapter.isEnabled()) {Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivity(intent);}Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);// 300為可以被其他藍(lán)牙設(shè)備搜索到的時(shí)間,單位為秒enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivityForResult(enable, DISCOVERY_REQUEST);2,掃描周圍的設(shè)備
通過BluetoothAdapter 的startDiscovery()進(jìn)行掃描,找到一個(gè)設(shè)備,就會(huì)發(fā)出一條廣播,所以找到的新設(shè)備要在廣播接收器里面進(jìn)行接收。
掃描的時(shí)間會(huì)比較長(zhǎng),一般會(huì)持續(xù)十多秒。
3,通過廣播接收器找到掃描到的新設(shè)備。
前面已經(jīng)說了,如果adapter發(fā)現(xiàn)新的設(shè)備,就會(huì)發(fā)出廣播。因此我們需要在廣播接收器里面得到新設(shè)備。
BluetoothDevice對(duì)象就是發(fā)現(xiàn)的新設(shè)備,BluetoothDevice有好多方法,比如通過bluetoothdevice.getName()獲取新設(shè)備名稱。通過bluetoothdevice.getAddress()獲取設(shè)備的硬件地址,比如“00:11:22:AA:BB:CC”。當(dāng)然還有其他的方法,這里不再多說。
發(fā)現(xiàn)的新設(shè)備可以顯示到一個(gè)列表里面。這里只是說明原理,列表顯示在源碼里面。
當(dāng)然,最后需要對(duì)廣播接收器進(jìn)行注冊(cè)。
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter);4,得到BluetoothSocket。
需要說明的是,這里手機(jī)是作為客戶端來使用。如果是作為服務(wù)端,得到Socket的方法會(huì)有所不同。
無論手機(jī)是作為客戶端還是服務(wù)端,在和其他設(shè)備連接過程中,都需要UUID,下面簡(jiǎn)單地介紹下UUID。
UUID
UUID 含義是通用唯一識(shí)別碼 (Universally Unique Identifier),這 是一個(gè)軟件建構(gòu)的標(biāo)
準(zhǔn),也是被開源軟件基金會(huì) (Open Software Foundation, OSF) 的組織應(yīng)用在分布式計(jì)算環(huán)境 (Distributed Computing Environment, DCE) 領(lǐng)域的一部分。
在藍(lán)牙 3.0 及一下版本中,UUID 被用于唯一標(biāo)識(shí)一個(gè)服務(wù),比如文件傳輸服務(wù),串口服務(wù)、打印機(jī)服務(wù)等,如下:
藍(lán)牙串口服務(wù)
SerialPortServiceClass_UUID = ‘{00001101-0000-1000-8000-00805F9B34FB}’
LANAccessUsingPPPServiceClass_UUID = ‘{00001102-0000-1000-8000-00805F9B34FB}’
撥號(hào)網(wǎng)絡(luò)服務(wù)
DialupNetworkingServiceClass_UUID = ‘{00001103-0000-1000-8000-00805F9B34FB}’
信息同步服務(wù)
IrMCSyncServiceClass_UUID = ‘{00001104-0000-1000-8000-00805F9B34FB}’
SDP_OBEXObjectPushServiceClass_UUID = ‘{00001105-0000-1000-8000-00805F9B34FB}’
文件傳輸服務(wù)
OBEXFileTransferServiceClass_UUID = ‘{00001106-0000-1000-8000-00805F9B34FB}’
IrMCSyncCommandServiceClass_UUID = ‘{00001107-0000-1000-8000-00805F9B34FB}’
因?yàn)槲覀兒退{(lán)牙模塊進(jìn)行通訊,所以選擇藍(lán)牙串口服務(wù)的UUID。
通過UUID建立連接
private static String uuid = "00001101-0000-1000-8000-00805F9B34FB"; try{ //device為BluetoothDevice 對(duì)象,即掃描到的新設(shè)備對(duì)象 BluetoothSocket mmSocket=device.createRfcommSocketToServiceRecord(UUID.fromString(uuid)); } catch(IOException e){ }得到BluetoothSocket 之后,就可以在兩臺(tái)設(shè)備之間建立連接,在連接之前,我們最好取消上面開啟的掃描功能功能。
//adapter是BluetoothAdapter 的對(duì)象。 adapter.cancelDiscovery();進(jìn)行連接:
try{ //這個(gè)方法是阻塞式的,所以最好開一個(gè)線程進(jìn)行連接。在這里可以寫一個(gè)回調(diào),連接成功后,就可以通過該socket讀寫數(shù)據(jù)了,詳細(xì)的代碼見源碼。mmSocket.connect(); }catch(Exception e){ //連接過程中若拋出異常,則關(guān)閉socket。try {mmSocket.close();} catch (Exception e1) {Log.e("close", e1.toString());} }5,通過BluetoothSocket 對(duì)象讀寫數(shù)據(jù)。
收到數(shù)據(jù)后,通過Handler 發(fā)送message來刷新界面。
public class ConnectedThread extends Thread {private final BluetoothSocket mmSocket;private final InputStream mmInStream;private final OutputStream mmOutStream;public String datas;public Message message;public Handler handler;//輸入輸出流的初始化public ConnectedThread(BluetoothSocket socket,Handler handlers) {mmSocket = socket;this.handler=handlers;InputStream tmpIn = null;OutputStream tmpOut = null;try {tmpIn = socket.getInputStream();tmpOut = socket.getOutputStream();} catch (IOException e) {}mmInStream = tmpIn;mmOutStream = tmpOut;}/*** 接收數(shù)據(jù),線程*/public void run() {byte[] buffer = new byte[2048];int bytes;while (true) {try {bytes = mmInStream.read(buffer);String str= new String(buffer,"ISO-8859-1");str=str.substring(0,bytes);datas=str;message=new Message();message.what=Constant.DATAS;handler.sendMessage(message);} catch (IOException e) {break;}}}public void write(byte[] bytes) {try {mmOutStream.write(bytes);} catch (IOException e) {}}}6,其他
關(guān)于將手機(jī)作為服務(wù)端我沒有嘗試過,下面是連接的代碼:
private static String uuid = "00001101-0000-1000-8000-00805F9B34FB"; //adapter是BluetoothAdapter 的對(duì)象。 BluetoothServerSocket =adapter.listenUsingRfcommWithServiceRecord("blue",UUID.fromString(uuid));//連接之前會(huì)一直等待,所以要開啟一個(gè)線程 while (true) { try { BluetoothSocket socket = mmServerSocket.accept(); } catch (IOException e) { break; } }拿到BluetoothSocket之后,就可以進(jìn)行通訊了,通訊的代碼和作為客戶端連接設(shè)備應(yīng)該是一樣的。我沒有嘗試過。
7,源碼下載
源碼下載
總結(jié)
- 上一篇: 老鼠的旅行
- 下一篇: centos7.5 挂载超过2T的大硬盘