经典蓝牙那些事儿——(登录、登录异常、自动连接、中断、断后重连等)

最近项目中用到传统蓝牙连接设备通讯,折腾了一周把基本功能实现了,这里简单记录一下。

蓝牙设备: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);
}

本文仅将思路和一些代码片段写下来记录一下,希望有用!

发布了72 篇原创文章 · 获赞 42 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/xiaoxun2802/article/details/96279155