1.  

  首先,这个库是用于BLE(低功耗蓝牙)通信的,地址:https://github.com/dingjikerbo/BluetoothKit

  1.  

当然,也可以选择根据andorid提供的底层接口自己完成这部分的通信,这个库优点在于确实很方便使用,基本都是回调就能完成。作者好像也是前就职于阿里?

 介绍下用法:

   先在gradle加入:

  1. compile 'com.inuker.bluetooth:library:1.4.0'

  在Menifest中配置:

  (ps:在6.0以上需要使用动态权限)

  1. <uses-permission android:name="android.permission.BLUETOOTH" />
  2. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  3. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  4. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  5.  
  6. <uses-feature
  7. android:name="android.hardware.bluetooth_le"
  8. android:required="true" />
  9.  
  10. <application
  11. android:label="@string/app_name">
  12. <service
  13. android:name="com.inuker.bluetooth.library.BluetoothService" />
  14. </application>

 在Application里设置

  

  1. BluetoothContext.set(this);

 核心类BluetoothClient,创建一个这样的单例对象,可以借用其例子中的ClientManager类

  1. BluetoothClient mClient = new BluetoothClient(context); //自己写
  2. BluetoothClient mClient = ClientManager.getClient(); //借用作者的ClientManager

  一般都需要做个扫描界面来选择设备吧,这个库是支持普通蓝牙和低功耗蓝牙混扫的

  1. SearchRequest request = new SearchRequest.Builder()
  2. .searchBluetoothLeDevice(3000, 3) // 先扫BLE设备3次,每次3s
  3. .searchBluetoothClassicDevice(5000) // 再扫经典蓝牙5s
  4. .searchBluetoothLeDevice(2000) // 再扫BLE设备2s
  5. .build();
  6.  
  7. mClient.search(request, new SearchResponse() {
  8. @Override
  9. public void onSearchStarted() {
  10.  
  11. }
  12.  
  13. @Override
  14. public void onDeviceFounded(SearchResult device) {
         //发现设备
  15. Beacon beacon = new Beacon(device.scanRecord);
         //beacon用于解析广播
  16. BluetoothLog.v(String.format("beacon for %s\n%s", device.getAddress(), beacon.toString()));
         //device对象就包括了设备的mac地址和蓝牙名称 ,将device放在list里面 按mac地址做唯一区别
  17. }
  18.  
  19. @Override
  20. public void onSearchStopped() {
  21.       //扫描停止
  22. }
  23.  
  24. @Override
  25. public void onSearchCanceled() {
  26.       //扫描取消
  27. }
  28. });

手动停止扫描:

  1. mClient.stopSearch();

 

 通过上面的代码我们可以完成设备的扫描,获取到扫描结果,也可以得到目标设备的mac地址;

 广播的作用是可以不连接设备,就能够获取到设备的一些信息,比如电量或者其他的一些厂家信号;

言归正传,我们得到了mac地址就可以连接设备了,通过一些代码既可以完成连接设备:

  1. //连接参数
  2. BleConnectOptions options = new BleConnectOptions.Builder()
  3. .setConnectRetry(2) // 连接如果失败重试2次
  4. .setConnectTimeout(3000) // 连接超时3s
  5. .setServiceDiscoverRetry(2) // 发现服务如果失败重试3次
  6. .setServiceDiscoverTimeout(2000) // 发现服务超时2s
  7. .build();
  8.  
  9. mClient.connect(MAC, options, new BleConnectResponse() {
  10. @Override
  11. public void onResponse(int code, BleGattProfile data) {
  12.  
  13. }
  14. });

 个人建议不能确定双方通信都及其正常的情况下,是需要设置连接参数的,可以保证连接的成功率。如果要监听蓝牙连接状态可以注册回调,只有两个状态:连接和断开,建议把监听设置放在连接前面

  1. mClient.registerConnectStatusListener(MAC, mBleConnectStatusListener);
  2.  
  3. private final BleConnectStatusListener mBleConnectStatusListener = new BleConnectStatusListener() {
  4.  
  5. @Override
  6. public void onConnectStatusChanged(String mac, int status) {
  7. if (status == STATUS_CONNECTED) {
  8.       //连接
  9. } else if (status == STATUS_DISCONNECTED) {
  10.       //断开
  11. }
  12. }
  13. };
  14.  
  15. mClient.unregisterConnectStatusListener(MAC, mBleConnectStatusListener);

  也可以通过mClient获取连接状态:

  1. int status = mClient.getConnectStatus(MAC)

  连接成功后一般都要打开notify使能,以便获得硬件回复的数据:

  1. //打开notify
    mClient.notify(MAC, serviceUUID, characterUUID, new BleNotifyResponse() { //是notify的UUID
  2. @Override
  3. public void onNotify(UUID service, UUID character, byte[] value) {
  4. //硬件回复的数据在这里,统一处理
          handleResult(value);
  5. }
  6.  
  7. @Override
  8. public void onResponse(int code) {
  9. if (code == REQUEST_SUCCESS) {
  10.       //我一般都在打开notify成功后才开始发送数据
  11. }
  12. }
  13. });
  14.  
  15. //关闭notify
  1. mClient.unnotify(MAC, serviceUUID, characterUUID, new BleUnnotifyResponse() {
  2. @Override
  3. public void onResponse(int code) {
  4. if (code == REQUEST_SUCCESS) {
  5.  
  6. }
  7. }
  8. });

  写数据,只有通过mClient.write写数据才有可能收到notify回来的数据,如果通过writeNoRsp写是不可能收到的,作者注明writeNoRsp建议用于固件升级:

  1. mClient.write(MAC, serviceUUID, characterUUID, bytes, new BleWriteResponse() {
  2. @Override
  3. public void onResponse(int code) {
  4. if (code == REQUEST_SUCCESS) {
  5.  
  6. }
  7. }
  8. });

  这样就可以实现write-->notify的读写操作了。

  说一些我遇到的问题:

  1.android6.0以上动态权限不仅需要蓝牙相关权限,还需要GPS权限,必须保证GPS也打开,才能正常搜索;

  2.连接速度问题,经测试,这个库在nexus5上连接较慢,底层从发现设备到发现服务有时候甚至需要2,3s左右;

  3.部分设备有时候出现 notify 返回 -1,尝试过在连接的时候把扫描停止了,有好转,不过并未彻底解决;

  4.在部分华为机型上蓝牙连接不稳定

  5.一定要在Application里设置  BluetoothContext.set(this);

关于Ble通信库BluetoothKit的使用 以及可能出现的问题分析的更多相关文章

  1. ZeroMQ:云时代极速消息通信库

    ZeroMQ:云时代极速消息通信库(大规模|可扩展|低成本|高效率解决之道,大规模分布式|多线程应用程序|消息传递架构构建利器) [美]Pieter Hintjens(皮特.亨特金斯)著   卢涛 李 ...

  2. 清晰易懂TCP通信原理解析(附demo、简易TCP通信库源码、解决沾包问题等)C#版

    目录 说明 TCP与UDP通信的特点 TCP中的沾包现象 自定义应用层协议 TCPLibrary通信库介绍 Demo演示 未完成功能 源码下载 说明 我前面博客中有多篇文章讲到了.NET中的网络编程, ...

  3. 消息通信库ZeroMQ 4.0.4安装指南

    一.ZeroMQ介绍 ZeroMQ是一个开源的消息队列系统,按照官方的定义,它是一个消息通信库,帮助开发者设计分布式和并行的应用程序. 首先,我们需要明白,ZeroMQ不是传统的消息队列系统(比如Ac ...

  4. Linux Ubuntu安装Nvidia多GPU通信库NCCL

    0. 前言 在使用Python版本的PaddleDetection进行一些实验时,想同时利用多个GPU提高效率,遇到了一点问题 You may need to install 'nccl2' from ...

  5. 【深入浅出 Yarn 架构与实现】2-2 Yarn 基础库 - 底层通信库 RPC

    RPC(Remote Procedure Call) 是 Hadoop 服务通信的关键库,支撑上层分布式环境下复杂的进程间(Inter-Process Communication, IPC)通信逻辑, ...

  6. Android BLE设备蓝牙通信框架BluetoothKit

    BluetoothKit是一款功能强大的Android蓝牙通信框架,支持低功耗蓝牙设备的连接通信.蓝牙广播扫描及Beacon解析. 关于该项目的详细文档请关注:https://github.com/d ...

  7. c# 说说开发通用通信库,尤其是分布式服务的通信

    来,牛皮需要吹起,IT行业需要自娱自乐.开篇吹牛..... 现在我们通信真是各种各样,各种组件,但是就我的看法,功能越完善,封装越完善,牺牲的性能可能就越大,代码量就越大. 当然这不能阻挡IT大军的脚 ...

  8. Android组件间通信库EventBus学习

    项目地址:   https://github.com/greenrobot/EventBus EventBus主要特点 1. 事件订阅函数不是基于注解(Annotation)的,而是基于命名约定的,在 ...

  9. NetLink通信原理研究、Netlink底层源码分析、以及基于Netlink_Connector套接字监控系统进程行为技术研究

    1. Netlink简介 0x1:基本概念 Netlink是一个灵活,高效的”内核-用户态“.”内核-内核“.”用户态-用户态“通信机制.通过将复杂的消息拷贝和消息通知机制封装在统一的socket a ...

随机推荐

  1. 第八节 JS运动基础

    运动基础 让Div运动起来 速度——物体运动的快慢 运动中的Bug 不会停止 速度取某些值会无法停止 到达位置后再点击还会运动 重复点击速度加快 匀速运动(速度不变) 运动框架及应用: 运动框架: 在 ...

  2. python爬虫——绕开杂乱无章的代码和堵住请求的302异常(2)

    淘宝那次抓包,居然发现不了要抓的url位置,三星中... 不过不怕,不就是没法快点分析出包嘛,下次用phantomJS硬杠,或者有时间慢慢分析也好. 今天挑战一个稍微好爬的网站:狗搬家(误) 打开后台 ...

  3. Html lable 标签

    Html lable 标签 <html> <body> <!-- label 关联光标标签,点击文字使得关联的标签获取光标.for="username" ...

  4. Docker Swarm 负载均衡详解 or 模式选择

    Docker Swarm 负载均衡详解 Swarm模式内置DNS组件,可以自动为集群中的每个服务分配DNS记录. Swarm manager使用内部负载均衡,根据服务的DNS名称在集群内的服务之间分发 ...

  5. 结合iconworkshop,创建ribbon界面

    mfc实现的程序中,ribbon界面是主流,比较适合测量类项目.几个修改图标的小技巧: 1.现有的bmp,可以直接修改 在好几个地方,已经将IDB_*和显示效果对接清楚了,直接修改这里的bmp,就可以 ...

  6. SVN冲突以及解决办法

    1.冲突原因: 假设 A.B 两个用户都在版本号为 100 的时候,更新了 kingtuns.txt 这个文件,A 用户在修改完成之后提交 kingtuns.txt 到服务器, 这个时候提交成功,这个 ...

  7. Mac OS X 避免产生临时文件 .DS_Store

    参考: 删除Mac中所有 .DS_Store 隐藏文件 Mac OS X 避免产生临时文件 .DS_Store .DS_Store 隐藏文件保存针对目录的特殊信息和设置配置,例如查看方式,图标大小以及 ...

  8. hduoj 1002 A + B Problem II

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 题目描述如下: A + B Problem II Time Limit: 2000/1000 M ...

  9. stlcky footers布局小技巧

    sticky-footer解决方案 在网页设计中,Sticky footers设计是最古老和最常见的效果之一,大多数人都曾经经历过.它可以概括如下:如果页面内容不够长的时候,页脚块粘贴在视窗底部:如果 ...

  10. win平台下Path变量消失问题

    解决方法:2019.01.10文章转载自 李北北:https://www.jianshu.com/p/b89f0c99867e 问题描述:修改了path变量,但是环境变量中path消失,于是想再次打开 ...