經典藍牙那些事兒——(登錄、登錄異常、自動連接、中斷、斷後重連等)

最近項目中用到傳統藍牙連接設備通訊,折騰了一週把基本功能實現了,這裏簡單記錄一下。

藍牙設備:HC-05藍牙模塊

主要功能:-首次手動配對;-自動連接;-連接超時或異常處理;-中斷監聽;-中斷後檢測重新連接

測試版本:Android 6.0

實現經典藍牙功能的基本邏輯:

 整個藍牙功能邏輯如上圖所示,其中比較關鍵的是藍牙自動連接和斷開後重新連接。關於藍牙自動連接,本文采用的是首次配對後,利用SharedPreferences將目標藍牙設備的MAC地址存入,等開始掃描時,採用掃描到的設備MAC地址(與SharedPreferences文件中的MAC地址是否匹配)+設備名雙重檢測方式判斷當前設備是否爲目標藍牙設備,從而進行藍牙自動連接,該部分核心代碼如下:

if (device.getBondState() == BluetoothDevice.BOND_BONDED) {//已配對設備進行操作
    if (device.getName().substring(0, 3).equals("Spe")) {
         Tools.saveTempInfos(context,
              "BluetoothAddress", "mac_address", device.getAddress());
         messageListence.OnReceived(device.getAddress());
    } else {
         messageListence.OnReceived(BLUETOOTH_EXCEPTION);
    }
} else {
    System.out.println("設備未配對!");
}

連接超時或異常處理,該部分也是藍牙連接的一個重要部分,因爲超時或者異常均會影響用戶體驗,這裏參考了https://blog.csdn.net/vic_torsun/article/details/79650865一文,解決了該問題,代碼如下:

try {
     socket = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
     System.out.println(socket.isConnected());
     socket.connect();
     System.out.println(socket.isConnected());
     os = socket.getOutputStream();
     is = socket.getInputStream();
} catch (IOException e) {
     Toast.makeText(context, "1.連接失敗!", Toast.LENGTH_SHORT).show();
     try {
          socket = (BluetoothSocket) device.getClass().
             getMethod("createRfcommSocket", new Class[]{int.class}).invoke(device, 1);
          socket.connect();
     } catch (Exception e1) {
        try {
            socket.close();
        } catch (IOException e2) {
            e2.printStackTrace();
        }
        Toast.makeText(context, "未搜索到藍牙設備或藍牙設備未打開!", 
             Toast.LENGTH_SHORT).show();
     }
     return;
} catch (Exception e) {
     e.printStackTrace();
}

斷後重新連接則需要設置實時監聽,利用廣播進行藍牙狀態監聽,同時在廣播中設置接口將對應的信息返回到廣播接收者,實現邏輯很簡單:斷開——>監聽斷開——>嘗試重新連接,其中需要加入心跳監測,這裏利用的是Handler+Runnable的方式定時進行監測,具體代碼如下:

private Handler blueHandler = new Handler();
private Runnable blueRunnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("定時Handler!");
        if (IsConnect == false) {
            bluetoothTools.cancelDiscovering();
            System.out.println("設備未連接!");
            bluetoothTools.startDiscovery();
        } else {
            System.out.println("設備連接正常!");
        }
        blueHandler.postDelayed(this, Heart_BEAT_RATE);
    }
};

在連接成功後和斷開連接後,分別重置監聽器,這樣可以避免監聽過程中發生連接衝突,從而導致異常,中斷後重新連接的部分代碼:

else if (message.equals(BTReceiver.ACTION_ACL_DISCONNECTED)) {
  IsConnect = false;
  blueHandler.removeCallbacks(blueRunnable);
  blueHandler.postDelayed(blueRunnable, Heart_BEAT_RATE);
}

本文僅將思路和一些代碼片段寫下來記錄一下,希望有用!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章