对蓝牙感兴趣可以加群讨论学习(QQ:494309361)
有个人项目或者定制化需求的可加QQ:823581722 进行联系
![二维码.png](https://camo.githubusercontent.com/677c5d25f4d05d7ff325e3e56deb7e2e086fdb69482e78b097dbd08a6c70c46b/68747470733a2f2f7777772e70677965722e636f6d2f6170702f7172636f64652f44723864)
![BleLib库结构图.png](https://camo.githubusercontent.com/68ecf8e53f5dfda9e085530e29451e8d6c5d4dfc27160cd4071f29165992e0e3/687474703a2f2f75706c6f61642d696d616765732e6a69616e7368752e696f2f75706c6f61645f696d616765732f333838343131372d326335613062393563646137353135382e706e673f696d6167654d6f6772322f6175746f2d6f7269656e742f7374726970253743696d61676556696577322f322f772f383430)
该类的主要是来描述并记录蓝牙的属性和状态,如记录蓝牙名称、蓝牙MAC地址、蓝牙别名(即修改之后的名称)、蓝牙连接状态等,该类处在被保护状态,禁止外部随意生成该对象,
如果有特别需求可以通过BleFactory.create(...)进行创建该对象(并不建议)
该类是蓝牙状态类,定义了蓝牙扫描、连接、通知使能、发送、接收等状态的常量值(连接异常等状态码可参考该类)
该类是最重要的一个类,主要是蓝牙操作中用到的各个方法的实现类,是整个蓝牙的核心功能实现,BleManager是对外提供所有蓝牙操作接口的
管理类,当BluetoothLeService处理之后要把结果返回到BleManager中,然后再由BleManager对外提供接口。
该类提供了几乎所有你需要用到的方法,包括蓝牙扫描、连接、断开、蓝牙当前连接状态等等,管理了蓝牙操作的所有接口和方法。
![Version](https://camo.githubusercontent.com/b05202ed084ba870b2c4238c7001d8836ef0718119c9ff8155a76caf67ee16e3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e362e312d626c75652e737667)
添加自动分包发送接口(无需添加延迟,自动根据系统底层返回结果处理)
EntityData entityData = new EntityData.Builder()
.setLastPackComplete(true)//最后一包是否自动补零,默认false
.setAutoWriteMode(autoWriteMode)//是否设置自动模式发送,默认false
.setAddress(device.getBleAddress())
.setData(data)//大数据文件的字节数组
.setPackLength(20)//每包发送字节数
.setDelay(50L)//自动模式下无需设置delay
.build();
mBle.writeEntity(entityData, new BleWriteEntityCallback<BleDevice>() {
@Override
public void onWriteSuccess() {
...
}
@Override
public void onWriteFailed() {
...
}
});
![Version](https://camo.githubusercontent.com/4c0e5642c7c450e88f323881fcb4039b5dd545431cc5a5c777ca1ef1ce6af242/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e362e302d626c75652e737667)
![Version](https://camo.githubusercontent.com/2f2e6d1010384567bce59d1bf79d45bde452fc38a03aebb8ffbf4e2b091f306d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e352e342d626c75652e737667)
1、添加过滤扫描设备接口
mBle = Ble.options()
.setLogBleExceptions(true)
.setThrowBleException(true)
.setAutoConnect(true)
.setFilterScan(true)//设置是否过滤扫描到的设备
.setConnectFailedRetryCount(3)
.setConnectTimeout(10 * 1000)
.setScanPeriod(12 * 1000)
.setUuidService(UUID.fromString("0000fee9-0000-1000-8000-00805f9b34fb"))
.setUuidWriteCha(UUID.fromString("d44bc439-abfd-45a2-b575-925416129600"))
.create(getApplicationContext());
2、优化自动重连接口
3、添加Android5.0发送广播的接口
byte[] payload = new byte[16];
payload[0] = 0x01;
mBle.startAdvertising(payload);
4、收到广播包并解析后的数据
BleScanCallback<BleDevice> scanCallback = new BleScanCallback<BleDevice>() {
@Override
public void onLeScan(final BleDevice device, int rssi, byte[] scanRecord) {
Log.e(TAG, "onLeScan: "+device.getBleAddress());
synchronized (mBle.getLocker()) {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
}
//收到广播包并解析后的数据
@Override
public void onParsedData(BleDevice device, ScanRecord scanRecord) {
super.onParsedData(device, scanRecord);
byte[] data = scanRecord.getManufacturerSpecificData(65535);//参数为厂商id
if (data != null){
Log.e(TAG, "onParsedData: "+ ByteUtils.BinaryToHexString(data));
}
}
};
![Version](https://camo.githubusercontent.com/0ef7d0d11e7759219d37bcf7af3ff20dcf5d2895649b13be0d59462fe80df639/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e352e332d626c75652e737667)
1、添加发送大数据量的进度回调
private void sendEntityData() throws IOException {
byte[] data = ByteUtils.toByteArray(getAssets().open("WhiteChristmas.bin"));
Log.e(TAG, "sendEntityData: "+data.length);
mBle.writeEntity(mBle.getConnetedDevices().get(0), data, 20, 50, new BleWriteEntityCallback<BleDevice>() {
@Override
public void onWriteSuccess() {
L.e("writeEntity", "onWriteSuccess");
}
@Override
public void onWriteFailed() {
L.e("writeEntity", "onWriteFailed");
}
@Override
public void onWriteProgress(double progress) {
Log.e("writeEntity", "当前发送进度: "+progress);
}
@Override
public void onWriteCancel() {
Log.e(TAG, "onWriteCancel: ");
}
});
}
2、修复持续接收通知回调过快导致数据重复的问题
3、修复多设备连接,同时断开所有设备,回调次数不完整的问题
![Version](https://camo.githubusercontent.com/409fddb908c9abfd66646bbd92549035a8aec4ed81a3cc02aa96cc52ad6ceb17/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e352e32253230626574612d626c75652e737667)
1、添加自动连接的接口(使用新的初始化写法)
mBle = Ble.options()
.setLogBleExceptions(true)
.setThrowBleException(true)
.setAutoConnect(true)//自动重连
.setConnectFailedRetryCount(3)
.setConnectTimeout(10 * 1000)
.setScanPeriod(12 * 1000)
.setUuidService(UUID.fromString("0000fee9-0000-1000-8000-00805f9b34fb"))
.setUuidWriteCha(UUID.fromString("d44bc439-abfd-45a2-b575-925416129600"))
.create(getApplicationContext());
2、优化断开连接后,自动移除通知监听的问题
![Version](https://camo.githubusercontent.com/0c5a8c547e6c86a02c4b98cd66d915b64fc7d4bd2b89e0c96621fc271171c14b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e352e302d626c75652e737667)
1、添加了发送大数据包(如:文件等)的接口
try {
//获取整个文件的总字节
byte[]data = toByteArray(getAssets().open("WhiteChristmas.bin"));
//发送大数据量的包
mBle.writeEntity(mBle.getConnetedDevices().get(0), data, 20, 50, new BleWriteEntityCallback<BleDevice>() {
@Override
public void onWriteSuccess() {
L.e("writeEntity", "onWriteSuccess");
}
@Override
public void onWriteFailed() {
L.e("writeEntity", "onWriteFailed");
}
});
} catch (IOException e) {
e.printStackTrace();
}
2、修复了正在扫描时,关闭蓝牙导致停止扫描onStop()不回调的问题
![Version](https://camo.githubusercontent.com/103ae94e713ed65d967ee8c548d3f0b21d5c623c99ffdc0afda975f333d93a61/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e332e302d626c75652e737667)
1、添加通过mac地址连接的接口:
String address = device.getBleAddress();//或者 String address = "3E:9A:4A:71:F6:4D";
mBle.connect(address, new BleConnCallback<BleDevice>() {
@Override
public void onConnectionChanged(BleDevice device) {
}
});
2、添加BLE4.2的设置MTU的接口:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
//此处第二个参数 不是特定的 比如你也可以设置500 但是如果设备不支持500个字节则会返回最大支持数
mBle.setMTU(mBle.getConnetedDevices().get(0).getBleAddress(), 250, new BleMtuCallback<BleDevice>() {
@Override
public void onMtuChanged(BleDevice device, int mtu, int status) {
super.onMtuChanged(device, mtu, status);
ToastUtil.showToast("最大支持MTU:"+mtu);
}
});
}else {
ToastUtil.showToast("设备不支持MTU");
}
![Version](https://camo.githubusercontent.com/a125b0aa31691ce60483ecd6944b1cbfa7403f08dedaf1f8f4c13ed757e4db77/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e322e302d626c75652e737667)
修复连接多个设备在onChanged()回调中判断设备对象
/*设置通知的回调*/
private BleNotiftCallback<BleDevice> bleNotiftCallback = new BleNotiftCallback<BleDevice>() {
@Override
public void onChanged(BleDevice device, BluetoothGattCharacteristic characteristic) {
UUID uuid = characteristic.getUuid();
Log.e(TAG, "onChanged==uuid:" + uuid.toString());
Log.e(TAG, "onChanged==address:"+ device.getBleAddress());
Log.e(TAG, "onChanged==data:" + Arrays.toString(characteristic.getValue()));
}
};
![Version](https://camo.githubusercontent.com/c5e4738b7baf0989cedcef3650a4a91ee721438430ad780055a3475e5768df45/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e312e352d626c75652e737667)
![Version](https://camo.githubusercontent.com/b9459a7a6e7394f06d0101d30e3f1bd50d0f689c21f6deb9aeddb5d0a533870c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e312e322d626c75652e737667)
1、修复上个版本依赖地址变化,导致依赖时出现问题。
2、添加清理蓝牙缓存接口
![Version](https://camo.githubusercontent.com/3dbff44630d2ee5d63916f0c74931e3e21ba31f1d0f2763554eb947881ace6fb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e312e312d626c75652e737667)
![Version](https://camo.githubusercontent.com/98c11fa4ac06510c7f0597a716697449e46b7511989daf95f2b3e571511b8792/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e312e302d626c75652e737667)
该版本添加跳转到测试界面(先连接设备),在测试界面操作该蓝牙对象的扫描、连接、断开、通知等回调的接口(任意界面都可以随心所欲的操作或者拿到mcu返回的数据)
1、在其他界面你也想拿到蓝牙设备传过来的数据,你可以这样做:(重要)
//测试通知
public void testNotify(BleDevice device) {
if(device != null){
mNotifyStatus.setText("设置通知监听成功!!!");
mBle.startNotify(device, new BleNotiftCallback<BleDevice>() {
@Override
public void onChanged(BluetoothGattCharacteristic characteristic) {
Log.e(TAG, "onChanged: " + Arrays.toString(characteristic.getValue()));
mNotifyValue.setText("收到MCU通知值:\n"+Arrays.toString(characteristic.getValue()));
}
});
}
}
2、在其他界面也想连接或者断开上个界面的设备对象,你可以这么做:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//测试连接或断开
final BleDevice device = mLeDeviceListAdapter.getDevice(position);
if (device == null) return;
if (mBle.isScanning()) {
mBle.stopScan();
}
if (device.isConnected()) {
//2.1.0版本新增接口(mBle.disconnect(device)接口仍可正常使用)
mBle.disconnect(device, connectCallback);
} else if (!device.isConnectting()) {
mBle.connect(device, connectCallback);
}
}
});
3、扫描、发送数据、读取数据等接口都可如上正常使用(与之前版本一样)
![Version](https://camo.githubusercontent.com/a957343f8e88db47466293c8d58eed9682734855a2cb0b2777e027d6f5d79d3f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e302e352d626c75652e737667)
![Version](https://camo.githubusercontent.com/20397a9cb942f848cfbefa7d14f6cf419be771d4810d8ebd0f7b0e7582c2d72a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e302e342d626c75652e737667)
该版本修复读、写、通知特征uuid相同的情况下,出现无法设置通知的BUG
![Version](https://camo.githubusercontent.com/6bf79f15e063d9b7285fa386b15cc482670e858de2f8da3dd8cb039ec7420e56/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e302e332d626c75652e737667)
![Version](https://camo.githubusercontent.com/b5e0eb6cf55b02a20da076ab05aef34162f5b243a548685b4eabeb3443f735cf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e302e322d626c75652e737667)
该版本增加主动读取数据以及读取远程RSSI值的接口
![Version](https://camo.githubusercontent.com/38567af460871731ea07a45c153774e0dcce48d579229e836be4605db4d9d1ac/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76322e302e302d626c75652e737667)
该版本重构V 1.x版本,作为全新升级版本,重大类、接口进行重命名,使各个接口完成单一功能,并使之得到单一功能的回调。
注:至此V 2.0.0版本以后不再维护1.x版本
![Version](https://camo.githubusercontent.com/19b31ff627e2f94607fa597734b57c4134e96dc535ed0f0ccc4f3a4972786c15/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76312e302e342d626c75652e737667)
![Version](https://camo.githubusercontent.com/03be099fc3fede9264488d6bbc48c1ca8e64bc81f27421b2661d6335d92f233a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f426c654c69622d76312e302e302d626c75652e737667)
初始版本,可完成基本的BLE蓝牙一系列操作(扫描、连接、断开、设置通知、发送数据等等)
![Download](https://camo.githubusercontent.com/69f59c32df3db332c6d01b1ac2ef9da3db95b92fb94c8187ee8de63928d5ef56/68747470733a2f2f6170692e62696e747261792e636f6d2f7061636b616765732f73757065726c69752f6d6176656e2f426c654c69622f696d616765732f646f776e6c6f61642e737667)
compile 'cn.com.superLei:blelibrary:2.6.1'
1.初始化蓝牙(判断设备是否支持BLE,蓝牙是否打开以及6.0动态授权蓝牙权限等)
private void initBle() {
//方式1
mBle = Ble.options()//开启配置
.setLogBleExceptions(true)//设置是否输出打印蓝牙日志(非正式打包请设置为true,以便于调试)
.setThrowBleException(true)//设置是否抛出蓝牙异常
.setAutoConnect(true)//设置是否自动连接
.setFilterScan(true)//设置是否过滤扫描到的设备
.setConnectFailedRetryCount(3)
.setConnectTimeout(10 * 1000)//设置连接超时时长(默认10*1000 ms)
.setScanPeriod(12 * 1000)//设置扫描时长(默认10*1000 ms)
.setUuidService(UUID.fromString("0000fee9-0000-1000-8000-00805f9b34fb"))//主服务的uuid
.setUuidWriteCha(UUID.fromString("d44bc439-abfd-45a2-b575-925416129600"))//可写特征的uuid
.create(getApplicationContext());
或者
//方式2 使用默认配置
mBle = Ble.create(getApplicationContext());
//方式3(同方式1)
Ble.Options options = Ble.options()
.setLogBleExceptions(true)
.setAutoConnect(true)...;
mBle = Ble.create(getApplicationContext(), options);
注意:若进行数据交互,必须进行配置uuid的各个值
}
mBle.startScan(scanCallback);
BleScanCallback<BleDevice> scanCallback = new BleScanCallback<BleDevice>() {
@Override
public void onLeScan(final BleDevice device, int rssi, byte[] scanRecord) {
Toast.makeText(BleActivity.this, "ssss", Toast.LENGTH_SHORT).show();
synchronized (mBle.getLocker()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
}
};
mBle.connect(device, connectCallback);
private BleConnCallback<BleDevice> connectCallback = new BleConnCallback<BleDevice>() {
@Override
public void onConnectionChanged(BleDevice device) {
if (device.isConnected()) {
setNotify(device);
}
Log.e(TAG, "onConnectionChanged: " + device.isConnected());
mLeDeviceListAdapter.notifyDataSetChanged();
setConnectedNum();
}
@Override
public void onConnectException(BleDevice device, int errorCode) {
super.onConnectException(device, errorCode);
Toast.makeText(BleActivity.this, "连接异常,异常状态码:" + errorCode, Toast.LENGTH_SHORT).show();
}
};
private void setNotify(BleDevice device) {
/*连接成功后,设置通知*/
mBle.startNotify(device, new BleNotiftCallback<BleDevice>() {
@Override
public void onChanged(BleDevice device, BluetoothGattCharacteristic characteristic) {
Log.e(TAG, "onChanged: " + Arrays.toString(characteristic.getValue()));
}
@Override
public void onReady(BleDevice device) {
Log.e(TAG, "onReady: ");
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt) {
Log.e(TAG, "onServicesDiscovered is success ");
}
@Override
public void onNotifySuccess(BluetoothGatt gatt) {
Log.e(TAG, "onNotifySuccess is success ");
}
});
}
5.读取远程Rssi
mBle.readRssi(mBle.getConnetedDevices().get(0), new BleReadRssiCallback<BleDevice>() {
@Override
public void onReadRssiSuccess(int rssi) {
super.onReadRssiSuccess(rssi);
Log.e(TAG, "onReadRssiSuccess: " + rssi);
Toast.makeText(BleActivity.this, "onReadRssiSuccess:"+ rssi, Toast.LENGTH_SHORT).show();
}
});
boolean result = mBle.write(device, changeLevelInner(), new BleWriteCallback<BleDevice>() {
@Override
public void onWriteSuccess(BluetoothGattCharacteristic characteristic) {
Toast.makeText(BleActivity.this, "发送数据成功", Toast.LENGTH_SHORT).show();
}
});
if (!result) {
Log.e(TAG, "changeLevelInner: " + "发送数据失败!");
}
//找到你需要升级文件的路径(一般情况都是保存再服务器上,一旦有更新会自动提示,然后APP下载并保存到本地,生成对应的file对象)
File file = new File(...);
//读写SD卡权限,此处略(6.0及以上需添加)
OtaManager mOtaManager = new OtaManager(BleActivity.this);
boolean result = mOtaManager.startOtaUpdate(file, (BleDevice) mBle.getConnetedDevices().get(0), mBle);
Log.e("OTA升级结果:", result + "");
![Demo预览图.gif](https://camo.githubusercontent.com/1033c4ef8fa6d6baa98ed07354c557fc597d492277bedc952a393f423f8fcaa8/68747470733a2f2f75706c6f61642d696d616765732e6a69616e7368752e696f2f75706c6f61645f696d616765732f333838343131372d623336376332383566633734333065332e6769663f696d6167654d6f6772322f6175746f2d6f7269656e742f7374726970)
五、如果你觉得不错,对你有过帮助,请给我一点打赏鼓励,支持我维护的动力:
![](https://camo.githubusercontent.com/6eb11b823efcc9f65b35cd43eb7150778c4c9c879d2a63e133afdbe04867b47a/68747470733a2f2f75706c6f61642d696d616765732e6a69616e7368752e696f2f75706c6f61645f696d616765732f333838343131372d316636633163306662353838353235322e6a70673f696d6167654d6f6772322f6175746f2d6f7269656e742f7374726970253743696d61676556696577322f322f772f333230)
注:打赏后可留言/联系本人,提供您的需求以及建议,本人会进行定期的更新优化库的体验,多谢支持!