android - studio - bluetooth low energy
Android BluetoothGatt-estado 133-registro de devoluciĆ³n de llamada (3)
De acuerdo, lo he descubierto. El problema fue principalmente un descuido de cuando estaba leyendo la documentación de BluetoothGatt
. Estaba llamando .disconnect()
, pero no .close()
. Como Galaxy s4 solo puede manejar 6 conexiones a la vez, mi servicio solo se ejecutó 6 veces. Agregar el .close()
a mi código permitió que cerrara adecuadamente la conexión y liberara esas conexiones usadas.
code.google.com/p/android/issues/detail?id=68538
¡Así que recuerde usar .close () en su objeto BluetoothGatt si tiene una conexión recurrente al mismo dispositivo (s)!
Antes que nada, leí SOLUCIONADO: la devolución de llamada del GATT no se registra y tomó los pasos sugeridos en esa publicación para resolver este problema sin éxito. La solución recomendada allí si no la ha leído es realizar todas las llamadas BLE desde el hilo principal directamente o con un controlador.
Estoy trabajando en una aplicación BLE que desea ejecutar un servicio (llamado desde la actividad una vez cada 10 segundos) que realiza estas tareas:
1)Gets list of our products available to connect to (done, works)
2)For each available device:
2a)connect to device
2b)discover services
2c)read 5 characteristics in this fashion:
2c1)read characteristic
2c2)onCharacteristicRead parse data
2c3)when finished with data read next characteristic
2c4)repeat until all are read (this is done using a state var and switch statement)
2d)disconnect from device
2e)connect to next device
2f)repeat until all devices are read from
2g)stopSelf()
Entonces el problema ... Todo funciona bien por un tiempo. Puedo realizar todo el inicio del servicio {startService (...); en mainActivity} para terminar {stopSelf (); en servicio} 6 veces.
En la 7ma vez recibo BluetoothGatt Falló para registrar la devolución de llamada. No estoy seguro de por qué puedo ejecutarlo 6 veces con éxito y luego fallar en la 7ma vez.
Tenga en cuenta que estoy haciendo todas las llamadas BLE desde el hilo principal, y eso ha sido confirmado en el log cat desde múltiples ubicaciones.
Aquí hay un resumen de mi código:
SERVICE.JAVA
private Handler handler = new Handler();
private BluetoothGatt cGatt = null;
private int unitIndex = 0; // keep track of currently connected unit
private int state = 0; //used to keep track of which characteristic to read next
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i(TAG, "Service Started...");
//get ArrayList of units
if(units.size > 0)
handler.post(connectNextRunnable); //calls connectNextDevice()
else
stopSelf();
}
private Runnable discoverServices = new Runnable()
{
public void run()
{
cGatt.discoverServices();
}
}
private Runnable readNextValue = new Runnable()
{
public void run()
{
BluetoothGattCharacteristic c = null;
switch(state)
{
//set c to appropriate characteristic
default: // all characteristics read
unitIndex++;
handler.post(connectNextRunnable)
return
}
cGatt.readCharacteristic(c);
}
}
private void connectNextDevice()
{
if(unitIndex == 0)
store System.nanoTime in variable
if(unitIndex >= units.size) //finished will all units
stopSelf();
if(unitIndex < units.size)
cGatt.disconnect //if null
cGatt.connectGatt(this, false, gattCallback)
}
private BluetoothGattCallback gattCallback = new BluetoothGattCallback()
{
public void onConnectionStateChange()
{
handler.post(discoverServices);
}
public void onServicesDeiscovered()
{
handler.post(readNextValue);
}
public void onCharacteristicRead()
{
ParseData();
}
private void ParseData()
{
//do stuff with data
handler.post(readNextValue);
}
}
Entonces, como he dicho, todas las cosas BLE se llaman desde el hilo principal a través de un controlador. El servicio se ejecuta exitosamente 6 veces de principio a fin. En la 7 ª vez que obtengo ese tonto no pudo registrar la devolución de llamada.
Puedo proporcionar más información de logcat si crees que es relevante. No lo hice en la publicación original porque recibí mucha información para verificar los datos recibidos, etc.
La siguiente información es la información de logcat para la 7ma ejecución de mi servicio de principio a fin.
08-15 12:00:10.746: I/PMIQ BTS(32027): Service Started...
08-15 12:00:10.746: I/PMIQ BTS(32027): Units: 1
08-15 12:00:10.746: D/AbsListView(32027): unregisterIRListener() is called
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to next device...
08-15 12:00:10.766: I/PMIQ BTS(32027): Unit index = 0
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to pmIQ-IQ130_D93A
08-15 12:00:10.766: I/System.out(32027): main
08-15 12:00:10.766: D/BluetoothGatt(32027): connect() - device: 00:1E:C0:19:D9:3A, auto: false
08-15 12:00:10.766: D/BluetoothGatt(32027): registerApp()
08-15 12:00:10.766: D/BluetoothGatt(32027): registerApp() - UUID=e9d10870-4b09-451c-a9fa-c6b5f3594a77
08-15 12:00:10.766: I/BluetoothGatt(32027): Client registered, waiting for callback
08-15 12:00:10.766: D/BluetoothGatt(32027): onClientRegistered() - status=133 clientIf=0
08-15 12:00:10.766: I/PMIQ BTS(32027): CONECTION STATE CHANGED...Binder_2
**08-15 12:00:10.766: E/BluetoothGatt(32027): Failed to register callback**
08-15 12:00:10.766: I/PMIQ BTS(32027): Could not connect to null ... 257
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to next device...
08-15 12:00:10.766: I/PMIQ BTS(32027): Unit index = 1
08-15 12:00:10.766: I/PMIQ BTS(32027): ******************************
08-15 12:00:10.766: I/PMIQ BTS(32027): Start Time: 4360642409647
08-15 12:00:10.766: I/PMIQ BTS(32027): End Time: 4360648970925
08-15 12:00:10.766: I/PMIQ BTS(32027): Difference: 6561278
08-15 12:00:10.766: I/PMIQ BTS(32027): Time to complete: 6
08-15 12:00:10.766: I/PMIQ BTS(32027): ******************************
08-15 12:00:10.876: I/PMIQ BTS(32027): ...Service Destroyed
Si lo has logrado aquí, ¡gracias! No pude encontrar NINGUNA información sobre qué significa = 133 significa ?! Solo ocurre cuando la devolución de llamada falla. Cada otro tiempo es estado = 0.
08-15 12:00:10.766: D/BluetoothGatt(32027): onClientRegistered() - status=133 clientIf=0
Si alguien pudiera responder esto ... me puede ayudar mucho. O si alguien puede decirme por qué solo funciona 6 veces. ¡Cualquier idea o presentimiento podría ser útil!
¡Gracias a todos!
Después de meses de investigación y de sacarme el pelo, encontré una solución de la que normalmente no se habla.
Tu solicitud de conexión normal se ve más o menos así:
cGatt.connectGatt(this, false, gattCallback);
Hay otra versión del comando connectGatt, con un 4º parámetro. Este parámetro especifica a qué tipo de dispositivo bluetooth se está conectando. Agregué un "2" para especificar que me estoy conectando a través de Bluetooth LE. (se llama "transporte", perdóneme si mi explicación es incorrecta, pero solucionó todos mis problemas)
Prueba esto:
cGatt.connectGatt(this, false, gattCallback, 2);
¡Y BAM, ahora mi pesadilla # 133 ha terminado (rezo)!
SO Android <6.0:
mBluetoothDevice.connectGatt(context, false, callback);
Android OS> = 6.0:
mBluetoothDevice.connectGatt(context, false, callback, BluetoothDevice.TRANSPORT_LE);
En última instancia, se necesita equipo de hardware para resolver completamente este problema.