蓝牙开发经验小结——蓝牙通讯
来源:互联网 发布:南风知我意1七微百度云 编辑:程序博客网 时间:2024/06/04 19:21
场景:控制端——普通手机;被控制端——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 anything if (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 send if (message.length() > 0) { // Get the message bytes and tell the BluetoothChatService to write StringBuilder 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 streams try { 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 connected while (true) { try { // Read from the InputStream bytes = 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 mode BluetoothChatService.this.start(); break; } } }
该处理办法经过实际验证是可行的。
另外,使用指定mac的连接方式,作为client端通常是已知对端的蓝牙mac的,而若server端要知道client的蓝牙mac,可以在如下节点获取并做一下保存(AcceptThread中的run方法):
// Listen to the server socket if we're not connected while (mState != STATE_CONNECTED) { try { // This is a blocking call and will only return on a // successful connection or an exception socket = mmServerSocket.accept(); } catch (IOException e) { logd("Socket Type: " + mSocketType + "accept() failed"+e); break; } // If a connection was accepted if (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方法,及时退出。
阅读全文
0 0
- 蓝牙开发经验小结——蓝牙通讯
- 蓝牙开发经验小结——自动配对
- 蓝牙开发经验小结——自动文件传输(OBEX)
- 蓝牙通讯的开发
- Android蓝牙开发经验
- Android蓝牙开发教程(三)——蓝牙设备相互通讯
- 【android 蓝牙开发——传统蓝牙】
- iOS开发之蓝牙通讯
- 蓝牙通讯
- CSR蓝牙开发调试经验
- Android蓝牙通讯(三)————蓝牙通讯的实现
- 原生Android开发—蓝牙
- Android蓝牙聊天,蓝牙通讯
- Android蓝牙开发——蓝牙操作的步骤
- 【android 蓝牙开发——BLE(低功耗)蓝牙】
- Android蓝牙开发小实例—打开关闭蓝牙
- 实验二:蓝牙通讯功能开发
- Android蓝牙开发浅析 及 Android蓝牙通讯模块源码(Android蓝牙开发浅析 续)
- USER_LOGONID_DUP 请检查收款账号是不是自己的签约支付宝账号。 原因及处理
- python中的计时模块:time.time()
- Burp Suite基础教学 之Spider
- arpack库问题,原因未知(已解决)
- lssvm工具箱使用心得
- 蓝牙开发经验小结——蓝牙通讯
- There is no setter for property named 'storeId' in 'class com.auth.entity.Auth'
- Revit API之如何创建梯形墙及带正反面的墙【比目鱼原创】
- Android 音视频录制(3)——全关键帧视频录制(视频编辑必备)
- typedef学习笔记
- ios11 tableview下移
- select
- 数据为桥迈向智能,渤海财险数据架构智能化演进
- theano和keras安装