支持与外围BLE设备进行扫描、连接、读、写、通知订阅与取消等基本操作
支持获取信号强度、设置最大传输单元
支持自定义扫描规则
支持多设备连接
支持重连机制
支持配置超时机制
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
...
maven { url 'https://jitpack.io' }
}
}
implementation 'com.github.kanshenmekan:FastBle:latestVersion'
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
BleManager.apply {
enableLog(true)
maxConnectCount = 5
operateTimeout = 2000
splitWriteNum = 20
bleConnectStrategy = BleConnectStrategy.Builder().setConnectOverTime(10000)
.setConnectBackpressureStrategy(BleConnectStrategy.CONNECT_BACKPRESSURE_DROP)
.setReConnectCount(1).setReConnectInterval(2000).build()
}
}.init(this)
BleManager enableLog(boolean enable)
设置连接超时
BleConnectStrategy connectOverTime
设置连接时重连次数和重连间隔(毫秒),默认为0次不重连
BleConnectStrategy setReConnectCount(count: Int) setReConnectInterval(interval: Long)
设置连接背压策略
BleConnectStrategy connectBackpressureStrategy
1.BleConnectStrategy.CONNECT_BACKPRESSURE_DROP
当存在mac相同的设备已经在连接的时候,忽略掉后面发起的连接,直至这次连接失败或者成功,已经存在连接成功,不会发起连接
2.BleConnectStrategy.CONNECT_BACKPRESSURE_LAST
当存在mac相同的设备已经在连接的时候,取消之前的链接,直接用最新发起的,已经存在连接成功,不会发起连接
设置autoConnect
BleConnectStrategy.Builder().setAutoConnect(autoConnect: Boolean)
true 当发起连接的时候,如果无法找到设备,会保持连接状态,不回调结果(如果设置了超时,会一直等待到超时时间回调连接超时),等待设备可以连接之后,再回调结果。
false 直接连接,回调结果,默认为false
设置分包发送的时候,每一包的数据长度,默认20个字节
BleManager.splitWriteNum
设置readRssi、setMtu、write、read、notify、indicate的超时时间(毫秒),默认5秒
BleManager.operateTimeout
BleManager.setBleStateCallback(object : BluetoothChangedObserver.BleStatusCallback {
override fun onStateOn() {
}
override fun onStateTurningOn() {
}
override fun onStateOff() {
}
override fun onStateTurningOff() {
}
})
Tips:
- 不管有没有这个需求,都去设置一个蓝牙状态回调,库里面可以解决,直接关闭蓝牙,系统不走蓝牙断开的回调的问题
val scanRuleConfig = BleScanRuleConfig.Builder()
.setServiceUuids(serviceUUID) // 只扫描指定的服务的设备,可选
.setDeviceName(names, true) // 只扫描指定广播名的设备,可选
.setScanTimeOut(10000) // 扫描超时时间,可选,默认10秒
.setDeviceMac()
// .setScanSettings(scanSettings: ScanSettings)
.build()
BleManager.bleScanRuleConfig = scanRuleConfig
Tips:
可以通过设置ScanSettings,设置搜索模式,或者回调模式,默认是SCAN_MODE_BALANCED搜索模式,回调是CALLBACK_TYPE_ALL_MATCHE,还有匹配模式等等,具体看库代码
默认serviceUuid和macs只要满足list,其中一个就会被认定符合条件(serviceUuid中包含,或者macs包含),当names的模糊模式关闭的时候,和macs效果一样,
当names的模糊关闭的时候,会在所有通过serviceUuid和macs的设备,之后再判断是否包含names中的一个
更多自定义过滤规则在搜索回调中实现
BleManager.scan(object : BleScanCallback {
override fun onScanStarted(success: Boolean) {
//开始扫描 success 表示是否成功开始扫描
}
override fun onLeScan(
oldDevice: BleDevice,
newDevice: BleDevice,
scannedBefore: Boolean) {
// 扫描到一个符合规则的设备
// oldDevice 上一次扫描到的 newDevice新扫描到的
// scannedBefore之前是否扫描到过,当scannedBefore为false的时候 oldDevice和newDevice相同
}
override fun onScanFinished(scanResultList: List<BleDevice>) {
// 扫描结束,列出所有扫描到的符合扫描规则的BLE设备
}
override fun onFilter(bleDevice: BleDevice): Boolean {
// 通过配置扫描规则之后,自定义过滤规则
}
},5000)
第二个参数可选,默认为配置的扫描规则,可以每次配置时间
BleManager.cancelScan()
Tips:
- 调用该方法后,如果当前还处在扫描状态,会立即结束,并回调`onScanFinished`方法。
BleManager.connect(bleDevice,
object : BleGattCallback() {
override fun onStartConnect(bleDevice: BleDevice) {
// 开始连接
}
override fun onConnectFail(bleDevice: BleDevice?, exception: BleException) {
// 连接失败
}
override fun onConnectCancel(bleDevice: BleDevice, skip: Boolean) {
// 连接取消 skip true表示发起了新连接取代这个链接,或者这个设备已经连接成功了 false表示主动取消了这次连接
}
override fun onConnectSuccess(
bleDevice: BleDevice,
gatt: BluetoothGatt?,
status: Int) {
// 连接成功,BleDevice即为所连接的BLE设备
}
override fun onDisConnected(
isActiveDisConnected: Boolean,
device: BleDevice,
gatt: BluetoothGatt?,
status: Int) {
// 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法
}
},strategy: BleConnectStrategy = bleConnectStrategy)
Tips:
- 在某些型号手机上,connectGatt必须在主线程才能有效。非常建议把连接过程放在主线程。
- 连接失败后重连:框架中包含连接失败后的重连机制,可以配置重连次数和时间间隔。当然也可以自行在`onConnectFail`回调方法中延时调用`connect`方法。
- 连接断开后重连:可以在`onDisConnected`回调方法中再次调用`connect`方法。
- 为保证重连成功率,建议断开后间隔一段时间之后进行重连。
- 某些机型上连接失败后会短暂地无法扫描到设备,可以通过设备对象或设备mac直连,而不经过扫描。
- 可以单独配置某次连接的连接策略,不设置默认为全局的策略
通过已知设备Mac直接
fun connect(
mac: String,
bleGattCallback: BleGattCallback?,
strategy: BleConnectStrategy = bleConnectStrategy,
): BluetoothGatt?
val connectStrategy =
BleConnectStrategy.Builder().setAutoConnect(true)
.setConnectOverTime(-1)
.setConnectBackpressureStrategy(BleConnectStrategy.CONNECT_BACKPRESSURE_DROP)
.build()
BleManager.connect(bleDevice, reconnectBleGattCallback, connectStrategy)
- 我们把AutoConnect参数设置为true,等待设备可以连接的时候才会进行回调
- 设置一个最长的超时时间setConnectOverTime,单位为millisecond,如果超时未负数,则会一直处于连接状态,直至连接成功或失败,或者被取消这次连接
- 可以在`onDisConnected`回调方法中再次调用`connect`方法。
fun notify(
bleDevice: BleDevice,
uuid_service: String,
uuid_notify: String,
callback: BleNotifyCallback?,
)
BleNotifyCallback() {
override fun onNotifySuccess(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic) {
// 打开通知操作成功
}
override fun onNotifyFailure(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic?,
exception: BleException) {
// 打开通知操作失败
}
override fun onNotifyCancel(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic) {
// 打开之后,再取消
}
override fun onCharacteristicChanged(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic,
data: ByteArray) {
// 打开通知后,设备发过来的数据将在这里出现
}
}
fun stopNotify(
bleDevice: BleDevice,
uuid_service: String,
uuid_notify: String,
): Boolean
fun indicate(
bleDevice: BleDevice,
uuid_service: String,
uuid_indicate: String,
callback: BleIndicateCallback?)
BleIndicateCallback() {
override fun onIndicateSuccess(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic) {
// 打开通知操作成功
}
override fun onIndicateFailure(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic?,
exception: BleException) {
// 打开通知操作失败
}
override fun onIndicateCancel(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic) {
// 打开通知后,取消的时候
}
override fun onCharacteristicChanged(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic,
data: ByteArray?) {
// 打开通知后,设备发过来的数据将在这里出现
}
}
fun stopNotify(
bleDevice: BleDevice,
uuid_service: String,
uuid_notify: String,
): Boolean
fun read(
bleDevice: BleDevice,
uuid_service: String,
uuid_read: String,
callback: BleReadCallback?)
BleReadCallback() {
override fun onReadSuccess(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic,
data: ByteArray) {
// 读特征值数据成功
}
override fun onReadFailure(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic?,
exception: BleException) {
// 读特征值数据失败
}
}
fun write(
bleDevice: BleDevice,
uuid_service: String,
uuid_write: String,
data: ByteArray?,
split: Boolean = true,
splitNum: Int = splitWriteNum,
continueWhenLastFail: Boolean = false,
intervalBetweenTwoPackage: Long = 0,
callback: BleWriteCallback?,
writeType: Int = BleOperator.WRITE_TYPE_DEFAULT)
BleWriteCallback() {
override fun onWriteSuccess(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic,
current: Int,
total: Int,
justWrite: ByteArray,
data: ByteArray
) {
// 发送数据到设备成功
// `current`表示当前发送第几包数据,`total`表示本次总共多少包数据,`justWrite`表示刚刚发送成功的数据包。
//data 表示整个数据
}
override fun onWriteFailure(
bleDevice: BleDevice,
characteristic: BluetoothGattCharacteristic?,
exception: BleException,
current: Int,
total: Int,
justWrite: ByteArray?,
data: ByteArray?,
isTotalFail: Boolean
) {
// 发送数据到设备失败 exception错误信息
// `current`表示当前发送第几包数据,`total`表示本次总共多少包数据,`justWrite`表示刚刚发送失败的数据包
//data 表示整个数据
// isTotalFail 是否整个过程都失败了
}
}
Tips:
- 在没有扩大MTU及扩大MTU无效的情况下,当遇到超过20字节的长数据需要发送的时候,需要进行分包。splitNum表示分包的字节数,默认20,参数`boolean split`表示是否使用分包发送,默认为true,默认对超过splitNum字节的数据进行分包发送。
- 对于分包发送的策略,可以选择发送上一包数据发送失败之后,后面的数据还需不需要发送,continueWhenLastFail,默认为false。
- 参数`intervalBetweenTwoPackage`表示延时多长时间发送下一包,单位ms,默认0。
- 参数writeType,表示使用哪种发送模式BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE,WRITE_TYPE_DEFAULT,WRITE_TYPE_SIGNED,默认是判断characteristic具备那种发送模式
优先WRITE_TYPE_NO_RESPONSE,WRITE_TYPE_DEFAULT,最后是WRITE_TYPE_SIGNED
fun addOperatorToQueue(
bleDevice: BleDevice?,
identifier: String = BleBluetooth.DEFAULT_QUEUE_IDENTIFIER,
sequenceBleOperator: SequenceBleOperator,
): Boolean
val sequenceWriteOperator =
SequenceWriteOperator.Builder().serviceUUID(service_uuid)
.priority(PRIORITY_WRITE_DEFAULT)
.characteristicUUID(characteristic_uuid).data(data).writeType(writeType)
.bleWriteCallback(bleWriteCallback)
.continuous(continuous)
.delay(if (continuous) 10 else 100)
.timeout(1000)
.split(true)
.splitNum(20)
.build()
BleManager.addOperatorToQueue(bleDevice, sequenceBleOperator = sequenceWriteOperator)
Tips:
- 当一个characteristic连续发送数据,两次间隔太短的话,容易造成失败,这个时候可以使用队列发送
- 可以为每个可写的characteristic创造一个队列,传入不同的identifier,也可以共用一个队列,每个设备有个默认队列
- priority 优先级越高,在队列的越前面
- writeType 和正常写入相同
- delay 任务之后等待多久
- 当continuous 为true的时候,等待任务完成之后(触发回调或者超时),才会进行delay任务,之后获取下一个任务
当continuous 为false的时候,会直接进行delay任务,之后获取下一个任务
- timeout 当continuous为true之后,这个设置才有效果,如果任务在时间内没有回调,直接忽略掉,进行delay任务,之后获取下一个任务
建议给一个适当的时长,以便任务有足够时间触发回调
如果timeout为0,则会一直等待,直到任务回调触发
//移除队列中某个任务
fun removeOperatorFromQueue(
bleDevice: BleDevice?,
identifier: String = BleBluetooth.DEFAULT_QUEUE_IDENTIFIER,
sequenceBleOperator: SequenceBleOperator,
): Boolean
//清空某个队列全部任务
fun clearQueue(
bleDevice: BleDevice?,
identifier: String = BleBluetooth.DEFAULT_QUEUE_IDENTIFIER)
//清除所有队列任务
fun clearAllQueue(bleDevice: BleDevice?)
//暂停某个队列
fun pauseQueue(
bleDevice: BleDevice?,
identifier: String = BleBluetooth.DEFAULT_QUEUE_IDENTIFIER,
)
//恢复某个队列
fun resume(bleDevice: BleDevice?, identifier: String = BleBluetooth.DEFAULT_QUEUE_IDENTIFIER)
BleManager.readRssi(bleDevice,
object : BleRssiCallback() {
override fun onRssiFailure(bleDevice: BleDevice, exception: BleException) {
// 读取设备的信号强度失败
}
override fun onRssiSuccess(bleDevice: BleDevice, rssi: Int) {
// 读取设备的信号强度成功
}
})
Tips:
获取设备的信号强度,需要在设备连接之后进行。
某些设备可能无法读取Rssi,不会回调onRssiSuccess(),而会因为超时而回调onRssiFailure()。
BleManager.setMtu(bleDevice,mtu,object : BleMtuChangedCallback() {
override fun onSetMTUFailure(bleDevice: BleDevice, exception: BleException) {
// 设置MTU失败
}
override fun onMtuChanged(bleDevice: BleDevice, mtu: Int) {
// 设置MTU成功,并获得当前设备传输支持的MTU值
}
})
Tips:
设置MTU,需要在设备连接之后进行操作。
默认每一个BLE设备都必须支持的MTU为23。
MTU为23,表示最多可以发送20个字节的数据。
在Android 低版本(API-17 到 API-20)上,没有这个限制。所以只有在API21以上的设备,才会有拓展MTU这个需求。
该方法的参数mtu,最小设置为23,最大设置为512。
并不是每台设备都支持拓展MTU,需要通讯双方都支持才行,也就是说,需要设备硬件也支持拓展MTU该方法才会起效果。调用该方法后,可以通过onMtuChanged(int mtu)查看最终设置完后,设备的最大传输单元被拓展到多少。如果设备不支持,可能无论设置多少,最终的mtu还是23。
fun requestConnectionPriority(bleDevice: BleDevice, connectionPriority: Int): Boolean
Tips:
设置连接的优先级,一般用于高速传输大量数据的时候可以进行设置。 Must be one of{@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED}, {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH} or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}.
fun disconnect(bleDevice: BleDevice?)
fun disconnectAllDevice()
//退出,无回调
fun destroy()
//退出,有scan和connect的回调
fun release()