android – 蓝牙GATT onConnectionState更改不适用于Lollipop
作者:互联网
我目前有一种方法可以写入BLE设备发出蜂鸣声.我的蓝牙回拨如下:
public class ReadWriteCharacteristic extends BluetoothGattCallback {
public ReadWriteCharacteristic(Context context, String macAddress, UUID service, UUID characteristic, Object tag, Activity activity) {
mMacAddress = macAddress;
mService = service;
mCharacteristic = characteristic;
mTag = tag;
mContext = context;
this.activity =activity;
final BluetoothManager bluetoothManager =
(BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
}
final private static String TAG = "ReadCharacteristic";
private Object mTag;
private String mMacAddress;
private UUID mService;
private BluetoothManager mBluetoothManager = null;
private BluetoothAdapter mBtAdapter = null;
private BluetoothGatt mBluetoothGatt = null;
private String mBluetoothDeviceAddress ="";
private UUID mCharacteristic;
BluetoothDevice device;
private Activity activity;
private BluetoothAdapter mBluetoothAdapter;
private Context mContext;
ReadWriteCharacteristic rc;
private int retry = 5;
public String getMacAddress() {
return mMacAddress;
}
public UUID getService() {
return mService;
}
public UUID getCharacteristic() {
return mCharacteristic;
}
public byte[] getValue() { return mValue; }
public void one rror() {
Log.w(TAG, "onError");
}
public void readCharacteristic(){
if (retry == 0)
{
one rror();
return;
}
retry--;
device = mBluetoothAdapter.getRemoteDevice(getMacAddress());
mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
int connectionState = mBluetoothManager.getConnectionState(device,
BluetoothProfile.GATT);
if (device != null) {
if (connectionState == BluetoothProfile.STATE_DISCONNECTED)
{
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null
&& getMacAddress().equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.w(TAG, "Re-use GATT connection");
if (mBluetoothGatt.connect()) {
Log.w(TAG, "Already connected, discovering services");
mBluetoothGatt.discoverServices();
//return ;
} else {
Log.w(TAG, "GATT re-connect failed.");
return;
}
}
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return;
}
Log.w(TAG, "Create a new GATT connection.");
rc= ReadWriteCharacteristic.this;
Log.w(TAG, "Starting Read [" + getService() + "|" + getCharacteristic() + "]");
mBluetoothGatt = device.connectGatt(mContext, false, rc);
refreshDeviceCache(mBluetoothGatt);
mBluetoothDeviceAddress = getMacAddress();
} else {
Log.w(TAG, "Attempt to connect in state: " + connectionState);
if(mBluetoothGatt!=null)
mBluetoothGatt.close();
readCharacteristic();
}
}
}
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
Log.w(TAG,"onConnectionStateChange [" + status + "|" + newState + "]");
if ((newState == 2)&&(status ==0)) {
gatt.discoverServices();
}
else if(status == 133 )
{
//gatt.disconnect();
gatt.close();
mBluetoothGatt = null;
try
{
Thread.sleep(2000);
}
catch(Exception e)
{
}
readCharacteristic();
}
else{
if(mBluetoothGatt!=null)
mBluetoothGatt.close();
// gatt.close();
Log.w(TAG, "[" + status + "]");
//gatt.disconnect();
try
{
Thread.sleep(2000);
}
catch(Exception e)
{
}
mBluetoothGatt = null;
readCharacteristic();
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
Log.w(TAG,"onServicesDiscovered [" + status + "]");
BluetoothGattService bgs = gatt.getService(getService());
if (bgs != null) {
BluetoothGattCharacteristic bgc = bgs.getCharacteristic(getCharacteristic());
gatt.readCharacteristic(bgc);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
Log.w(TAG,"onCharacteristicWrite [" + status + "]");
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.w(TAG,"onCharacteristicWrite [" + getDataHex(characteristic.getValue()) + "]");
// gatt.disconnect();
if(mBluetoothGatt!=null)
mBluetoothGatt.close();
// gatt.close();
// mBluetoothGatt=null;
}
else if(status ==133)
{
gatt.close();
try
{
Thread.sleep(2000);
}
catch(Exception e)
{
}
readCharacteristic();
}
else{
//gatt.disconnect();
gatt.close();
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
Log.w(TAG,"onCharacteristicRead [" + status + "]");
if (status == BluetoothGatt.GATT_SUCCESS) {
mValue = characteristic.getValue();
// Perform write operations
gatt.writeCharacteristic(bgc);
}
else if(status ==133)
{
gatt.close();
try
{
Thread.sleep(2000);
}
catch(Exception e)
{
}
readCharacteristic();
}
else {
// gatt.disconnect();
gatt.close();
}
}
}
此代码适用于运行Kitkat及以下设备.但是在运行Lollipop的设备上,这个代码适用于第一个实例.但是从下一个例子来看,无论我是断开连接还是关闭连接并重试,它都无法正常工作.它在onConnectionStateChange方法中不断给我一个257的状态代码.据我所知,蓝牙GATT方法对于kitkat和Lollipop设备都是相同的.
令我惊讶的是,当我使用旧的BLE API时,这个代码在Lollipop设备上工作正常,即startLeScan(例如 – mBluetoothAdapter.startLeScan(mLeScanCallback);).这个问题只出现在我使用新的BLE API时,即BluetoothLeScanner(scanner.startScan(filters,settings,new scancallback());).对于使用旧BLE API的Lollipop设备,扫描速度非常慢,因此我无法使用它.我只是不明白如何解决这个问题.有没有人遇到同样的问题,并找到了解决方案?任何帮助将深表感谢.
解决方法:
我会在这里改变一些事情.为要从特征中读取的数据创建一个类变量,例如private string heartRate;
1)您不需要readCharacteristic()方法.相反,在设备正确连接后的onConnectionStateChange中,调用mBluetoothGatt.discoverServices().然后在onServicesDiscovered()方法中,我将调用gatt.getServices().然后使用foreach循环并遍历返回的服务并比较服务的UUID,直到找到您关心的服务.然后,如果heartRate == null,则调用service.getCharacteristic(HeartRateUUID),然后读取特征.在onCharacteristicRead()中检查UUID是否等于心率特征.如果是,则将特征值赋给heartRate变量.如果您有兴趣,我可以输入方法或提供伪代码.
2)我不会调用gatt.connect(),然后调用gatt.discoverServices().一旦看到来自设备的广告包,gatt.connect()就会重新连接到当前设备.我会调用gatt.connect()然后在onConnectedStateChange()方法中调用gatt.discoverServices().
3)在onConnectedStateChange方法中,不要使用gatt变量.请改用mBluetoothGatt. mBluetoothGatt.disconnect()与当前连接的设备断开连接. mBluetoothGatt.close()终止gatt实例.调用mBluetoothGatt.Close()后,无法调用mBluetoothGatt.connect().这可能不需要,但如果设备已连接,我调用mBluetoothGatt.disconnect(),然后调用mBluetoothGatt.close().
4)您还可以将特征读数链接在一起.在onCharacteristicRead()中,在获得heartRate的值之后,可以立即调用characteristic.getService().getCharacteristic(UUIDTemperature)然后读取该特性.它将再次调用OnCharacteristicRead方法.
如果您要我澄清任何事情,请告诉我.我在蹩脚的Surface Pro 3键盘上打字.
标签:android,android-5-0-lollipop,bluetooth-lowenergy,android-bluetooth,android-ble 来源: https://codeday.me/bug/20190623/1273578.html