这里声明一下,这篇文章仅仅针对有一定蓝牙开发基础的同学。
Android BLE开发是个大坑, 连接很不稳定。 多次连接外围设备时, 就会出现连接失败的情况。 观察日志发现 onClientConnectionState() 方法经常出现133 的错误码。
1、 为什么会出现 133的错误码
如何解决?
2、 GATT每次连接前, close之前的资源
// 全局gatt
private BluetoothGatt mGatt;
private void connect(BluetoothDevice device, BluetoothGattCallback callback) {
// 释放上次gatt连接资源
close();
if (SdkUtil.isAtLeastM_23()) {
mGatt = device.connectGatt(ViotSDK.getInstance().getBaseContext(), false, callback, BluetoothDevice.TRANSPORT_LE);
} else {
mGatt = device.connectGatt(ViotSDK.getInstance().getBaseContext(), false, callback);
// 释放上次gatt连接资源
public void close() {
if (mGatt != null) {
mGatt.disconnect();
mGatt.close();
mGatt = null;
3、清理Gatt缓存
在重连的时候先将Gatt缓存进行清理:
public boolean refreshDeviceCache() {
try {
VLog.d(TAG, "clear gatt cache");
BluetoothGatt localBlueToothGatt = mBluetoothGatt;
Method localMethod = localBlueToothGatt.getClass().getMethod("refresh", new Class[0]);
if (localMethod != null) {
localMethod.setAccessible(true);
Boolean bool = ((Boolean) localMethod.invoke(localBlueToothGatt, new Object[0])).booleanValue();
localMethod.setAccessible(false);
return bool;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
return false;
然后进行close操作:
mBluetoothGatt.close();
mBluetoothGatt = null;
4、 出现133错误码时, 进行重试策略
在Gatt连接的回调中,如果连接失败,并且错误码是133时,进行重试连接
// 重试连接三次
private static int GATT_CONNECT_RETRY_MAX_COUNT = 3;
private int retryCount = 0;
private class BleCallback extends BluetoothGattCallback {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (BluetoothGatt.GATT_SUCCESS == status) { // gatt连接成功
} else { // gatt连接失败
// 连接失败需要释放资源
close();
if (status == 133 && retryCount < GATT_CONNECT_RETRY_MAX_COUNT) { // 133错误码重试
connect(deviice, callback);
由于设备 Rom是公司系统组自己定制的, 所以开关蓝牙的操作是有权限的。 我们可以在重试的过程中, 对设备蓝牙进行重启,更彻底的释放蓝牙连接。
// 重试连接三次
private static int GATT_CONNECT_RETRY_MAX_COUNT = 3;
prvate int retryCount = 0;
private Handler handler = new Handler(Looper.myLooper());
private class BleCallback extends BluetoothGattCallback {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (BluetoothGatt.GATT_SUCCESS == status) { // gatt连接成功
} else { // gatt连接失败
// 释放资源
close();
if (status == 133 && retryCount < GATT_CONNECT_RETRY_MAX_COUNT) {
if (BluetoothUtil.switchBlueState(false)) { // 关闭蓝牙
handler.postDelayed(() -> {
if (BluetoothUtil.switchBlueState(true)) { // 5s后,开启蓝牙
handler.postDelayed(new Runnable() { // 5s后重试连接设备
@Override
public void run() {
connect(deviice, callback);
}, 5000);
} else {
// 重新打开蓝牙失败
connectDeviceError();
}, 5000);
} else {
// 关闭蓝牙失败
connectDeviceError();
private void connectDeviceError() {
蓝牙操作类BluetoothUtil
public class BluetoothUtil {
private static final String TAG = BluetoothUtil.class.getSimpleName();
* 切换蓝牙开关状态
public static boolean switchBlueState(boolean isOpen) {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
boolean suc;
if (isOpen) {
suc = adapter.enable();
Log.d(TAG, "open blue suc :" + suc);
} else {
suc = adapter.disable();
Log.d(TAG, "close blue suc :" + suc);
return suc;
5、 FastBLe
FastBLe 是一个优秀的BLE开源库,在GitHub有4.4K Star, 支持重连机制,连接设备较稳定。
6、 总结
经过多次优化, 发现并不能完全杜绝133的错误码的出现,只能减少133的出现。
这个问题也和机型有关, 我尝试的小米连接较稳定, oppo经常出现。在Ble开发中,容易遇到。还是需要谷歌在协议层, 设备厂商在硬件层进行优化。 开发能做的是尽可能的提高Ble连接的稳定性。
大家如果有更好的办法, 欢迎在评论区讨论