Android 讀取藍牙設備信息開發


(1)Android手機一般以客戶端的角色主動連接SPP協議設備(接上藍牙模塊的數字傳感器),連接流程是:
  1.使用registerReceiver注冊BroadcastReceiver來獲取藍牙狀態、搜索設備等消息;
  2.使用BlueAdatper的搜索;
  3.在BroadcastReceiver的onReceive()里取得搜索所得的藍牙設備信息(如名稱,MAC,RSSI);
  4.通過設備的MAC地址來建立一個BluetoothDevice對象;

  5.由BluetoothDevice衍生出BluetoothSocket,准備SOCKET來讀寫設備;

  6.通過BluetoothSocket的createRfcommSocketToServiceRecord()方法來選擇連接的協議/服務,這里用的是SPP(UUID:00001101-0000-1000-8000-00805F9B34FB);
  7.Connect之后(如果還沒配對則系統自動提示),使用BluetoothSocket的getInputStream()和getOutputStream()來讀寫藍牙設備。

****************注意:對於UUID,必須使用Android的SSP(協議棧默認)的UUID:00001101-0000-1000-8000-00805F9B34FB才能正常和外部的,也是SSP串口的藍牙設備去連接。

(2)添加權限

1 <uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
2 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>

(3)BluetoothAdapter類:

BluetoothAdapter類簡單點來說就是代表了本設備(手機、電腦等)的藍牙適配器對象,通過它我們可以藍牙設備進行基本開發了。

主要有如下功能:

  1、開關藍牙設備

  2、掃描藍牙設備

  3、設置/獲取藍牙狀態信息,例如:藍牙狀態值、藍牙Name、藍牙Mac地址等;

BluetoothAdapter初始化並提示打開藍牙使用:

 1 private BluetoothAdapter  mBluetoothAdapter;
 2 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 3 if (!mBluetoothAdapter.isEnabled()) {
 4     //彈出對話框提示用戶是后打開
 5     Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
 6     startActivity(intent);
 7     //  startActivityForResult(intent, REQUEST_ENABLE);
 8     //不做提示,強行打開
 9     // mBluetoothAdapter.enable();
10 }

創建監聽藍牙狀態的廣播:

 1 BroadcastReceiver mFoundReceiver = new BroadcastReceiver() {
 2 
 3         public void onReceive(Context context, Intent intent) {
 4             String action = intent.getAction();
 5             //找到設備
 6             if (BluetoothDevice.ACTION_FOUND.equals(action)) {
 7                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
 8                 // 添加進一個設備列表,進行顯示。
12                 if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
13                     Log.v(TAG, "find device:" + device.getName() + device.getAddress());
14                 }
15             }
16             //搜索完成
17             else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
18                 cancelDiscovery();20             }
21         }
22     };

注冊廣播監聽藍牙狀態:

 1 private void startDiscovery() { 5     IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);//開啟搜索
 6     registerReceiver(mFoundReceiver, filter);
 7     filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成
 8     registerReceiver(mFoundReceiver, filter);15     mBluetoothAdapter.startDiscovery();17 }

開啟和關閉藍牙掃描:

// 開啟
mBluetoothAdapter.startDiscovery();
// 關閉
mBluetoothAdapter.cancelDiscovery();

點擊掃描到的列表,傳遞點擊項的BluetoothDevice通過putExtra給藍牙數據顯示界面。

4)進行BluetoothSocket socket 和 BluetoothDevice mBluetoothDevice 進行操作。

 1 private class ConnectThread extends Thread {
 2 
 3         public ConnectThread(BluetoothDevice device) {
 4             try {
 5                 socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
 6             } catch (IOException e) {
 7                 e.printStackTrace();
 8             }
10         }
11 
12         public void run() {
13             while (mAutoConnectInterruptTime < 5) {
14                 try {
15 
16                     socket.connect();
17                     runOnUiThread(new Runnable() {
18                         @Override
19                         public void run() {
20                             // TODO 顯示連接成功
21                         }
22                     });
23                     isConnect = true;
24                     mAutoConnectInterruptTime = 0;
25                     manageConnectedSocket(socket); // 創建新的線程對藍牙進行數據讀取。
26                     break;
27 
28                 } catch (Exception e) {
29                     e.printStackTrace();
30                     mAutoConnectInterruptTime++;
31 
32                     try {
33                         Thread.sleep(2000);
34                     } catch (InterruptedException e1) {
35                         e1.printStackTrace();
36                     }
37 
38                     runOnUiThread(new Runnable() {
39                         @Override
40                         public void run() {
41                             // TODO 顯示連接失敗
42                         }
43                     });
44                     // TODO 進行對 inputStream outputStream socket 進行關閉 置空.
45                     return;
46                 }
47             }
48 
49         }
50 
51         public void cancel() {
52             try {
53                 socket.close();
54             } catch (IOException e) {
55                 e.printStackTrace();
56             }
57         }
58     }

(5)通過BluetoothSocket socket 藍牙數據讀取:

 1 public class Receive extends Thread {
 2         // 變量 略過
 3 
 4         // 構造方法
 5         public Receive(BluetoothSocket socket) {
 6 
 7             // 獲取輸入流
 8             try {
 9                 inputStream = socket.getInputStream();
10                 outputStream = socket.getOutputStream();
11             } catch (IOException e) {
12                 e.printStackTrace();
13             }
14         }
15 
16         @Override
17         public void run() {
18             final byte[] bytes = new byte[1024];// 緩沖數據流
19             int          count;// 返回讀取到的數據
20             // 監聽輸入流
21             try {
22                 while (inputStream != null && (count = inputStream.read(bytes)) != -1) {
23                     //獲取有效部分
24                     final byte[] contents = new byte[count];
25                     for (int i = 0; i < contents.length; i++) {
26                         contents[i] = bytes[i];
27                     }
28                     parse(contents); // TODO 對讀取到數據進行轉換
29                 }
30             } catch (Exception e) {
31                 e.printStackTrace();
32             }
33 
34             ConnectThread connectBtThread = new ConnectThread(mBluetoothDevice);
35             connectBtThread.start();
36             // TODO 進行對 inputStream outputStream socket 進行關閉 置空。
37             runOnUiThread(new Runnable() {
38                 @Override
39                 public void run() {
40                     // TODO 關閉藍牙連接
41                 }
42             });
43             // TODO inputStream outputStream socket 進行關閉 置空
44         }
45     }

參考:

 

關於用到BluetoothServerSocket和BluetoothSocket兩個類來建立Server端和Client端,還需要使用到一些關於流(Stream)的知識。

  • BluetoothServerSocket——服務端(監聽端、監聽器、接受請求的一端)
    • Accept()——阻塞宿主線程,直至收到客戶端請求。返回BluetoothSocket對象。由於這個
    • Accept(int timeout)——阻塞宿主線程,直至收到客戶端請求或等待時間超過timeout。返回BluetoothSocket對象。
    • Close()——關閉BluetoothServerSocket監聽器。

  可以看到,Accept方法是一個阻塞方法,所以在進行開發的時候,一般都需要用到多線程的知識。JAVA的多線程知識。

  • BluetoothSocket——客戶端(請求端)
    • Close()——關閉BluetoothSocket請求端。
    • Connect()——主動向服務端(監聽端)發起連接請求。

可使用BluetoothAdapter類的listenUsingRfcommWithServiceRecord方法來新建一個ServerSocket。

  可以使用web上的任何一款UUID產生器為你的程序獲取一個UUID,然后使用fromString(String)初始化一個UUID。

  使用ServerSocket實例的accept方法進行監聽,當監聽到帶有我們初始化的UUID參數的連接請求后作出響應,連接成功后返回一個BluetoothSocket對象。連接完成后,調用close方法關閉該Socket監聽。

使用BluetoothDevice的實例的createRfcommSocketToServiceRecord方法來創建一個BluetoothSocket實例。

  傳入我們服務端的UUID值。

  然后使用BluetoothSocket實例的Connect方法對Server端進行連接請求,當連接成功后,Client端和Server端的傳輸通道就被打開。

參考鏈接:

Android中連接藍牙設備時遇到createRfcommSocketToServiceRecord的UUID問題和BluetoothSocket的connect失敗

http://www.cnblogs.com/cxcco/archive/2012/01/15/2322783.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM