重新访问android 上的bluetooth-lowenergy 问题:我仍在使用延迟。
概念:在每个引发BluetoothGattCallback 的重大操作(例如连接、服务发现、写入、读取)之后,都需要一个交易。附言查看 BLE API level 19 sample for connectivity 上的 Google 示例,了解应该如何发送广播并获得一些一般性的了解等...
首先,scan(或scan)用于蓝牙设备,用所需设备填充 connectionQueue 并调用 initConnection()。
看看下面的例子。
private Queue<BluetoothDevice> connectionQueue = new LinkedList<BluetoothDevice>();
public void initConnection(){
if(connectionThread == null){
connectionThread = new Thread(new Runnable() {
@Override
public void run() {
connectionLoop();
connectionThread.interrupt();
connectionThread = null;
}
});
connectionThread.start();
}
}
private void connectionLoop(){
while(!connectionQueue.isEmpty()){
connectionQueue.poll().connectGatt(context, false, bleInterface.mGattCallback);
try {
Thread.sleep(250);
} catch (InterruptedException e) {}
}
}
现在,如果一切正常,您已经建立了连接,并且已经调用了 BluetoothGattCallback.onConnectionStateChange(BluetoothGatt gatt, int status, int newState)。
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
switch(status){
case BluetoothGatt.GATT_SUCCESS:
if (newState == BluetoothProfile.STATE_CONNECTED) {
broadcastUpdate(BluetoothConstants.ACTION_GATT_CONNECTED, gatt);
}else if(newState == BluetoothProfile.STATE_DISCONNECTED){
broadcastUpdate(BluetoothConstants.ACTION_GATT_DISCONNECTED, gatt);
}
break;
}
}
protected void broadcastUpdate(String action, BluetoothGatt gatt) {
final Intent intent = new Intent(action);
intent.putExtra(BluetoothConstants.EXTRA_MAC, gatt.getDevice().getAddress());
sendBroadcast(intent);
}
附: sendBroadcast(intent) 可能需要这样做:
Context context = activity.getBaseContext();
context.sendBroadcast(intent);
然后广播被BroadcastReceiver.onReceive(...)接收
public BroadcastReceiver myUpdateReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(BluetoothConstants.ACTION_GATT_CONNECTED.equals(action)){
//Connection made, here you can make a decision: do you want to initiate service discovery.
// P.S. If you are working with multiple devices,
// make sure that you start the service discovery
// after all desired connections are made
}
....
}
}
在广播接收器中做任何你想做的事后,我会继续:
private Queue<BluetoothGatt> serviceDiscoveryQueue = new LinkedList<BluetoothGatt>();
private void initServiceDiscovery(){
if(serviceDiscoveryThread == null){
serviceDiscoveryThread = new Thread(new Runnable() {
@Override
public void run() {
serviceDiscovery();
serviceDiscoveryThread.interrupt();
serviceDiscoveryThread = null;
}
});
serviceDiscoveryThread.start();
}
}
private void serviceDiscovery(){
while(!serviceDiscoveryQueue.isEmpty()){
serviceDiscoveryQueue.poll().discoverServices();
try {
Thread.sleep(250);
} catch (InterruptedException e){}
}
}
同样,在服务发现成功后,BluetoothGattCallback.onServicesDiscovered(...) 被调用。同样,我向 BroadcastReceiver 发送了一个意图(这次使用不同的操作字符串),现在您可以开始阅读、编写和启用通知/指示...
附注如果您使用多台设备,请确保在所有设备都报告已发现其服务后开始读取、写入等内容。
private Queue<BluetoothGattCharacteristic> characteristicReadQueue = new LinkedList<BluetoothGattCharacteristic>();
private void startThread(){
if(initialisationThread == null){
initialisationThread = new Thread(new Runnable() {
@Override
public void run() {
loopQueues();
initialisationThread.interrupt();
initialisationThread = null;
}
});
initialisationThread.start();
}
}
private void loopQueues() {
while(!characteristicReadQueue.isEmpty()){
readCharacteristic(characteristicReadQueue.poll());
try {
Thread.sleep(BluetoothConstants.DELAY);
} catch (InterruptedException e) {}
}
// A loop for starting indications and all other stuff goes here!
}
BluetoothGattCallback 将拥有来自 BLE 传感器的所有传入数据。一个好的做法是将带有数据的广播发送到您的 BroadcastReceiver 并在那里处理它。