一、断开连接的调用方法
- android.bluetooth.BluetoothGatt.disconnect() 断开连接
- android.bluetooth.BluetoothGatt.close() 释放连接资源
二、源码分析
- android.bluetooth.BluetoothGatt.disconnect()的源码分析
private IBluetoothGatt mService;//对象中的属性
BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device,
int transport) {
mContext = context;
mService = iGatt; //创建对象的时候,将gatt对象赋值给mService
mDevice = device;
mTransport = transport;
mServices = new ArrayList<BluetoothGattService>();
mConnState = CONN_STATE_IDLE;
}
public void disconnect() {
if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return;
try {
mService.clientDisconnect(mClientIf, mDevice.getAddress());
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
- android.bluetooth.BluetoothGatt.close()的源码分析
public void close() {
if (DBG) Log.d(TAG, "close()");
unregisterApp();
mConnState = CONN_STATE_CLOSED;
}
private void unregisterApp() {
if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
if (mService == null || mClientIf == 0) return;
try {
mCallback = null;
mService.unregisterClient(mClientIf);
mClientIf = 0;
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
}
三、断开连接小计
- 网上看到的大部分处理方式
监听页面的生命周期,再页面需要执行销毁处理,判断gatt连接对象是否存在,如果存在,则同时调用上述的两种方式进行关闭连接操作处理。
但这样处理有个问题:
看上述的两段源码,close其实算得上是将callback置空处理,有点类似GC机制,如果同时使用,则在disconnect操作后,会触发android.bluetooth.BluetoothGattCallback().onConnectionStateChange(BluetoothGatt, int, int)的处理监听(这个是异步的,毕竟蓝牙底层处理需要时间),如果在调用disconnect后直接调用close(),将百分百出现空指针问题,切断开操作不够优雅!
- 自己的处理方式
检测连接是否真正的断开,函数封装
public int getConnectedState() {
int state = 100;
if (lock_bluetoothManager != null && (lock_mac != null | lock_mac == "") && mBluetoothAdapter != null
&& mBluetoothAdapter.isEnabled()) {
BluetoothDevice bdevice = mBluetoothAdapter.getRemoteDevice(lock_mac);
// 蓝牙连接状态为0,1,2,3 为了避免出问题初始化为100
/**
* STATE_DISCONNECTED 0 STATE_CONNECTING 1 STATE_CONNECTED 2 STATE_DISCONNECTING
* 3
*/
state = lock_bluetoothManager.getConnectionState(bdevice, BluetoothProfile.GATT);
}
Log.i("getConnectedState()方法调用,返回数据为-->", String.valueOf(state));
return state;
}
具体断开操作思路:
- 在需要断开连接的地方,调用 mBluetoothGatt.disconnect(); 进行尝试断开处理操作;
- 等待 onConnectionStateChange(BluetoothGatt, int, int) 状态监听函数的触发;
- 为了避免信号的变化导致的连接不稳定,需要对连接失败做一个处理,getConntectState();
- 在连接状态回调处,进行判断
-
if (newState == BluetoothProfile.STATE_DISCONNECTED) {// 连接失败 或者连接断开都会调用此方法 Log.i("连接回调-->", "getConnectedState()"); if (getConnectedState() == BluetoothProfile.STATE_CONNECTED) { Log.i("onConnectionStateChange-->", "连接伪失败"); return; } Log.i("onConnectionStateChange-->", "连接失败"); Message message = new Message(); message.what = CONNECT_FAIL; AppSendMesg(message); }
在CONNECT_FAIL中实现处理(此时的状态是真正的断开了连接了),此时需要对连接对象进行资源释放操作
-
if(mBluetoothGatt != null) { //释放资源 mBluetoothGatt.close(); }
-