La conexión Bluetooth RFCOMM no se pudo establecer consecutivamente en Android 4.2

Tengo una aplicación que habla con un dispositivo personalizado a través de RFCOMM vía Bluetooth. El código de comunicación se basa en el proyecto de muestra BluetoothTalk. Estaba funcionando sin ningún problema antes en Galaxy S3, Galaxy S2, Galaxy Note y Nexus 7.

Recientemente, Nexus 7 fue actualizado a Android 4.2 y desde entonces, el problema ocurre de la siguiente manera:

  1. Cuando se utiliza la aplicación para configurar una conexión por primera vez, lo que significa que el dispositivo está encendido y la aplicación acaba de lanzarse, no hay problema, puede obtener datos normalmente.

  2. Entonces si usted para la comunicación, e intenta recomenzar, la comunicación falla con el error "java.io.IOException: zócalo del bt cerrado, lee vuelta: -1". A partir de ese momento, no importa cuántas veces intente reconectarse, simplemente falla siempre.

  3. La única manera de hacerlo funcionar de nuevo es, si reinicia el dispositivo personalizado y la aplicación, a continuación, intente conectarse, la comunicación se convierte en normal. Pero entonces, una vez que se detiene y reinicia la comunicación, sigue fallando.

Tomé prestado un Nexus 4 con Android 4.2 y el problema sigue siendo.

Es realmente molesto porque el principal valor de nuestro dispositivo es confiar en la aplicación Bluetooth RFCOMM. Revisé dos veces la documentación sobre BT en Android 4.2 y no vi ningún cambio significativo. Estoy bastante seguro de que el código de mi lado, ya que funciona para cualquier dispositivo Android no está ejecutando 4.2

Cualquier sugerencia o sugerencia sería muy apreciada. El dispositivo debe ser demostrado en el comienzo de diciembre y realmente queremos abordar este problema lo antes posible.

EDIT: Ahora que 4.2.1 ha sido liberado y el problema todavía no se resuelve. ¿Podemos al menos obtener alguna confirmación con respecto a si está bajo trabajo y se arreglará pronto?

Esto no le ayuda mucho, pero tenga en cuenta que Google presentó una nueva pila de Bluetooth con 4.2.

Esto debería ser una buena cosa – en mi experiencia como usuario y desarrollador, Android con Bluez (el antiguo combo) nunca funcionó de forma fiable, así que estaba muy contento de saber que se llevó a cabo una reescritura total.

Supongo que todo lo que puedo decir es que suena como si se han encontrado con un error o quirk en la nueva pila. Es lamentable oír que hay problemas con la nueva pila también.

En cuanto a su demo, tenga en cuenta que Google publica las imágenes de firmware de todos sus dispositivos Nexus (https://developers.google.com/android/nexus/images), y mostrarlas a sus dispositivos es bastante fácil.

Así que le sugiero que presente un informe de fallo y, a continuación, flash sus dispositivos a 4.1.2.

Tuve un problema similar y pasé un tiempo depurando este problema. Estoy funcionando con androide 4.3 y encontré la única modificación básica que fue requerida al código de la muestra de BluetoothChat fijando:

MY_UUID_SECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 

Estoy intentando conectar con un módulo del bluetooth HC-05 y creo que utiliza el perfil del SPP según lo indicado por este UUID. Puede consultar el UUID de un dispositivo con esta línea de código:

 UUID uuid = device.getUuids()[0].getUuid(); 

Compruebe el UUID y ver si coincide con un perfil que tiene sentido, en función del tipo de dispositivo al que se está conectando.

 MY_UUID_SECURE = uuid; 

El UUID puede indicar un tipo diferente de perfil de dispositivo, dependiendo de a qué se está conectando. Con el UUID adecuado, seguía siendo capaz de ejecutar el código AcceptThread y escuchar como un BluetoothServerSocket sin ningún problema. Espero que esto ayude, sin embargo, soy relativamente nuevo al desarrollo de Android y de Bluetooth, así que si mis suposiciones son incorrectas, me corrigen por favor.

Encontró problemas similares. Se arreglaron algunos de ellos construyendo con el SDK 4.2 con 17 como meta de compilación.

Por fin he descubierto la solución.

Resulta que no es un error en el nuevo controlador de Bluetooth. Es un caso de esquina no considerado en la aplicación de muestra Bluetooth, más específicamente, proyecto BluetoothChat, proporcionado por Android SDK.

En el código de servicio Bluetooth dentro del proyecto de ejemplo de BluetoothChat, cuando se produce un error o se pierde la conexión, se inicia el servicio para reiniciar el modo de escucha. No hay problema cuando el teléfono se utiliza como servidor, sin embargo, en algunos casos cuando el teléfono se utiliza como cliente, una vez que entra en modo de escucha, no se puede conectar a otros servidores. Porque en la función "conectar", no cancela (In) SecureAcceptThread. Así que esencialmente está escuchando otras conexiones como servidor al intentar conectarse a otros servidores como cliente. Es conflictivo.

La forma de resolver este problema es, si está seguro de que su teléfono no se utilizará como servidor de escucha de la conexión entrante, simplemente quite el código para reiniciar el modo de escucha una vez que la conexión falla o se detiene.

Encuentro con el mismo problema con mi Nexus 4.

En mi caso, creo que el problema radica en el protocolo de descubrimiento de servicios SDP. El dispositivo y el servidor deben utilizar el mismo UUID para un determinado servicio.

Estoy utilizando el SPP (protocolo de puerto serie) en mi aplicación. Así que cambio UUID de lo que está en el código de ejemplo de BluetoothChat como "fa87c0d0-afac-11de-8a39-0800200c9a66" a SPP "00001101-0000-1000-8000-00805F9B34FB". Ahora está bien.

Y desactivo el código de escucha de acceptThread en BluetoothChatService.start (). Más conciso ahora. Espero que ayude.

Me pasó a mí en mis pruebas también. I el código de la muestra de BluetoothChat usted debe mirar el método connectionLost. No recuerdo si hay alguna variable que mantiene el número de conexiones perdidas, pero usted podría agregar que usted mismo. En el método connectionLost, compruebe si el número de conexiones perdidas es menor que un número predefinido (en mi caso 3). Si eso es cierto, envíe un mensaje a la interfaz de usuario con mHandler (un brindis) y llame a connect (dispositivo) de nuevo. Si eso no es cierto (has perdido la conexión más de 3 veces), llama al método stop ().

También asegúrese de abrir el socket en ConnectThread de esta manera:

  public ConnectThread(BluetoothDevice device, boolean isSecure) { mmDevice = device; BluetoothSocket tmp = null; mSocketType = isSecure ? "Secure" : "Insecure"; // Get a BluetoothSocket for a connection with the given BluetoothDevice if (isSecure) { // reflection is better to use Method m = null; try { Log.d(TAG, "create reflection"); m = device.getClass().getMethod("createRfcommSocket",new Class[] { int.class }); } catch (NoSuchMethodException e1) { e1.printStackTrace(); } try { tmp = (BluetoothSocket) m.invoke(device, 1); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } mmSocketFallBack = tmp; } else { Log.d(TAG, "create insecure"); try { tmp = device .createInsecureRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { e.printStackTrace(); } } mmSocket = mmSocketFallBack; } 

Tu connectionLost debería ser similar a:

 public void connectionLost() { init = false; Log.d(TAG, "connectionLost -> " + mConnectionLostCount); mConnectionLostCount++; if (mConnectionLostCount < 3) { // Send a reconnect message back to the Activity Message msg = mHandler.obtainMessage(cBluetooth.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(WebAppInterface.TOAST, "Connection lost. Reconnecting..."); msg.setData(bundle); mHandler.sendMessage(msg); connect(mSavedDevice,true); } else { mConnectionLostCount = 0; Message msg = mHandler.obtainMessage(cBluetooth.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(WebAppInterface.TOAST,"Device connection was lost!"); msg.setData(bundle); mHandler.sendMessage(msg); cBluetooth.this.stop(); } } 

Espero que pueda adaptarlo para su caso. Usted podría comprobar estos acoplamientos también, ellos me ayudaron mucho:

  1. Ejemplo de control remoto
  2. Solución moribunda de conexión
  3. Ejemplo de servicio Bluetooth para inspirarte

Tengo la misma experiencia en 4.2.2.

Pero había descubierto que la pila de bluetooth empieza a portarse mal sólo después de que mi aplicación caiga o se mate sin limpiar adecuadamente los recursos (socket y / o arroyos). Antes de que cuando cierre mi aplicación correctamente funciona bien.

Por ejemplo, cuando cierro socket y luego mato la aplicación, puedo iniciarla y volver a conectarme normalmente. Si yo mato mi aplicación sin cerrar previamente el zócalo es condenado y tengo que reiniciar el dispositivo para hacerlo funcionar otra vez.

Así que parece nuevo Android bluetooth pila tiene algunos errores en el mecanismo de limpieza implícita. Cuando una aplicación cae Android debe limpiar los recursos bluetooth abierto que no está sucediendo.

Mi código de gestión bluetooth está en subclase de aplicación. No hay forma – o no puedo ver uno – cómo enganchar en la aplicación destruir y hacer la limpieza.

Cualquier sugerencia apreciada

EDITAR:

He hecho una solución bastante desordenada.

He creado aplicaciones separadas que contienen solo servicio remoto. Moví todo el código de comunicación (socket y corrientes de apertura, lectura, escritura, cierre) en este servicio remoto. A continuación, si la aplicación principal se bloquea o se anula, el servicio sigue funcionando. Cuando vuelvo a iniciar la aplicación, la conexión sigue en pie. Los bytes leídos del flujo de entrada bluetooth se transfieren a la aplicación principal a través de mensajes de servicio estándar. Para mi caso esto está bien ya que transferir cantidades muy pequeñas de datos.

Todavía cuando la aplicación que contiene el servicio es asesinado, el mismo desastre sucede.

Estoy enfrentando el mismo problema. Esto funciona para mí:

 try { Thread.sleep(1000); } catch(Exception e3) { Toast.makeText(getApplicationContext(), "wa ni sud sa thread sleep!", Toast.LENGTH_SHORT).show(); } btSocket.close(); 
  • Android Bluetooth Serial / RFCOMM / SPP, ¿Cómo cambiar el BAUD RATE?
  • Android Bluetooth IOException: conexión rechazada
  • El conector Bluetooth de Android se bloquea
  • ¿Cómo crear un socket Android RFCOMM sin ninguna entrada del usuario?
  • ¿Podría crear más de un canal RFCOMM por hora?
  • Android Bluetooth: El software causó la interrupción de conexión IOException?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.