Excepción fallida de detección de servicios mediante Bluetooth en Android


Actualmente estoy trabajando en una aplicación de Android que se conecta a un instrumento a través de Bluetooth y necesito escribir comandos de cadena y recibir respuestas de cadena de vuelta. Actualmente tengo la conexión / lectura / escritura trabajando para TCP / IP a través de Wi-Fi y ahora tratando de implementar Bluetooth. Pero me estoy topando con algunas barricadas. He estado buscando en la web tratando de encontrar ejemplos de algo similar y no he tenido suerte. He estado usando el ejemplo de recursos para desarrolladores de Android: Bluetooth Chat como mi punto de referencia principal.

Mi código actual parece funcionar.. A continuación, lanza una excepción de error de Detección de servicio en el punto de la conexión. Estoy usando la clase DeviceListActivity para descubrir y seleccionar el dispositivo al que quiero conectarme. Devuelve anActivityResult y luego mi clase Bluetooth espera a que maneje eso y luego hace la conexión a él. El código debajo es casi idéntico a la aplicación de Chat Bluetooth.

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(!m_BluetoothAdapter.isEnabled())
    {
        m_BluetoothAdapter.enable();
    }
    switch (requestCode) {
        case REQUEST_CONNECT_DEVICE:
            // When DeviceListActivity returns with a device to connect
            if (resultCode == Activity.RESULT_OK) {
                // Get the device MAC address
                String address = data.getExtras()
                                     .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
                // Get the BLuetoothDevice object
                BluetoothDevice device = m_BluetoothAdapter.getRemoteDevice(address);
                // Attempt to connect to the device
                connect(device);
            }
            break;

        case REQUEST_ENABLE_BT:
            // When the request to enable Bluetooth returns
            if (resultCode == Activity.RESULT_OK) {
                // Bluetooth is now enabled, so set up a chat session
            }
            else {
                // User did not enable Bluetooth or an error occured

                Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_SHORT).show();
                finish();
            }
    }
}

Esta es mi conexión función:

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

private void connect(BluetoothDevice device) {
    m_Device = device;
    BluetoothSocket tmp = null;

    // Get a BluetoothSocket for a connection with the
    // given BluetoothDevice
    try {
        tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
    }
    catch (IOException e) {

    }
    m_Socket = tmp;

    m_BluetoothAdapter.cancelDiscovery();

    try {
        // This is a blocking call and will only return on a
        // successful connection or an exception
        m_Socket.connect();
    }
    catch (IOException e) {
        try {
            m_Socket.close();
        }
        catch (IOException e2) {
        }
        return;
    }
}

Con suerte, lo que sea que esté haciendo mal es simple, pero me temo que nunca es tan fácil. Esta es mi primera vez haciendo cualquier desarrollo de Bluetooth, y tal vez estoy haciendo algo descaradamente mal... Pero no estoy seguro de por qué obtengo la excepción de error de detección de servicio.

Puede emparejar/encontrar el dispositivo en todo momento manualmente en el teléfono... Requiere un código de acceso, pero no creo que ese sea el problema que estoy teniendo.

Author: Peter Mortensen, 2010-08-03

5 answers

Después de tres días lo descubrí gracias a algunas publicaciones muy útiles.

Tuve que reemplazar:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

Con:

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
         tmp = (BluetoothSocket) m.invoke(device, 1);

Y voilà funciona!

 93
Author: TxAg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-01 15:33:54

A partir de API 15 puede utilizar el siguiente método:

Intente reemplazar su UUID con el valor devuelto de getUuids () método de la clase BluetoothDevice. Lo que funcionó para mí fue algo como esto:

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);

La razón por la que esto funciona es que diferentes dispositivos soportan diferentes UUID y al obtener los UUID del dispositivo usando Getuuid usted está soportando todas las características y dispositivos.

Otro nuevo método interesante (soportado desde API 14) es este: BluetoothHealth.getConnectionState . No lo he intentado, pero parece prometedor...

 13
Author: Muzikant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-13 19:45:30

Esta fue una modificación sugerida por un usuario anónimo que intentaba responder a la respuesta aceptada.

Una gran diferencia entre tu código antes y después es el UUID que estás pasando. Encontré mi respuesta aquí: http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord(java.util.UUID)

Tuve que reemplazar:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

Con:

private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
tmp = device.createRfcommSocketToServiceRecord(SPP_UUID);

Y voila funciona! El código original es para un aplicación para Android peer to peer. No tiene sentido usar la aplicación UUID cuando se conecta a un dispositivo bluetooth serie simple. Por eso falla el descubrimiento.

 2
Author: Rup,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:30:15

Así que como se mencionó anteriormente, el punto es que necesita usar el UUID que el servidor está esperando.

Si se conecta a un dispositivo bluetooth, como un auricular o un ratón, debe verificar qué UUID está escuchando el dispositivo. Puedes ver a los UUID así.

UUID[] uuids = bluetoothDevice.getUuids();

Y si quieres saber qué significan estos UUID, ver esto.

 1
Author: Devgrapher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-10 12:28:38

Esta es una pregunta muy antigua, pero encontré que el uso de la createInsecureRfcommSocketToServiceRecord() en lugar de createRfcommSocketToServiceRecord() junto con el getUuids() mencionado anteriormente hacer el truco para mí

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
 1
Author: animalito maquina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-15 18:34:51