我正在尝试按如下方式创建BLE模块:
Connect -> Discover Service -> Auto Set characteristics -> Send checkSum Bytes
如果设备在10秒内无法接收到字节,蓝牙连接将断开连接。
说到这种做法,即使我设置了后台Thread
来发送校验和字节,蓝牙连接也会断开连接。我发现创建Handler消息太难以通过广播将消息从BLuetoothLeService返回到Main Activity
。即使我已经宣布立即找到服务和特性,但在发送字节之前没有得到任何响应。您能否告诉我哪些回调方法应该找到并设置?
以下是我的工作:
DeviceControlActivity.java
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG , "Unable to initialize Bluetooth");
finish();
}
mBluetoothLeService.connect(mDeviceAddress);
mBluetoothLeService.setBLEServiceCb(mDCServiceCb);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
int status = intent.getIntExtra(BluetoothLeService.EXTRA_STATUS, BluetoothGatt.GATT_SUCCESS);
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
if(BluetoothLeService.getBtGatt() != null)
{
BluetoothLeService.getBtGatt().discoverServices();
}
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the user interface.
displayGattServices(mBluetoothLeService.getSupportedGattServices());
}
else if (BluetoothLeService.ACTION_DATA_NOTIFY.equals(action)) {
// Notification
byte [] value = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);
String uuidStr = intent.getStringExtra(BluetoothLeService.EXTRA_UUID);
boolean isFloat = intent.getBooleanExtra(BluetoothLeService.EXTRA_FLOAT, false);
packetLength = intent.getIntExtra(BluetoothLeService.EXTRA_LENGTH, 20);
System.out.println("status B : " + isFloat);
if(isFloat){
onCharacteristicChangedWithParam(uuidStr, value);
}else{
onCharacteristicChanged(uuidStr, value);
}
} else if (BluetoothLeService.ACTION_DATA_WRITE.equals(action)) {
// Data written
String uuidStr = intent.getStringExtra(BluetoothLeService.EXTRA_UUID);
onCharacteristicWrite(uuidStr,status);
} else if (BluetoothLeService.ACTION_DATA_READ.equals(action)) {
// Data read
String uuidStr = intent.getStringExtra(BluetoothLeService.EXTRA_UUID);
byte [] value = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);
onCharacteristicsRead(uuidStr,value,status);
}
}
};
BluetoothLeService.java
/**
* Service for managing connection and data communication with a GATT server hosted on a
* given Bluetooth LE device. */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class BluetoothLeService extends Service {
public static BluetoothGatt getBtGatt() {
return mBluetoothGatt;
}
public static BluetoothManager getBtManager() {
return mThis.mBluetoothManager;
}
public static BluetoothLeService getInstance() {
return mThis;
}
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (mBluetoothGatt == null) {
Log.e(TAG , "mBluetoothGatt not created!");
// return;
}
BluetoothDevice device = gatt.getDevice();
String address = device.getAddress();
// Log.d("onConnectionStateChange status = " + status + ", newState = " + newState);
try {
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
broadcastUpdate(ACTION_GATT_CONNECTED, address, status);
startReadRssi();
break;
case BluetoothProfile.STATE_DISCONNECTED:
broadcastUpdate(ACTION_GATT_DISCONNECTED, address, status);
stopReadRssi();
break;
default:
Log.e(TAG , "New state not processed: " + newState);
break;
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
BluetoothDevice device = gatt.getDevice();
BluetoothGattService rblService = mBluetoothGatt.getService(U_ABC_SERVICE);
if (rblService == null) {
Log.e(TAG, "RBL service not found!");
return;
}
List<BluetoothGattCharacteristic> Characteristic = rblService
.getCharacteristics();
for (BluetoothGattCharacteristic a : Characteristic) {
Log.e(TAG, " a = uuid : " + a.getUuid() + "");
}
setReadChar();
mWriteCharacteristic = rblService.getCharacteristic(U_ABC_W_CHARACTERISTIC);
if (mWriteCharacteristic == null) {
Log.e(TAG, "RBL TX Characteristic not found!");
return;
}
mCmdCharacteristic = rblService.getCharacteristic(U_ABC_C_CHARACTERISTIC);
if (mCmdCharacteristic == null) {
Log.e(TAG, "RBL CMD Characteristic not found!");
return;
}
// List<BluetoothGattService> gattServices = gatt.getServices();
/*
mWriteService = gatt.getService(U_ABC_SERVICE);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCmdCharacteristic = mWriteService.getCharacteristic(U_ABC_C_CHARACTERISTIC);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setReadChar();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mWriteCharacteristic = mWriteService.getCharacteristic(U_ABC_W_CHARACTERISTIC);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED, device.getAddress(), status);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
//readCharacteristicQueue.remove();
broadcastUpdate(ACTION_DATA_NOTIFY, characteristic , BluetoothGatt.GATT_SUCCESS);
}