Error Android Bluetooth LE: Error al registrar la devolución de llamada

Estoy en el proceso de escribir una aplicación de Android que se conectará a un dispositivo de salud a través de Bluetooth LE. Sin embargo, parece que no me estoy conectando a su servidor GATT correctamente. Cada pocos segundos, mi archivo de registro muestra esto:

03-27 11:33:39.821: D/BluetoothAdapter(26644): onScanResult() - Device=0C:F3:EE:AA:33:35 RSSI=-53 03-27 11:33:39.821: I/BluetoothGattActivity(26644): New LE Device: BT-001 @ -53 03-27 11:33:39.821: I/BluetoothGattActivity(26644): New LE Device matches !!! 03-27 11:33:39.831: I/BluetoothGattActivity(26644): In the fish function. 03-27 11:33:39.831: D/BluetoothGatt(26644): connect() - device: 0C:F3:EE:AA:33:35, auto: false 03-27 11:33:39.831: D/BluetoothGatt(26644): registerApp() 03-27 11:33:39.831: D/BluetoothGatt(26644): registerApp() - UUID=7155a6e0-5432-42cc-8b05-a080c86aaccb 03-27 11:33:39.841: I/BluetoothGatt(26644): Client registered, waiting for callback 03-27 11:33:49.840: E/BluetoothGatt(26644): Failed to register callback 03-27 11:33:49.840: I/BluetoothGattActivity(26644): myBluetoothGatt is null 

Si alguien me puede ayudar a ver dónde está mi problema y lo que está pasando, sería muy apreciado. Estoy usando un Galaxy s4. Creo que todo mi código relevante está abajo:

 private void broadcastUpdate(final String action) { final Intent intent = new Intent(action); sendBroadcast(intent); } private void fish(final BluetoothDevice device) { Log.i(TAG, "In the fish function."); myBluetoothGatt = device.connectGatt(this, false, myGattCallback); Log.i(TAG, "myBluetoothGatt is " + myBluetoothGatt); } private BluetoothAdapter.LeScanCallback callbackFunction = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.i(TAG, "New LE Device: " + device.getName() + " @ " + rssi); if (DEVICE_NAME.equals(device.getName())) { Log.i(TAG, "New LE Device matches !!!"); fish (device); } } }; private final BluetoothGattCallback myGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String intentAction; Log.i(TAG, "We are in the ConnectionStateChanged()."); if (newState == BluetoothProfile.STATE_CONNECTED) { intentAction = ACTION_GATT_CONNECTED; mConnectionState = STATE_CONNECTED; broadcastUpdate(intentAction); Log.i(TAG, "Connected to GATT server."); Log.i(TAG, "Attempting to start service discovery:" + myBluetoothGatt.discoverServices()); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { intentAction = ACTION_GATT_DISCONNECTED; mConnectionState = STATE_DISCONNECTED; Log.i(TAG, "Disconnected from GATT server."); broadcastUpdate(intentAction); } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { Log.i(TAG, "In area 1"); if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); System.out.println("--onServicesDiscovered"); } else { Log.w(TAG, "onServicesDiscovered received: " + status); } } @Override public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) { Log.i(TAG, "In area 2"); if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE); Log.i(TAG, "--onCharacteristicRead GATT_SUCCESS"); } } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { Log.i(TAG, "In area 3"); broadcastUpdate(ACTION_DATA_AVAILABLE); System.out.println("--onCharacteristicChanged"); } }; 

La llamada a device.connectGatt (esto, false, myGattCallback), debe hacerse en UIThread principal. Así que debería ser algo como esto:

 private void fish(final BluetoothDevice device) { Log.i(TAG, "In the fish function."); runOnUiThread(new Runnable() { @Override public void run() { myBluetoothGatt = device.connectGatt(this, false, myGattCallback); } }); } 

Tengo una corrección parcial para esta forma particular del error. Vi en esta pregunta la devolución de llamada del GATT falla al registrar que los dispositivos Samsung requieren que los intentos de descubrimiento Gatt se realicen en el subproceso de la interfaz de usuario.

La parte difícil para mí fue darse cuenta de que no estaba en el hilo que pensé que era. La devolución de llamada onLeScan no se devuelve en el subproceso de interfaz de usuario, sino en un subproceso Binder (al menos según el depurador). Terminé teniendo que utilizar un Handler para publicar un Runnable que inició mi código de descubrimiento de servicio.

La razón de esto es una solución parcial es que ahora estoy en un estado donde la conexión Gatt no es nulo, pero se bloquea después de estas líneas

 04-04 14:21:15.115 9616-9616/BluetoothApp I/BluetoothGatt﹕ Client registered, waiting for callback 04-04 14:21:15.115 9616-9627/BluetoothApp D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=5 

Todavía no he descubierto cómo solucionar este último problema, pero esto debería llevarte un paso más allá.

Registre tanto el callback como el device.connectGatt (esto, false, myGattCallback) dentro de un servicio de enlace y para uso posterior de la comunicación use el receptor.

Una vez que reciba el evento o los datos en la devolución de llamada, haga lo mismo y reciba del reciver (que debería estar escrito en la aplicación como una actividad principal separada o dentro si utiliza sólo una actividad y el resto de todos son fragmentos).

  • Solicitar opción de sitio de escritorio en dispositivos móviles
  • Android - Creación de listview con encabezados flotantes
  • Creación de una versión móvil de un sitio web
  • ¿Cómo maneja Android los hilos de fondo cuando deja una Actividad?
  • Titanio api.info nunca muestra nada en la consola
  • Buscando un AR con biblioteca de reconocimiento de imágenes
  • Desarrollando PhoneGap para Android - Mejor práctica para diferentes tamaños de pantalla / densidad de píxeles
  • Trabajar alrededor de QString móvil error
  • Mejor solución de desarrollo móvil multiformato C ++?
  • Android y la elección del marco IOS backend?
  • Problemas para conseguir que el video se reproduzca en Recyclerview
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.