"Error de detección de servicio" en Android Bluetooth Insecure Rfcomm

¿Alguien sabe cómo crear una conexión RFCOMM insegura entre 2 dispositivos Android en el nivel API 2.3.3 mientras se utiliza un nombre de servicio declarado arbitrariamente? (No el nombre de servicio al azar o cambiar, sólo un nombre de servicio que me defino)

Detalles

Estoy tratando de crear una conexión insegura Rfcomm entre 2 dispositivos Android: Droid X2 y un transformador de Asus. Estoy asumiendo que ambos dispositivos tienen funcionalidad a nivel de Android 2.3.3 para ganar la capacidad de usar Rfcomm inseguro.

Cuando intento crear la conexión de Bluetooth según lo descrito aquí , usando el ahora público createInsecureRfcommSocketToServiceRecord () y listenUsingInsecureRfcommWithServiceRecord (SERVICE, UUID), consigo un informado:

java.io.IOException: Service discovery failed at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:377) at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:201) at com.s4d.bluenomad.DeviceConnections$ClientThread.run(DeviceConnections.java:406) 

Encontré una pregunta relacionada donde alguien que creaba una conexión normal estaba recibiendo este error y usaba la reflexión para invocar un método privado. Sin embargo, no tengo idea de qué método privado correspondería ahora a iniciar una conexión "insegura". Intenté usar la solución propuesta en esa pregunta relacionada, pero me pide Android para emparejar los dispositivos que es exactamente lo que necesito evitar. Realmente necesito el enfoque inseguro.

Incluso probé una combinación de las soluciones oficiales y hackeadas aquí resumidas

Snippets de código relevantes

Creación de ServerThread para escuchar conexiones

 Log.i(TAG, "Constructing a ServerThread"); // Use a temporary object that is later assigned to serverSocket, // because serverSocket is final BluetoothServerSocket tmp = null; try { // MY_UUID is the app's UUID string, also used by the client code tmp = btAdapter.listenUsingInsecureRfcommWithServiceRecord(SERVICE_NAME, SERVICE_UUID); Log.i(TAG,"Started listening on insecure RFCOMM channel for service requests for: " + SERVICE_NAME); } catch (IOException e) { } serverSocket = tmp; 

ServerThread Escuchar conexiones

 BluetoothSocket socket; while(true) { try { socket = serverSocket.accept(); } catch( IOException e) { break; } if( socket != null ) { Log.i(TAG, "Received new socket connection requesting service: " + SERVICE_NAME); } else { Log.i(TAG, "Socket connection attempted, but socket received is NULL."); } } 

Creación de ClientThread para iniciar conexiones

 Log.i(TAG, "Constructing a ClientThread"); BluetoothSocket tmp = null; try { // MY_UUID is the app's UUID string, also used by the server code tmp = device.createInsecureRfcommSocketToServiceRecord(SERVICE_UUID); Log.i(TAG,"Created client socket on insecure RFCOMM channel for service requests for: " + SERVICE_NAME); } catch (IOException e) { Log.i(TAG, "Failed to createInsecureRfcommSocket() against MAC: " + device.getAddress()); } clientSocket = tmp; 

ClientThread Conexión al servidor

 try { clientSocket.connect(); } catch( final IOException e) { DeviceConnections.this.runOnUiThread(new Runnable() { @Override public void run() { console.append("Client unable to connect to service."); Log.i(TAG, "Client socket unable to connect() to: " + clientSocket.getRemoteDevice().getAddress()); e.printStackTrace(); } }); } 

Consigo la salida de registro "socket del cliente incapaz de conectar () a: [MY_MAC_ADDRESS]", entonces consigo el stacktrace para la excepción del "descubrimiento del servicio fallado".

Parece que el problema era que antes de llamar

 clientSocket.connect() 

Necesitaba llamar

 btAdapter.cancelDiscovery() 

Había visto esto en la documentación, pero se enumeró como un "rendimiento" cuestión – en mi caso, parece que esto era realmente un "funcional" cuestión. Una vez que agregué la llamada de la cancelación del descubrimiento, la conexión del zócalo trabajó inmediatamente.

Algunas cosas para comprobar

  • Utilizando el mismo y único UUID tanto en el cliente como en el servidor.
  • Tenga el permiso de BLUETOOTH
  • Pruebe con el estándar bien conocido SPP UUID 00001101-0000-1000-8000-00805F9B34FB

También le ayudará si puede pegar los registros completos en los códigos de error de API de impresión del lado del cliente y del servidor, si los hay.

"Error de detección de servicio" simplemente significa que nuestro dispositivo no puede encontrar servicio con el mismo UUID en ningún otro dispositivo.

El segundo dispositivo no ha llamado el método "listenUsingInsecureRfcommWithServiceRecord", antes de intentar llamar a "createInsecureRfcommSocketToServiceRecord" desde el primer dispositivo.

Asegúrese de que este código se ha ejecutado en el segundo dispositivo (como onResume () o un botón / optionsItem haga clic) antes de intentar conectarse desde el primer dispositivo.

  if ((mChatService != null) && (mBluetoothAdapter.isEnabled())) { // Only if the state is STATE_NONE, do we know that we haven't started already if (mChatService.getState() == BluetoothChatService.STATE_NONE) { // Start the Bluetooth chat services mChatService.start(); } } 

Debe cambiar 8ce255c0-200a-11e0-ac64-0800200c9a66 a cualquier otro UUID y puede utilizar su nombre de servicio porque 8ce255c0-200a-11e0-ac64-0800200c9a66 se utiliza para servicio predefinido BluetoothChatInsecure

Android La implementación de Bluetooth es dolorosa, ya que puede variar según los dispositivos.

Yo estaba experimentando el mismo problema. En mi caso específico, el error se produjo cuando al menos uno de los dispositivos BluetoothAdapter.getScanMode() se estableció en BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE (es decir, el dispositivo es detectable y se puede conectar desde dispositivos Bluetooth remotos).

Eso es curioso porque el dispositivo debe ser conectable, pero no lo fue.

Si el dispositivo getScanMode() == SCAN_MODE_CONNECTABLE , entonces no se produce ningún error.

Por ahora la solución que encontré es mostrar una advertencia al usuario, por lo que sólo se conectan a dispositivos emparejados. Si los dispositivos no están emparejados, el usuario debe utilizar la configuración de Android y hacer el trabajo.

La activación de la comunicación Bluetooth sólo para los dispositivos emparejados elimina la necesidad de ser detectable y, a continuación, evitar el "Error de detección de servicio".

Una vez más, es mi caso específico en mi dispositivo específico. Esto puede no ser una regla general, pero espero que esto ayude a cualquiera que esté recibiendo el mismo error.

  • Hacer un teléfono Android para posar como un dispositivo de entrada Bluetooth (ratón o teclado)
  • Android Wear, se conecta al dispositivo bluetooth
  • Android 4.4.2 anclaje inverso en MacBook Air vía Bluetooth PAN - no se conecta a Internet
  • Controladores de Samsung Galaxy bluetooth
  • Error de conexión Bluetooth de Android
  • Android BluetoothSocket.isConnected siempre devuelve false
  • Transferencia de archivos entre Android y iPhone a través de bluetooth?
  • "El recurso compartido Bluetooth ha dejado de funcionar" al realizar LeScan
  • ¿Cómo puedo volver a conectar mi aplicación en cada apertura al mismo dispositivo bluetooth de baja energía?
  • Comunicarse con Android dispositivo bluetooth a través de NodeJS y Termux
  • Adaptación de Bluetooth Bluetooth Chat para varios dispositivos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.