La conexión a un dispositivo Bluetooth falla en el sueño profundo

Estoy tratando de conectarme a un dispositivo bluetooth emparejado cada 25 segundos, programado a través de AlarmManager que activa un WakefulBroadcastReceiver para iniciar un servicio para realizar la conexión. Una vez que el dispositivo se va a dormir, todo funciona bien durante las primeras horas, pero empieza a fallar después de 4-5 horas, cuando supongo que el dispositivo entra en un sueño profundo .

Obtengo una NullPointerException de ParcelFileDescriptor, indicando que "FileDescriptor no debe ser nulo". He intentado buscar este error, e incluso he ido a través del código en ParcelFileDescriptor.java, pero estoy en un callejón sin salida. Estoy ejecutando esto en un Nexus 10, con Android 4.4.2. El código que intenta conectarse es el siguiente:

public GatewaySocket getSocket() throws IOException { if (!BluetoothAdapter.checkBluetoothAddress(macAddress)) return new GatewaySocket("Address " + macAddress + " is not a valid Bluetooth MAC Address"); BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter(); if (bluetooth == null) return new GatewaySocket("Sorry, no Bluetooth adapter available"); BluetoothDevice device = bluetooth.getRemoteDevice(macAddress); BluetoothSocket btSocket = null; try { btSocket = device.createRfcommSocketToServiceRecord(uuid); } catch (Exception e) { log(3, "" + this, "Error closing socket on connection: " + e); } if (btSocket == null) return new GatewaySocket("Unable to launch insecure connection to " + device); try { btSocket.connect(); } catch (IOException ex) { try { btSocket.close(); } catch (IOException ex2) { // do nothing } throw (ex); } GatewaySocket socket = new GatewaySocket(btSocket, btSocket.getInputStream(), btSocket.getOutputStream()); return socket; } 

GatewaySocket es una subclase delgada de BluetoothSocket. El error se produce en la línea btSocket.connect (), con la siguiente traza de pila:

 01-10 09:13:57.796: W/BluetoothAdapter(3591): getBluetoothService() called with no BluetoothManagerCallback 01-10 09:13:57.801: D/BTIF_SOCK(979): service_uuid: 00001101-0000-1000-8000-00805f9b34fb 01-10 09:13:57.801: E/bt-btif(979): SOCK_THREAD_FD_RD signaled when rfc is not connected, slot id:4374, channel:-1 01-10 09:13:57.801: W/System.err(3591): java.lang.NullPointerException: FileDescriptor must not be null 01-10 09:13:57.806: W/System.err(3591): at android.os.ParcelFileDescriptor.<init>(ParcelFileDescriptor.java:174) 01-10 09:13:57.806: W/System.err(3591): at android.os.ParcelFileDescriptor$1.createFromParcel(ParcelFileDescriptor.java:905) 01-10 09:13:57.806: W/System.err(3591): at android.os.ParcelFileDescriptor$1.createFromParcel(ParcelFileDescriptor.java:897) 01-10 09:13:57.806: W/System.err(3591): at android.bluetooth.IBluetooth$Stub$Proxy.connectSocket(IBluetooth.java:1322) 01-10 09:13:57.806: W/System.err(3591): at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:308) 01-10 09:13:57.806: W/System.err(3591): at com.gateway.service.AndroidGMConversation.getSocket(AndroidGMConversation.java:162) 01-10 09:13:57.806: W/System.err(3591): at com.gateway.GatewayManagerConversation.converse(GatewayManagerConversation.java:81) 01-10 09:13:57.806: W/System.err(3591): at com.gateway.GatewayManagerConversation.run(GatewayManagerConversation.java:72) 01-10 09:13:57.806: W/System.err(3591): at java.lang.Thread.run(Thread.java:841) 01-10 09:13:57.806: V/PS(3591): Finished with device 06:92:25:0A:A5:50 

¡Cualquier sugerencia sera apreciada!

He encontrado la solución después de pasar por las clases de la biblioteca de Bluetooth, y encontré que no cierra el FileDescriptor mientras que llama a bluetoothsocket.close(); A pesar de que llama al método dispatch() sobre el FileDescriptor, que no lo cierra.

Simplemente llame a este método antes del bluetoothsocket.close();

 private synchronized void clearFileDescriptor(){ try{ Field field = BluetoothSocket.class.getDeclaredField("mPfd"); field.setAccessible(true); ParcelFileDescriptor mPfd = (ParcelFileDescriptor)field.get(socket); if(null == mPfd){ return; } mPfd.close(); }catch(Exception e){ Log.w(SensorTicker.TAG, "LocalSocket could not be cleanly closed."); } } 

Espero que esto solucione el problema de otros también. Pero debe ser manejado por la clase BluetoothSocket sobre el método close.

Esto parece el fallo BluetoothSocket.close () en Android 4.2 – 4.4.4, que parece estar fijado en 5.0. Básicamente, no está liberando el descriptor de archivo subyacente, por lo que se filtra hasta que llegue al límite de su dispositivo, y luego suceden cosas extrañas. Necesita obtener el ParcelFileDescriptor del BluetoothSocket y cerrarlo usted mismo.

Echa un vistazo a mi respuesta aquí para el código de solución: https://stackoverflow.com/a/27873675/1893015

  • Decodificación qr código de la imagen almacenada en el teléfono con Zxing (en el teléfono Android)
  • ¿Cómo descargar múltiples archivos simultáneamente usando intentservice en Android?
  • Acceso concurrente a archivos en Android
  • ¿Cómo buscar la cadena entera para una palabra específica?
  • ¿Por qué obtengo "Falló al rebotar al escribir" cuando convertí JSON de Firebase en objetos Java?
  • Triangle opengl en android
  • Envío de una cadena a través de Bluetooth desde un PC como cliente a un móvil como servidor
  • ¿Por qué el VoiceListener basado en Glass / GDK sólo captura VoiceCommand una vez en XE16?
  • Configurar mapa de bits como fondo de la vista de texto - Android
  • El complemento com.android.ide.eclipse.adt no ha podido cargar la clase android
  • Org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Campo no reconocido "id" (Criterios de clase), no marcado como ignorable
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.