蓝牙之数据传输问题

蓝牙数据传输问题

对于蓝牙来说google已经封装好了很多api所以使用起来并不会很难,但是实际开发中蓝牙开发最头疼的问题不是如何去调用api,而是数据的交互方面,如长连接,数据续传,硬件接受速率等问题.

打开蓝牙有几种方式?

首先我们先了解下几种常用的打开方式.

  • 第一种方法相对简单,直接调用系统对话框启动蓝牙:

    在AndroidManifest文件中添加需要的权限,高版本也不需要动态授权:

<uses-permission android:name="android.permission.BLUETOOTH" />
//处理回调对话框
startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), 1);
  • 第二种方法,静默开启,不会有方法一的对话框:

    在AndroidManifest文件中添加需要的权限:

    • 在AndroidManifest中配置需要的权限.
    • 对于6.0的运行时权限进行适配,在java中动态授权.
    • 最后直接调api开启
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.enable(); //开启
//mBluetoothAdapter.disable(); //关闭

如何搜索蓝牙设备?

搜索分为:主动搜索和被动搜索。

  • 主动搜索

    • 创建BluetoothAdapter对象
    • 配对的蓝牙设备列表
    • 定义发送接收广播

蓝牙的UUID是什么?有什么用?

UUID(Universally Unique Identifier) 统一表示定义.

蓝牙是通过串口发送AT命令,蓝牙默认是在数据模式的,要配置为AT命令模式,对其进行设置,不过UUID在出厂前是设置过的.

对于蓝牙设备,每个服务都有一个与它对应的UUID(唯一的).

如:

信息同步服务:00001104-0000-1000-8000-00805F9B34FB

文件传输服务:00001106-0000-1000-8000-00805F9B34FB

如何使用蓝牙进行数据传输?

蓝牙模块通信最重要的地方就是数据的发送和接收,其传输数据与Socket类似。

  • 在网络中使用Socket和ServerSocket控制客户端和服务端的数据读写。
  • 而蓝牙通讯也由客户端和服务端Socket来完成。蓝牙客户端Socket是BluetoothSocket,蓝牙服务端Socket是BluetoothServerSocket。这两个类都在android.bluetooth包中。
  • 无论是BluetoothSocket,还是BluetoothServerSocket,都需要一个UUID(全局唯一标识符,Universally Unique Identifier),UUID相当于Socket的端口,而蓝牙地址相当于Socket的IP。

实际开发中需要注意的地方.

需要注意的

1. 因为涉及涉及到I/O编程,所以需要注意两端的编码’utf-8’要一致.

2. 客户端与服务端的UUID也要相同.

3. 蓝牙属于底层数据传输,所以实际开发更多发送的是16进制数据.

4. 因为涉及到了I/O编程,所以对线程控制这块(同步,锁机制)需要注意使用.

5. 对于一些大容量字节数组的发送需要注意的地方.

6. 为了用户更好的体检避免流量的过度浪费,使用阻塞式的InputStream读取.

1. 因为涉及涉及到I/O编程,所以需要注意两端的编码’utf-8’要一致.

os.write("datas....".getBytes("utf-8"));

2. 客户端与服务端的UUID也要相同.

//客户端Socket
device.createRfcommSocketToServiceRecord(MY_UUID);
//服务端Socket
mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);

3. 蓝牙属于底层数据传输,所以实际开发更多发送的是16进制数据.

public static String bytesToHexString(byte[] bytes) {
        String result = "";
        for (int i = 0; i < bytes.length; i++) {
            String hexString = Integer.toHexString(bytes[i] & 0xFF);
            if (hexString.length() == 1) {
                hexString = ‘0‘ + hexString;
            }
            result += hexString.toUpperCase();
        }
        return result;
    }

5. 对于一些大容量字节数组的发送需要注意的地方.

我们需要发送64个字节的数组,如果一次性发送过去,单片机那里可能无法及时处理以致没有任何回应,因为单片机那里是设置了数据接收的延时时间。要想畅通的与蓝牙模块通信,考虑这个时间差非常重要。调整字节的发送速率,就成为非常关键的一步。值得注意的是,数据的发送是非常快的,就是因为这样才会导致单片机那里无法及时处理,所以,每次发送后的延时是非常重要的。我们单片机那里的延时是10毫秒,所以我们选择发送完每个字节后就延时10毫秒再发下个字节。

 for (byte b : bytes) {
     out.write(b);
     Thread.sleep(10);
 }

6.为了用户更好的体检避免流量的过度浪费,使用阻塞式的InputStream读取.

在使用InputStream的时候,必须注意,InputStream的读取是阻塞的。这点在一般的情况下是不会影响到我们的程序,但是记住这个情况对于代码的设计是非常重要的,尤其是在考虑用户体验的时候。

无参数的read()是每次只从流中读取一个字节,这种做法效率非常低,但是简单,像是读取整数值这种情况,使用read()就非常好,但如果是16进制字符串呢?使用InputStream.read(byte[] b)或者InputStream.read(byte[] b,int off,int len)方法,这样一次就能读取多个字节。

如果是读取多个字节,我们常常使用InputStream.available()方法来获取数据流中可读字节的个数。读取本地数据的时候,该方法发挥得非常好,但如果是读取非本地数据,就可能出现字节遗漏的问题,像是要读取100个字节,可能就是90个,甚至是0个。

出现0个的情况就是单片机那边没有响应或者字节还没发送过来,这时我们就需要一个循环来保证我们能够拿到数据:

  int count = 0;
  while (count == 0) {
   count = in.available();
  }
  byte[] bytes = new byte[count];
  in.read(bytes);
      但像是上面的90个字节的情况就是字节遗漏。对于这种情况,解决方法也很简单:
  byte[] bytes = new byte[count];
  int readCount = 0; // 已经成功读取的字节的个数
  while (readCount < count) {
   readCount += in.read(bytes, readCount, count - readCount);
  }

部分内容参考链接

时间: 2024-10-24 13:21:52

蓝牙之数据传输问题的相关文章

蓝牙的发展史

蓝牙技术最初由爱立信创制,始于爱立信公司的1994方案,它是研究在移动电话和其他配件间进行低功耗.低成本无线通信连接的方法. 发明者希望为设备间的通讯创造一组统一规则(标准化协议),以解决用户间互不兼容的移动电子设备. 1997年前爱立信公司此概念接触了移动设备制造商,讨论其项目合作发展,结果获得支持.蓝牙是创新与勇于尝试的象征. 1999年5月20日,索尼爱立信.IBM.英特尔.诺基亚及东芝公司等业界龙头创立"特别兴趣小组"(Special Interest Group,SIG),即

最全最详细的蓝牙版本介绍包含蓝牙4.0和4.1

概述:蓝牙核心规范发展的主要版本: 表1  蓝牙核心规范发展介绍 版本 规范发布 增强功能 0.7 1998.10.19 Baseband.LMP 0.8 1999.1.21 HCI.L2CAP.RFCOMM 0.9 1999.4.30 OBEX与IrDA的互通性 1.0 Draft 1999.7.5 SDP.TCS 1.0 A 1999.7.26 第一个正式版本 1.0 B 2000.10.1 安全性,厂商设备之间连接兼容性 1.1 2001.2.22 IEEE 802.15.1 1.2 20

BLK-MD-BC04-B蓝牙模块开发说明

BLK-MD-BC04-B蓝牙模块开发说明 日期:2011-9-24?浏览次数:4178 ? ? BLK-MD-BC04-B蓝牙通信模块, BLK-MD-BC04-B蓝牙通信模块?为本公司自主开发的智能型无线数据传输产品,高灵敏性接收,低成本,体积小巧,低功耗,用于蓝牙的数据传输领域. BlueCore4-Ext芯片,完全兼容蓝牙2.0规范 Uart接口,支持1200bps~2764800bps等多种波特率 支持SPP协议最高可支持3M调制模式 外围IO口通信 内建8M Flash可视及对等条件

Android蓝牙4.0之玩爆智能穿戴、家具(二)【进阶篇】

闲话中心 这几天最大的事可能就是美国总统的上任,双十一,还有乐视股价了,乍一看,好像和我们没什么关系,其实肯定是有的了,要不然他也成不了新闻啊,有一点我们得改变,就是我们必须要希望我们自己国家的企业能过强大,我们必须支持他们,哪怕他做的不够好,这个问题其实就像一个国家一样,我们都知道许多政策是不合理的,或者说有很多制度是坑人的,但是我们不能因为这些而不爱我们的国家,那么企业也是一样,就拿乐视来说,股价跌了,公司遇到资金问题了,你看看这些媒体都在报道什么,全是负面消息,马上倒闭了,或者说是撑不住了

Android开发之蓝牙通信

时隔半年时间,又遇到了蓝牙开发了,之前是蓝牙连接打印相关方面的,这次需要蓝牙配对数据传输,折腾过去折腾过来,也就那么回事,下定决心系统的梳理这块的知识 蓝牙开发必练基本功 蓝牙权限 为了在您的应用程序中使用蓝牙功能,您必须声明蓝牙权限蓝牙.您需要此权限来执行任何蓝牙通信,如请求一个连接.接受一个连接和传输数据.如果你想让你的应用启动设备发现或操纵蓝牙设置,你也必须申报bluetooth_admin许可.大多数应用程序都需要此权限,仅用于发现本地蓝牙设备的能力.此权限授予的其他权限不应被使用,除非

基于Android平台的i-jetty网站智能农业监控系统

基于android平台i-jetty网站的智能农业监控系统 摘要:传统的监控系统,一般是基于PC的有线通信传输,其有很多不足之处,如功耗较高.布线成本高.难度大,适应性差,可扩展性不强,增加新的通信线路需要再次布线施工,而且维护起来也比较麻烦,一旦线路出问题,需要繁琐的检查.而嵌入式Web监控系统是基于物联网技术,其无线通信技术具有成本低廉.适应性强.扩展性强.信息安全.使用维护简单等优点. 智能农业中,种植大棚是通过大棚内安装温湿度以及光照传感器,来对农作物的环境参数进行实时采集,由Web监控

iOS 后台运行 类型

iOS后台运行,需要有特定的类型才可以进行.这些内容并不是一直不变的,苹果也在逐步的更新这些内容. 本文内容是2015年11月03日时苹果支持的后台运行类型. 这是官方连接地址 其中较为重要的是下面这张表,我已截图出来. 解释一下: 1. 音频播放和录制: 2. 位置更新: 3. VOIP: *4. 后台下载(此处指预更新): 5. 使用External Accessory framework库(通常是通过MFI认证的蓝牙应用): 6. 蓝牙应用(使用Core Bluetooth framewo

物联网常见通信协议梳理

1  概述 在上一篇文章<物联网常见通信协议与通讯协议梳理[上]-通讯协议>中,对物联网常用通信协议和通讯协议作了区分,并对通讯协议进行了分享:本文将对常用的通信协议进行剖析,重点面向市场上使用率较高的,且又不是诸如TCP/IP之类老生常谈的. 2  近距离通信协议 2.1  RFID RFID的空中接口通信协议规范基本决定了RFID的工作类型,RFID读写器和相应类型RFID标签之间的通讯规则,包括:频率.调制.位编码及命令集.ISO/IEC制定五种频段的空中接口协议. (1)ISO/IEC

国内外移动医疗10家标志性模式:硬件+软件

原文链接:http://www.yicai.com/news/2014/02/3455198.html 国际医疗卫生会员组织HIMSS对移动医疗的定义为,mHealth,就是通过使用移动通信技术——例如PDA.移动电话和卫星通信来提供医疗服务和信息.最近几年随着移动医疗大环境的改善,特别是穿戴式设备的兴起,移动医疗软硬件商家也迎来了爆发式发展,同时也给市场和投资人带来了无尽的想象. 大环境1:据国外咨询报告称,2012年全球移动医疗产业将达到600亿美元规模,目前年复合增长率达到30%-40%,