Повторно разглеждане на проблема с bluetooth-lowenergy на android: Все още използвам забавяния.
Концепцията: след всяко основно действие, което провокира BluetoothGattCallback (напр. свързване, откриване на услуга, писане, прочетете) необходима е сделка. P.S. разгледайте примера на Google за BLE API ниво 19 пример за свързаност за да разберете как трябва да се изпращат излъчвания и да получите някакво общо разбиране и т.н...
Първо сканирайте (или сканиране) за BluetoothDevices, попълнете 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);
}
P.S. 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 (този път с различен низ за действие) и сега можете да започнете да четете, пишете и активирате известия/индикации... P.S. Ако работите с множество устройства, уверете се, че сте започнали нещата за четене, писане и т.н., след като всички устройства са съобщили, че услугите им са били открити.
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 и да го обработвате там.
person
Rain
schedule
10.12.2014