我建立了一个BLE连接,用于在设备之间发送数据(每10秒钟他们建立一个新连接,发送数据,然后断开连接),通常工作正常。 但是,几分钟后,设备永远不再连接,应该与另一个连接的设备处于循环调用“ ACTION_GATT_DISCONNECTED ”(此字符串指的是断开连接的接收器操作)。
在我的接收器中,我有3个相关的动作:
@Override
public void onReceive(Context context, Intent intent) {
customBluetoothManager = customBluetoothManager.getInstance(context, null, null);
final String action = intent.getAction();
Log.d("test", "onReceive");
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
Log.d("test", action);
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
Log.d("test", action);
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
Log.d("test", action);
//....
//Code to send data after services discovered
//....
}
}
所以,在最初的几分钟内一切正常。首先是调用 ACTION_GATT_CONNECTED ,然后调用 ACTION_GATT_SERVICES_DISCOVERED 操作,然后设备发送数据,然后断开连接并释放蓝牙通信通道。 问题是,有时候,并不总是在同一点(由于这个原因,我无法找到任何模式来重现这个问题),循环总是调用 ACTION_GATT_DISCONNECTED ,所以沟通永远不会成立。
从 BluetoothGattCallback 类的 onConnectionSateChange 回调中分配 ACTION_GATT_DISCONNECTED :
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
mBluetoothGatt.close();
}
}
我不知道会出现什么问题......有什么建议吗?
---------- UPDATE --------------
使用进行连接的回调更新:
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
String name = device.getName();
long epoch = System.currentTimeMillis() / 1000;
SharedPreferences prefs = context.getSharedPreferences(
"epoch", Context.MODE_PRIVATE);
long epochStored = prefs.getLong("epoch", 0);
if (name != null && name.compareTo(bluetoothDeviceName) == 0 && (epochStored == 0 || epochStored < epoch - Utils.getDelay())) {
mac = device.getAddress();
mDeviceAddress = device.getAddress();
final Intent gattServiceIntent = new Intent(context, BluetoothLeService.class);
if (!connected) {
Utils.setMessageLog(ac, tv, "Binding service");
context.bindService(gattServiceIntent, mServiceConnection, context.BIND_AUTO_CREATE);
} else {
mBluetoothLeService.connect(mac);
}
}
}
};
连接功能:
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
连接成功后,我在接收器中收到“SERVICES_DISCOVERED”动作,并通过此代码编写特征:
public void sendData() {
List<BluetoothGattService> listServices = mBluetoothLeService.getSupportedGattServices();
BluetoothGattService bluetoothGattService = null;
for (BluetoothGattService gattService : listServices) {
if (gattService.getUuid().compareTo(myUUID) == 0) {
bluetoothGattService = gattService;
}
}
if(bluetoothGattService != null) {
List<BluetoothGattCharacteristic> gattCharacteristics = bluetoothGattService.getCharacteristics();
ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
if (gattCharacteristic.getUuid().compareTo(myCharUUID)) == 0) {
charas.add(gattCharacteristic);
boolean status = mBluetoothLeService.writeCharacteristic(gattCharacteristic, Utils.getUserData(context, "id"));
}
}
}
}
第一次建立蓝牙通信工作正常。
-------------第二次更新--------------
我正在调用 close()来释放连接:
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
disconnect();
close();
}
close()函数:
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
----------- UPDATE WITH ERROR LOG ------------
05-31 11:14:38.581 5897-6100/app D/OCSC: Status: 0
05-31 11:14:38.581 5897-6100/app D/OCSC: New State: 2
05-31 11:15:08.361 5897-6073/app D/OCSC: Status: 0
05-31 11:15:08.361 5897-6073/app D/OCSC: New State: 2
05-31 11:15:35.031 5897-6010/app D/OCSC: Status: 0
05-31 11:15:35.031 5897-6010/app D/OCSC: New State: 2
05-31 11:16:08.331 5897-5909/app D/OCSC: Status: 0
05-31 11:16:08.341 5897-5909/app D/OCSC: New State: 2
05-31 11:16:36.031 5897-5908/app D/OCSC: Status: 0
05-31 11:16:36.031 5897-5908/app D/OCSC: New State: 2
05-31 11:17:08.341 5897-6100/app D/OCSC: Status: 0
05-31 11:17:08.341 5897-6100/app D/OCSC: New State: 2
05-31 11:17:38.621 5897-6100/app D/OCSC: Status: 0
05-31 11:17:38.621 5897-6100/app D/OCSC: New State: 2
05-31 11:18:08.431 5897-6058/app D/OCSC: Status: 0
05-31 11:18:08.431 5897-6058/app D/OCSC: New State: 2
05-31 11:18:38.011 5897-6123/app D/OCSC: Status: 0
05-31 11:18:38.011 5897-6123/app D/OCSC: New State: 2
05-31 11:19:13.451 5897-6123/app D/OCSC: Status: 133
05-31 11:19:13.451 5897-6123/app D/OCSC: New State: 0
当发生断开连接问题时,我看到总是将新状态显示为22或133(只有一次我看到新状态为19)。
D/OCSC: New State: 133
D/OCSC: Status: 0
D/OCSC: New State: 133
D/OCSC: Status: 0
D/OCSC: New State: 133
D/OCSC: Status: 0
D/OCSC: New State: 22
D/OCSC: Status: 0
D/OCSC: New State: 22
D/OCSC: Status: 0
D/OCSC: New State: 22
D/OCSC: Status: 0
我在btsnoop_hci.log上找到了错误:
Rcvd错误响应 - 找不到属性,句柄:0x0005,句柄: 0x0005(通用访问配置文件:外观)
按类型请求发送读取,GATT包含声明,句柄: 0x0006..0x0008
Rcvd错误响应 - 找不到属性,句柄:0x0006,句柄: 0x0006(通用属性配置文件)
...
Rcvd错误响应 - 找不到属性,句柄:0x0008,句柄: 0x0008(通用属性配置文件:服务已更改)
...
Rcvd错误响应 - 找不到属性,句柄:0x0102,句柄: 0x0102(未知:未知)
...
Rcvd错误响应 - 无效的属性值长度,句柄:0x0102, 句柄:0x0102(未知:未知)
Logcat(测试1):
BluetoothGatt: onClientConnectionState() - status=0 clientIf=10
OCSC : Status: 0
OCSC : New State: 2
OCSC : Connected to GATT server.
BluetoothGatt: discoverServices()
BluetoothLeService: Attempting to start service discovery:true
test : com.example.bluetooth.le.ACTION_GATT_CONNECTED
BluetoothGatt: onClientConnectionState() - status=22 clientIf=8
BluetoothGatt: onClientConnectionState() - status=22 clientIf=10
BtGatt.GattService: onDisconnected() - clientIf=12
luetoothGatt: onClientConnectionState() - status=22 clientIf=11
BluetoothGatt: onClientConnectionState() - status=22 clientIf=12
OCSC : Status: 22
OCSC : New State: 0
OCSC : Disconnected from GATT server.
OCSC : Status: 22
OCSC : New State: 0
OCSC : Disconnected from GATT server.
OCSC : Status: 22
OCSC : New State: 0
OCSC : Disconnected from GATT server.
OCSC : Status: 22
OCSC : New State: 0
OCSC : Disconnected from GATT server.
BluetoothGatt: close()
BluetoothGatt: close()
BluetoothGatt: close()
BluetoothGatt: close()
Logcat(测试2):
BluetoothGatt: onClientConnectionState() - status=133 clientIf=7
OCSC : Status: 133
OCSC : New State: 0
OCSC : Disconnected from GATT server.
BluetoothGatt: close()
BluetoothGatt: onClientConnectionState() - status=133 clientIf=7
OCSC : Status: 133
OCSC : New State: 0
OCSC : Disconnected from GATT server.
BluetoothGatt: close()
BluetoothGatt: onClientConnectionState() - status=22 clientIf=12
OCSC : Status: 22
OCSC : New State: 0
OCSC : Disconnected from GATT server.
BluetoothGatt: close()
有什么想法吗?
答案 0 :(得分:0)
我怀疑你完成后不会清理BluetoothGatt对象。断开连接后,如果您对使用该BluetoothGatt对象不再需要连接到设备感兴趣,则必须调用该对象上的.close()以释放该对象分配的资源。所有应用程序的最大BluetoothGatt对象在最新的Android版本上为32。
您的代码中似乎覆盖了变量mBluetoothGatt。这样你就失去了引用而不能再调用close了...在删除引用之前一定要关闭它。