github地址:https://github.com/qindachang/BluetoothLELibrary

该库只支持1对1连接,如果你想1对多设备连接,请移步至 BluetoothLE-Multi-Library

demo运行环境 Android Studio 2.3

低功耗蓝牙库。优势:

  1. 适配到Android5.0和Android6.0、7.0的扫描方式(速度极快)。
  2. 适配小米手机连接蓝牙操作。
  3. 适配三星手机发现服务、开启通知等。
  4. 支持直接连发数百条数据,而不用担心消息发不出。自带消息队列(终于可以像iOS一样啦,不用去写延时啦)。
  5. 支持同时开启多个通知。
  6. 可以连续操作发送数据、读取特征、开启通知,即使你在for循环中写也没问题,自带队列。
  7. 扫描操作支持-> 设置扫描时长、根据设备名称扫描、根据硬件地址扫描、根据服务UUID扫描、连接成功后自动关闭扫描。
  8. 队列定时设置,满足因公司需求蓝牙时间间隔。
  9. 设备信号强度、距离计算回调,可用于防丢器产品。

注意点:

  1. Android 6.0扫描蓝牙需要地理位置权限。 Google动态权限开源库:easypermissions
  2. Android 7.0扫描蓝牙需要地理位置权限,并且需要开启系统位置信息。 LocationUtils ApiLevelHelper
  3. 发送数据、开启通知、读取特征等操作,需要在onServicesDiscovered()发现服务之后才能进行。
  4. 连接设备之前最好先停止扫描(小米手机可能会出现不能发现服务的情况)。

入门指南

引入方式

添加依赖

作为第一步,依赖这个库添加到您的项目。如何使用库, Gradle是推荐的方式使用这个库的依赖。

添加以下代码在你的APP级别 app build.gradle:

compile 'com.qindachang:BluetoothLELibrary:0.7.4'

权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

5.0以上需要

<!-- 只有当你的 targets API 等于或大于 Android 5.0 (API level 21) 才需要此权限 -->
<uses-feature android:name="android.hardware.location.gps" />

6.0以上设备需要

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

代码

前戏

是否支持蓝牙

mBluetoothLe.isSupportBluetooth();

判断蓝牙是否打开

mBluetoothLe.isBluetoothOpen();

请求打开蓝牙

mBluetoothLe.enableBluetooth(activity.this);

关闭蓝牙

mBluetoothLe.disableBluetooth();

一、获取单例实例

BluetoothLe mBluetoothLe = BluetoothLe.getDefault();

二、初始化

mBluetoothLe.init(this);//必须调用init()初始化

或者使用配置方式进行初始化,这样你可以针对自己的蓝牙产品,做出个性化的蓝牙队列请求。

such as : 发送队列间隔时间设置,因某些公司蓝牙操作要求时间间隔,例如150ms间隔才能发送下一条数据

在Application的onCreate()方法中参照以下方式配置:

    public class BaseApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
BluetoothConfig config = new BluetoothConfig.Builder()
.enableQueueInterval(true)//开启队列定时
.setQueueIntervalTime(150)//设置定时150ms时长(才会发下一条),单位ms
.build();
BluetoothLe.getDefault().init(this, config);
}
}

当然,你也可以使用自动的方式来配置蓝牙队列请求。这个时间间隔是通过读取远程蓝牙设备的最小间隔和最大间隔计算得出,保证了队列的最大可用性。

    BluetoothConfig config = new BluetoothConfig.Builder()
.enableQueueInterval(true)
.setQueueIntervalTime(BluetoothConfig.AUTO)//发送时间间隔将根据蓝牙硬件自动得出
.build();
BluetoothLe.getDefault().init(this, config);

上述的读取远程蓝牙设备的最小间隔和最大间隔,你可以在连上蓝牙发现服务后读取:

        @Override
public void onServicesDiscovered(BluetoothGatt gatt) {
mStringBuilder.append("发现服务啦\n");
mTvText.setText(mStringBuilder.toString()); mHandler.postDelayed(new Runnable() {
@Override
public void run() {
//查看远程蓝牙设备的连接参数,如蓝牙的最小时间间隔和最大时间间隔等..
Log.d("debug", mBluetoothLe.readConnectionParameters().toString());
}
}, 1000);
}

在使用途中修改以上配置:

修改配置:

    BluetoothConfig config = new BluetoothConfig.Builder()
.enableQueueInterval(false)
.build();
mBluetoothLe.changeConfig(config);

三、扫描

扫描过程已携带6.0动态权限申请:地理位置权限

    mBluetoothLe.setScanPeriod(15000)//设置扫描时长,单位毫秒,默认10秒
.setScanWithDeviceAddress("00:20:ff:34:aa:b3")//根据硬件地址过滤扫描
.setScanWithServiceUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")//设置根据服务uuid过滤扫描
.setScanWithDeviceName("ZG1616")//设置根据设备名称过滤扫描
.setReportDelay(0)//如果为0,则回调onScanResult()方法,如果大于0, 则每隔你设置的时长回调onBatchScanResults()方法,不能小于0
.startScan(Activity activity);

根据多个硬件地址、服务uuid、设备名称过滤扫描,你可以这样:

    .setScanWithDeviceAddress(new String[]{"00:20:ff:34:aa:b3","f3:84:55:b4:ab:7f"})
.setScanWithServiceUUID(new String[]{"0000180d-0000-1000-8000-00805f9b34fb","6E400001-B5A3-F393-E0A9-E50E24DCCA9E"})
.setScanWithDeviceName(new String[]{"ZG1616","HaHa"})

获取蓝牙扫描状态:

mBluetoothLe.getScanning();

停止扫描

mBluetoothLe.stopScan();

四、连接蓝牙、蓝牙连接状态

	//发送数据、开启通知等操作,必须等待onServicesDiscovered()发现服务回调后,才能去操作
//参数:false为关闭蓝牙自动重连,如果为true则自动重连
mBluetoothLe.startConnect(false, mBluetoothDevice);

获取蓝牙连接状态:

mBluetoothLe.getConnected();

获取发现服务状态:

mBluetoothLe.getServicesDiscovered();

断开连接

mBluetoothLe.disconnect();

五、发送数据(到蓝牙特征)

	//以下两个参数为硬件工程师提供,请你与你司的硬件工程师沟通
private static final String SERVICE_UUID = "0000180d-0000-1000-8000-00805f9b34fb";
private static final String WRITE_UUID = "0000fff5-0000-1000-8000-00805f9b34fb"; mBluetoothLe.writeDataToCharacteristic(bytes, SERVICE_UUID, WRITE_UUID);

六、Notification类型通知

	private static final String SERVICE_UUID = "0000180d-0000-1000-8000-00805f9b34fb";
private static final String HEART_NOTIFICATION_UUID = "00002a37-0000-1000-8000-00805f9b34fb";
private static final String STEP_NOTIFICATION_UUID = "0000fff3-0000-1000-8000-00805f9b34fb";

开启一个通知

	mBluetoothLe.enableNotification(true, SERVICE_UUID, STEP_NOTIFICATION_UUID);

开启多个通知

    mBluetoothLe.enableNotification(true, SERVICE_UUID, new String[]{HEART_NOTIFICATION_UUID, STEP_NOTIFICATION_UUID});

七、Indication类型通知

开启一个通知

	mBluetoothLe.enableIndication(true, SERVICE_UUID, STEP_NOTIFICATION_UUID);

开启多个通知

    mBluetoothLe.enableIndication(true, SERVICE_UUID, new String[]{HEART_NOTIFICATION_UUID, STEP_NOTIFICATION_UUID});

八、读取数据

    private static final String SERVICE_UUID = "0000180d-0000-1000-8000-00805f9b34fb";
private static final String READ_UUID = "0000fff5-0000-1000-8000-00805f9b34fb"; mBluetoothLe.readCharacteristic(SERVICE_UUID, READ_UUID);

九、蓝牙信号强度、距离

    mBluetoothLe.setReadRssiInterval(2000)//设置读取信号强度间隔时间,单位毫秒
.setOnReadRssiListener(TAG, new OnLeReadRssiListener() {
@Override
public void onSuccess(int rssi, int cm) { }
});

停止监听蓝牙信号强度

mBluetoothLe.stopReadRssi();

监听

//监听扫描
//Every Bluetooth-LE commands status will be callback in here. Flowing listener:
mBleManager.setOnScanListener(TAG, new OnLeScanListener() {
@Override
public void onScanResult(BluetoothDevice bluetoothDevice, int rssi, ScanRecord scanRecord) { } @Override
public void onBatchScanResults(List<ScanResult> results) { } @Override
public void onScanCompleted() { } @Override
public void onScanFailed(ScanBleException e) { }
});

更多的类似于

mBleManager.setOnConnectListener(...)//监听连接
mBleManager.setOnNotificationListener(...)//监听通知
mBleManager.setOnIndicateListener(...)//监听通知
mBleManager.setOnWriteCharacteristicListener(...)//监听写
mBleManager.setOnReadCharacteristicListener(...)//监听读
mBleManager.setOnReadRssiListener(...)//监听信号强度

拥有TAG的监听将可以在多个界面中产生回调,这可以帮助你实现多个Activity或Fragment监听蓝牙状态的需求。如不使用TAG的监听,将只有一个回调。

使用TAG监听,需要在生命周期onDestroy()中调用mBluetoothLe.destroy(TAG); 如不使用TAG监听,需要在生命周期onDestroy()中调用mBluetoothLe.destroy();

其它

清理蓝牙缓存

请你在连接上蓝牙后,再执行这步操作

mBluetoothLe.clearDeviceCache();

关闭GATT

在你退出应用的时候使用

mBluetoothLe.close();

取消队列

假设当你在for循环中发送100条数据,想要在中途取消余下的发送

mBluetoothLe.clearQueue();

避免内存泄露

在Activity生命周期onDestroy() 中使用:

mBluetoothLe.destroy();

如果你使用了tag标签的监听,使用: (它的好处是你可以在多个界面产生多个相同的回调)

mBluetoothLe.destroy(TAG);

取消对应tag:

mBluetoothLe.cancelTag(TAG);

取消全部tag:

mBluetoothLe.cancelAllTag();

仍在补充

  1. 一连多台蓝牙设备

了解更多

  1. 强烈建议阅读Demo : MainActivity.java / activity_main.xml

  2. 如何在多个Activity和Fragment中使用:https://github.com/qindachang/BluetoothLELibrary/tree/master/app/src/main/java/com/qindachang/bluetoothlelibrary/ui/demo

BluetoothLELibrary 支持1对1连接的更多相关文章

  1. 配置开发支持高并发TCP连接的Linux应用程序全攻略

    http://blog.chinaunix.net/uid-20733992-id-3447120.html http://blog.chinaunix.net/space.php?uid=16480 ...

  2. 多进程解决datasnap支持的tcp长连接数量少的问题

    对于实时采集数据的项目,应用场景比如是这样的:5000客户端,每个客户端每隔500MS要给服务器上传一次数据. 大家知道,像INDY这种阻塞型的通信控件,所能支持的TCP长连接的一般地不能超过1000 ...

  3. Linux配置支持高并发TCP连接(socket最大连接数)

    Linux配置支持高并发TCP连接(socket最大连接数) Linux配置支持高并发TCP连接(socket最大连接数)及优化内核参数 2011-08-09 15:20:58|  分类:LNMP&a ...

  4. Putty——支持Telnet,ssh连接的连接软件

    简介 PuTTY 的官方网站:http://www.chiark.greenend.org.uk/~sgtatham/putty/,截止到 2007年6月,发布的最高稳定版本是 0.6.PuTTY 是 ...

  5. 编译一个支持django及mysqlclient连接的alpine镜像

    一切都不难,难的就是在alpine镜像里. 最后,使用了网上编译好mysqlclient的镜像,才搞定. 记录一下. 一,基础镜像Dockerfile https://github.com/tnir/ ...

  6. LinkedIn的即时消息:在一台机器上支持几十万条长连接

    最近我们介绍了LinkedIn的即时通信,最后提到了分型指标和读回复.为了实现这些功能,我们需要有办法通过长连接来把数据从服务器端推送到手机或网页客户端,而不是许多当代应用所采取的标准的请求-响应模式 ...

  7. 探讨.net Socket支持在线连接数量

    发现不少同学在用.NET做通讯的时候都关心一个问题,.NET能支持多少个在线连接.其实.net的通讯由winsocket所支持,既然由低层的winsocket所支持那.NET其端的接入连接数的受限完全 ...

  8. 自主研发异步通信框架Minma(支持长连接和短连接)

    Minma是英文Minma Is Not Mina的简称 该框架采用Java NIO的核心技术,实现了基于事件驱动的多线程异步通信框架,支持常见的长连接(腾讯QQ)和短连接(http通信) 对于开发人 ...

  9. 深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接(转)

    1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 stude ...

随机推荐

  1. trick点

    1.问题里有取模操作的时候,最后输出(ans+mod)%mod 2.涉及到输出实数0的时候要特判输出的会不是是-0.000000(因为0.00乘一个负的浮点数结果是-0.000000,乘一个正的浮点数 ...

  2. IntelliJ IDEA 常用快捷键总结

    个人使用频率的高低排序: Alt+enter               代码提示 Alt+7                查看类的方法 Alt+insert        生成get和set方法 ...

  3. xshell配置

    字体:DejaVu Sans Mono 或者 Consolas 11号

  4. 分布式缓存之Memcache

    〇.为什么要用分布式缓存 1.软件从单机到分布式 走向分布式第一步就是解决:多台机器共享登录信息的问题. 例如:现在有三台机器组成了一个Web的应用集群,其中一台机器用户登录,然后其他另外两台机器共享 ...

  5. 使用和不使用navigationbar分别处理显示和返回页面

    不使用navigationbar的情况下 AnnounceViewController *pushView = [[AnnounceViewController alloc]init];pushVie ...

  6. Node之父ry发布新项目deno:下一代Node

    https://mp.weixin.qq.com/s/1LcO3EqGV2iRlZ1aIrQeqw

  7. C 标准库 - <stdlib.h>

    C 标准库 - <stdlib.h> 简介 stdlib .h 头文件定义了四个变量类型.一些宏和各种通用工具函数. 库变量 下面是头文件 stdlib.h 中定义的变量类型: 序号 变量 ...

  8. weblogic中部署项目报错org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken .

    原因: 原因是weblogic要查找自己的antlr,和lib下面的antlr包冲突.... 解决方法: 在weblogic.xml添加 <container-descriptor>    ...

  9. APP公布到应用市场(苹果APP STORE+安卓各大应用市场)

    注意事项 1.应用要签名,为了以后可以顺利更新应用.要保持每次的签名一致,所以要妥善保管好签名数据. 2.进行公布測试,最好有个检查表,每次公布的时候进行核查. 苹果APP STORE 一.证书的导出 ...

  10. js json 对象

    JSON 语法规则 JSON 语法是 JavaScript 对象表示法语法的子集. 数据在名称/值对中 数据由逗号分隔 大括号保存对象 中括号保存数组 JSON 名称/值对 JSON 数据的书写格式是 ...