场景:控制端——普通手机;被控制端——XX设备(无屏幕、无法用户操作、有系统权限)
有关蓝牙通讯的文章,网上有很多,也有免费的开源代码下载,BluetoothChatService和BluetoothUtil是核心代码。(找不到源码的可以联系我的邮箱,欢迎交流)过多的实现细节,这里不会赘述,仅讲述一下我在开发过程中,遇到的问题及解决方案。
蓝牙通讯过程:蓝牙开启——找到设备——配对——建立蓝牙socket连接——通讯协议;然后,再搭建你的业务逻辑。该代码实现的蓝牙连接为1对1的模式,因此,当你发现控制端反复连不上XX设备时,请注意检查是否已有控制端连接到了你想控制的XX设备。
简单轻量地使用蓝牙socket收发,应该没有问题。我遇到的问题是数据包截断——当一次发送的数据长度超过1KB时,会自动截断。因此,当你需要一次发送较大数据量时,需要小心处理。
抛砖引玉,我的处理办法详述如下:
在发送端的处理:

private static String END_FLAG = "XVOaVb77FMYHyeTx";//采用16位随机数做结束标记符
public void sendMessage(String message) {// Check that we're actually connected before trying anythingif (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {//Toast.makeText(App.getInstance(), R.string.not_connected, Toast.LENGTH_SHORT).show();logd("not connected yet.");return;}//logd("send:"+message);// Check that there's actually something to sendif (message.length() > 0) {// Get the message bytes and tell the BluetoothChatService to writeStringBuilder stringBuilder = new StringBuilder();stringBuilder.append(message).append(END_FLAG);//用结束符来标记,防止数据过长,导致控制端因数据截断而无法识别的问题byte[] send = stringBuilder.toString().getBytes();mChatService.write(send);}}

接收端的处理:

    private class ConnectedThread extends Thread {private final BluetoothSocket mmSocket;private final InputStream mmInStream;private final OutputStream mmOutStream;public ConnectedThread(BluetoothSocket socket, String socketType) {logd("create ConnectedThread: " + socketType);mmSocket = socket;InputStream tmpIn = null;OutputStream tmpOut = null;// Get the BluetoothSocket input and output streamstry {tmpIn = socket.getInputStream();tmpOut = socket.getOutputStream();} catch (IOException e) {logd("temp sockets not created"+e);}mmInStream = tmpIn;mmOutStream = tmpOut;}public void run() {logd("BEGIN mConnectedThread");byte[] buffer = new byte[1024];int bytes;StringBuilder stringBuilder = new StringBuilder();// Keep listening to the InputStream while connectedwhile (true) {try {// Read from the InputStreambytes = mmInStream.read(buffer);stringBuilder.append( new String(buffer, 0, bytes));//logd("length="+stringBuilder.length());if (stringBuilder.toString().contains(END_FLAG) && stringBuilder.toString().endsWith(END_FLAG)) {String[] msgs = stringBuilder.toString().split(END_FLAG);for (String s : msgs) {mHandler.obtainMessage(BluetoothUtil.MESSAGE_READ, bytes, -1, s).sendToTarget();}stringBuilder = new StringBuilder();}} catch (IOException e) {logd("disconnected"+e);connectionLost();// Start the service over to restart listening modeBluetoothChatService.this.start();break;}}}

该处理办法经过实际验证是可行的。
另外,使用指定mac的连接方式,作为client端通常是已知对端的蓝牙mac的,而若server端要知道client的蓝牙mac,可以在如下节点获取并做一下保存(AcceptThread中的run方法):

// Listen to the server socket if we're not connectedwhile (mState != STATE_CONNECTED) {try {// This is a blocking call and will only return on a// successful connection or an exceptionsocket = mmServerSocket.accept();} catch (IOException e) {logd("Socket Type: " + mSocketType + "accept() failed"+e);break;}// If a connection was acceptedif (socket != null) {synchronized (BluetoothChatService.this) {switch (mState) {case STATE_LISTEN:case STATE_CONNECTING:// Situation normal. Start the connected thread.clientDevie = socket.getRemoteDevice();//在这里可以做一下记录logd("client device address :" + clientDevie.getAddress());connected(socket, clientDevie, mSocketType);break;case STATE_NONE:case STATE_CONNECTED:// Either not ready or already connected. Terminate new socket.try {socket.close();} catch (IOException e) {logd("Could not close unwanted socket"+e);}break;}}}}

这份代码存在一些crash的bug,例如BluetoothChatService没有退出就直接关闭掉蓝牙会出现crash,因此最好注册蓝牙状态的广播监听,若收到“BluetoothAdapter.STATE_TURNING_OFF”的广播,就直接调用BluetoothChatService的stop方法,及时退出。

蓝牙开发经验小结——蓝牙通讯相关推荐

  1. 针对蓝牙4.0 BLE通讯过程的逆向和攻击

    本文讲的是针对蓝牙4.0 BLE通讯过程的逆向和攻击,从6个月前,我就开始针对BLE设备进行学习和研究,其中接触到了一些关于BLE逆向的博客和文章,但是相关内容都没有给出很好的方案.因此通过我的这篇文 ...

  2. Android App 连接ble蓝牙模块并进行通讯

    Android App 连接ble蓝牙模块并进行通讯 对于蓝牙的基础知识我在这里就不赘述了,直接来干货,讲解连接ble蓝牙模块并进行通讯,通讯使用广播模式,结尾附上一个项目的demo.精彩内容即将开始 ...

  3. android项目监听蓝牙连接,android 蓝牙ACL通讯详解

    本文主要是讲述android中蓝牙ACL链接的详细介绍,这里只讲述ACL,不讨论BLE,SCO,等等其他通讯通道,后面如果我有兴趣研究,我会贴上对应的文章链接 github下载地址 同时也是一个可直接 ...

  4. BLE 蓝牙网关与蓝牙定位

    参考:[IoT]BLE 蓝牙网关与蓝牙定位技术解析 地址:https://blog.csdn.net/liwei16611/article/details/85245109?spm=1001.2014 ...

  5. 经典蓝牙和低功耗蓝牙(BLE)有什么区别?

    蓝牙模块Bluetooth module)是指集成蓝牙功能的芯片基本电路集合,用于短距离2.4G的无线通讯模块.对于最终用户来说,蓝牙模块是半成品,通过在模块的基础上功能再开发.封装外壳等工序,实现能 ...

  6. android蓝牙聊天设备,Android蓝牙开发——实现蓝牙聊天

    最近课上刚好需要做一个课程设计关于蓝牙的就挑选了个蓝牙聊天室,其实关键还是在于对蓝牙API的了解 一.蓝牙API 与蓝牙开发主要的相关类是以下四个 BluetoothAdapter 字面上则理解为蓝牙 ...

  7. 【Android】蓝牙开发——经典蓝牙:配对与解除配对 实现配对或连接时不弹出配对框

    目录 一.配对方法 二.解除配对方法 三.配对/解除配对结果 四.justwork配对模式下,不弹出配对框 五.pincode配对模式下,不弹出配对框 六.小结 在之前的文章[Android]蓝牙开发 ...

  8. 【蓝牙系列】蓝牙5.4到底更新了什么(2)

    [蓝牙系列]蓝牙5.4到底更新了什么(2) 一. 背景   上一篇文章讲了蓝牙5.4的PAwR特征,非常适合应用在电子货架标签(ESL)领域, 但是实际应用场景中看,只有PAwR特性是不够的,如何保证 ...

  9. android苹果蓝牙版本,苹果蓝牙和安卓蓝牙能连吗

    大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答. 苹果蓝牙和安卓蓝牙能连: 1.首先,在的苹果手机的设置,找到蓝牙,然后打开它: 2.接着,拿起安卓手机,找到设置里的蓝牙,点击一下 ...

最新文章

  1. 共模电感适用的频率_【连载】手机常见电子元件介绍数据共模电感
  2. 【Python基础】GitHub 星标 8.8w+,Python 小白 100 天学习计划,从新手到大师!
  3. xlsx文件打开乱码_Excel 2016 双击无法打开xlsx文件怎么办?
  4. rocketmq批量消费
  5. matlab层次分析法程序购置设备,[转载]MATLAB实现层次分析程序
  6. Android系统性能优化(68)---绘制优化
  7. 将C#Lambda表达式转换为通用过滤器描述符和HTTP查询字符串
  8. inPixio Photo Studio 11(图片编辑软件)官方正式版V11.0.7709.20526 | 超好用的图片编辑器
  9. android+6.0中兴v5s,中兴v5s
  10. latex论文模板双栏
  11. easyui框架中动态改变表头
  12. mac教程:磁力种子qBittorrent 使用教程
  13. 空洞卷积(扩张卷积dilated convolution)
  14. linux检测扩容卡,怎么检测SD卡是否被扩容过?对SD卡进行扩容检测的方法
  15. 解决Oracle安装过程中出现的缺少KEY_XE.reg文件的问题
  16. 两个分数化简比怎么化_分数比化简比练习题及答案.doc
  17. ESP8266+0.96OLED驱动显示(I2C)
  18. 我与CSDN的2020
  19. S60,UIQ机型及其对应的系统版本清单
  20. python opencv写视频——cv2.VideoWriter()

热门文章

  1. PLC模拟量输入的软件滤波使用方法
  2. sourcetree的使用方法
  3. implicitly has an ‘any‘ type...以及suppressImplicitAnyIndexErrors版本错误TypeScript 5.5问题
  4. 有效的括号长按键入验证外星语词典字符的最短距离用栈实现队列
  5. ffmpeg命令详细说明
  6. Vulkan学习(十五): 总结
  7. Oracle 10g 32位 下载地址
  8. linux连接到sqlserver命令行,Linux 下连接sqlserver (上)
  9. 使用canvas制作背景水印
  10. 动态壁纸android,Android 十大最新版本动态壁纸大盘点