"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.
- Error al leer datos de InputStream en Bluetooth en Android
- ¿Cómo conectarse con un dispositivo Bluetooth pareado programático en Android?
- Android: Conexión e impresión a Bixolon SPP-R200
- Android: ¿Cómo averiguar el nombre del dispositivo bluetooth conectado?
- Reacción a la publicidad dirigida BLE (ADV_DIRECT_IND) en Android
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".
- Cómo enviar valores hexadecimales a través de Bluetooth en Android
- Lea desde InputStream usando lectura contra IOUtils.copy
- Cómo parear mediante programación un dispositivo bluetooth en Android
- ¿Puedes establecer múltiples conexiones Bluetooth entre los mismos dos dispositivos de Android?
- ¿Cómo unpair o suprimir el dispositivo bluetooth apareado programmatically en androide?
- La conexión BluetoothSocket de Android devuelve cero
- android sensortag azimut para la brújula no está funcionando (código java)
- ¿Es posible conectar el dispositivo Android Wear con otro dispositivo BLE directamente sin interacción del dispositivo telefónico?
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.
- Android define la forma XML como dibujable mediante programación
- ¿Necesita ayuda para descargar imágenes de fondo en Android?