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. redis 延迟消息

    1.查询下redis 是否打开了键空间通知功能 发现打开了,如果没有打开可以在执行下 我们可以看到参数设置 2.订阅下键空间或者事件通知 订阅键空间:subscribe __keyspace@0__: ...

  2. HttpClient的Post请求数据

    最近在项目中需要添加Post请求数据,以前的Get请求是使用JDK自带的URLConnection.在项目组人员的推荐下,开始使用HttpClient. HttpClient简介: HttpClien ...

  3. Android Service实现双向通信(一)

    首先,大概来总结一下与Service的通信方式有很多种: 通过BroadCastReceiver:这种方式是最简单的,只能用来交换简单的数据: 通过Messager:这种方式是通过一个传递一个Mess ...

  4. 【spring boot】在Spring mvc中controller中可以拿到对象信息,但是返回给前台却是什么也没有,解决方案

    如图所示: 最后: 问题解决: 这个原因是因为,User类并未给字段提供get/set方法,所以给前台传递过去的值是空的. 解决方案: 为User类添lombok的注解@Data,为实体类提供get/ ...

  5. 第六讲_图像分割Image Segmentation

    第六讲_图像分割Image Segmentation 语义分割(semantic segmentation) 常用神经网络介绍对比-FCN SegNet U-net DeconvNet 目录 +三大数 ...

  6. Sales Team 仪表盘

                实际设定值         仪表定义     <div class="oe_center" t-if="record.invoiced_ta ...

  7. Git命令学习总结(-)

    入职的第一天,让git命令直接给难住了,汗!使用习惯可视化的工具对于命令行早就忘记的一干二净.还好,回家自己练习一下,总会没有错的.git就不做简介了,版本管理除了svn就是git了,其他的都无所谓了 ...

  8. JrtpLib vs2012环境下编译及使用 GotoFirstSourceWithData 方法 进不去

    项目中有一项功能是接收rtp数据,接收rtp的可以用PJMedia,可以用JrtpLib.PJMedia库无法解决内外网的问题,只有用Jrtp库了. 首先说下Jrtp 的编译问题,我是在windows ...

  9. 代码运行时间 检测锁及死锁详细信息,及sql语句 平台转化

    代码运行时间   System.Diagnostics.Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 开始监视代码运行时间 ...

  10. 每天进步一点点——mysql——Percona XtraBackup(innobackupex)

    一.  简单介绍 Percona XtraBackup是开源免费的MySQL数据库热备份软件,它能对InnoDB和XtraDB存储引擎的数据库非堵塞地备份(对于MyISAM的备份相同须要加表锁).Xt ...