低功耗蓝牙框架。优势:
- 适配到 Android5.0 和 Android6.0 的扫描方式(速度极快)。
- 适配小米手机连接蓝牙操作。
- 适配三星手机发现服务、开启通知等。
- 支持直接连发数百条数据,而不用担心消息发不出。自带消息队列(终于可以像 iOS 一样啦,不用去写延时啦)。
- 支持同时开启多个通知。
- 可以连续操作发送数据、读取特征、开启通知,即使你在 for 循环中写也没问题,自带队列。
- 扫描操作支持-> 设置扫描时长、根据设备名称扫描、根据硬件地址扫描、根据服务 UUID 扫描、连接成功后自动关闭扫描。
注意点:
- Android 6.0 扫描蓝牙需要地理位置权限。
- 发送数据、开启通知、读取特征等操作,需要在 onServicesDiscovered()发现服务之后才能进行。
- 连接设备之前最好先停止扫描(小米手机可能会出现不能发现服务的情况)。
入门指南
权限:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED"/>
6.0 以上设备需要
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
引入方式
compile 'com.qindachang:BluetoothLELibrary:0.2.0'
前戏
判断蓝牙是否打开
mBluetoothLe.isBluetoothOpen();
请求打开蓝牙
mBluetoothLe.enableBluetooth(activity.this, true);
关闭蓝牙
mBluetoothLe.enableBluetooth(activity.this, false);
一、获取单例实例
BluetoothLe mBluetoothLe = BluetoothLe.getDefault();
二、初始化
mBluetoothLe.init(this);//必须调用 init()初始化
三、扫描
扫描过程已携带 6.0 动态权限申请:地理位置权限
private BluetoothDevice mBluetoothDevice;
mBluetoothLe.setScanPeriod(15000)//设置扫描时长,单位毫秒,默认 10 秒
.setScanWithServiceUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")//设置根据服务 uuid 过滤扫描
.setScanWithDeviceName("ZG1616")//设置根据设备名称过滤扫描
.setReportDelay(0)//如果为 0,则回调 onScanResult()方法,如果大于 0, 则每隔你设置的时长回调 onBatchScanResults()方法,不能小于 0
.startBleScan(this, new OnLeScanListener() {
@Override
public void onScanResult(BluetoothDevice bluetoothDevice, int rssi, ScanRecord scanRecord) {
mStringBuilder.append("扫描到设备:" + bluetoothDevice.getName() + "-信号强度:" + rssi + "\n");
tv_text.setText(mStringBuilder.toString());
mBluetoothDevice = bluetoothDevice;
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
mStringBuilder.append("批处理信息:" + results.toString() + "\n");
tv_text.setText(mStringBuilder.toString());
}
@Override
public void onScanCompleted() {
mStringBuilder.append("扫描结束\n");
tv_text.setText(mStringBuilder.toString());
}
@Override
public void onScanFailed(int code) {
mStringBuilder.append("扫描错误\n");
tv_text.setText(mStringBuilder.toString());
}
});
四、停止扫描
mBluetoothLe.stopBleScan();
五、连接蓝牙
//发送数据、开启通知等操作,必须等待 onServicesDiscovered()发现服务回调后,才能去操作
//参数:false 为关闭蓝牙断开自动重连,如果为 true 则自动断开重连
mBluetoothLe.startBleConnect(false, mBluetoothDevice, new OnLeConnectListener() {
@Override
public void onDeviceConnecting() {
mStringBuilder.append("连接中...\n");
tv_text.setText(mStringBuilder.toString());
}
@Override
public void onDeviceConnected() {
mStringBuilder.append("成功连接!\n");
tv_text.setText(mStringBuilder.toString());
}
@Override
public void onDeviceDisconnected() {
mStringBuilder.append("断开连接!\n");
tv_text.setText(mStringBuilder.toString());
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt) {
mStringBuilder.append("发现服务啦\n");
tv_text.setText(mStringBuilder.toString());
}
@Override
public void onDeviceConnectFail() {
mStringBuilder.append("连接失败~~\n");
tv_text.setText(mStringBuilder.toString());
}
});
断开连接
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);
六、监听发送数据
mBluetoothLe.setOnWriteCharacteristicListener(new OnLeWriteCharacteristicListener() {
@Override
public void onSuccess(BluetoothGattCharacteristic characteristic) {
Log.d("debug", "发送了数据:" + Arrays.toString(characteristic.getValue()));
mStringBuilder.append("发送了:").append(Arrays.toString(characteristic.getValue()));
mStringBuilder.append("\n");
tv_text.setText(mStringBuilder.toString());
}
@Override
public void onFailed(String msg, int status) {
}
});
七、开启通知
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.enableBleNotification(true, SERVICE_UUID, STEP_NOTIFICATION_UUID);
八、开启多个通知
mBluetoothLe.enableBleNotification(true, SERVICE_UUID, new String[]{HEART_NOTIFICATION_UUID, STEP_NOTIFICATION_UUID});
九、监听通知
mBluetoothLe.setBleNotificationListener(new OnLeNotificationListener() {
@Override
public void onSuccess(BluetoothGattCharacteristic characteristic) {
Log.d("debug", "收到通知:" + Arrays.toString(characteristic.getValue()));
}
@Override
public void onFailure() {
}
});
十、读取数据
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.setOnReadCharacteristicListener(new OnLeReadCharacteristicListener() {
@Override
public void onSuccess(BluetoothGattCharacteristic characteristic) {
}
@Override
public void onFailure(String info, int status) {
}
});
十一、取消队列
假设当你在 for 循环中发送 100 条数据,想要在中途取消余下的发送
mBluetoothLe.clearQueue();
十二、关闭 GATT
在你退出应用的时候使用
mBluetoothLe.close();
十三、清理蓝牙缓存
请你在连接上蓝牙后,再执行这步操作
mBluetoothLe.clearDeviceCache()
避免内存泄露
在 Activity 生命周期 onDestroy() 中使用:
mBluetoothLe.destroy();
仍在补充
- 连续操作发送数据、读取特征、开启通知操作设置优先级,像网络请求一样设置优先级
- 蓝牙设备信号强度监听
- 连接超时设置,连接不上的情况下自动重连的次数设置