IOException: lectura fallida, socket podría cerrado-Bluetooth en Android 4.3


Actualmente estoy tratando de lidiar con una extraña Excepción al abrir un BluetoothSocket en mi Nexus 7 (2012), con Android 4.3 (Construir JWR66Y, supongo que la segunda actualización 4.3). He visto algunas publicaciones relacionadas (e. g.https://stackoverflow.com/questions/13648373/bluetoothsocket-connect-throwing-exception-read-failed), pero ninguno parece proporcionar una solución para este problema. Además, como se sugiere en estos hilos, re-emparejamiento no ayuda, y constantemente tratando de conectar (a través de un stupid loop) tampoco tiene efecto.

Estoy tratando con un dispositivo integrado (un adaptador de coche OBD-II no nombre, similar a http://images04.olx.com/ui/15/53/76/1316534072_254254776_2-OBD-II-BLUTOOTH-ADAPTERSCLEAR-CHECK-ENGINE-LIGHTS-WITH-YOUR-PHONE-Oceanside.jpg). Mi teléfono Android 2.3.7 no tiene ningún problema de conexión, y el Xperia de un colega (Android 4.1.2) también funciona. Otro Google Nexus (no sé si 'Uno' o 'S', pero no '4') también falla con Android 4.3.

Aquí está el Fragmento del establecimiento de la conexión. Se está ejecutando en su propio Hilo, creado dentro de un Servicio.

private class ConnectThread extends Thread {

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

    private BluetoothAdapter adapter;
    private boolean secure;
    private BluetoothDevice device;
    private List<UUID> uuidCandidates;
    private int candidate;
    protected boolean started;

    public ConnectThread(BluetoothDevice device, boolean secure) {
        logger.info("initiliasing connection to device "+device.getName() +" / "+ device.getAddress());
        adapter = BluetoothAdapter.getDefaultAdapter();
        this.secure = secure;
        this.device = device;

        setName("BluetoothConnectThread");

        if (!startQueryingForUUIDs()) {
            this.uuidCandidates = Collections.singletonList(EMBEDDED_BOARD_SPP);
            this.start();
        } else{
            logger.info("Using UUID discovery mechanism.");
        }
        /*
         * it will start upon the broadcast receive otherwise
         */
    }

    private boolean startQueryingForUUIDs() {
        Class<?> cl = BluetoothDevice.class;

        Class<?>[] par = {};
        Method fetchUuidsWithSdpMethod;
        try {
            fetchUuidsWithSdpMethod = cl.getMethod("fetchUuidsWithSdp", par);
        } catch (NoSuchMethodException e) {
            logger.warn(e.getMessage());
            return false;
        }

        Object[] args = {};
        try {
            BroadcastReceiver receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    BluetoothDevice deviceExtra = intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
                    Parcelable[] uuidExtra = intent.getParcelableArrayExtra("android.bluetooth.device.extra.UUID");

                    uuidCandidates = new ArrayList<UUID>();
                    for (Parcelable uuid : uuidExtra) {
                        uuidCandidates.add(UUID.fromString(uuid.toString()));
                    }

                    synchronized (ConnectThread.this) {
                        if (!ConnectThread.this.started) {
                            ConnectThread.this.start();
                            ConnectThread.this.started = true;
                            unregisterReceiver(this);
                        }

                    }
                }

            };
            registerReceiver(receiver, new IntentFilter("android.bleutooth.device.action.UUID"));
            registerReceiver(receiver, new IntentFilter("android.bluetooth.device.action.UUID"));

            fetchUuidsWithSdpMethod.invoke(device, args);
        } catch (IllegalArgumentException e) {
            logger.warn(e.getMessage());
            return false;
        } catch (IllegalAccessException e) {
            logger.warn(e.getMessage());
            return false;
        } catch (InvocationTargetException e) {
            logger.warn(e.getMessage());
            return false;
        }           

        return true;
    }

    public void run() {
        boolean success = false;
        while (selectSocket()) {

            if (bluetoothSocket == null) {
                logger.warn("Socket is null! Cancelling!");
                deviceDisconnected();
                openTroubleshootingActivity(TroubleshootingActivity.BLUETOOTH_EXCEPTION);
            }

            // Always cancel discovery because it will slow down a connection
            adapter.cancelDiscovery();

            // Make a connection to the BluetoothSocket
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                bluetoothSocket.connect();
                success = true;
                break;

            } catch (IOException e) {
                // Close the socket
                try {
                    shutdownSocket();
                } catch (IOException e2) {
                    logger.warn(e2.getMessage(), e2);
                }
            }
        }

        if (success) {
            deviceConnected();
        } else {
            deviceDisconnected();
            openTroubleshootingActivity(TroubleshootingActivity.BLUETOOTH_EXCEPTION);
        }
    }

    private boolean selectSocket() {
        if (candidate >= uuidCandidates.size()) {
            return false;
        }

        BluetoothSocket tmp;
        UUID uuid = uuidCandidates.get(candidate++);
        logger.info("Attempting to connect to SDP "+ uuid);
        try {
            if (secure) {
                tmp = device.createRfcommSocketToServiceRecord(
                        uuid);
            } else {
                tmp = device.createInsecureRfcommSocketToServiceRecord(
                        uuid);
            }
            bluetoothSocket = tmp;
            return true;
        } catch (IOException e) {
            logger.warn(e.getMessage() ,e);
        }

        return false;
    }

}

El código está fallando en bluetoothSocket.connect(). Estoy recibiendo un java.io.IOException: read failed, socket might closed, read ret: -1. Esta es la fuente correspondiente en GitHub: https://github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetooth/BluetoothSocket.java#L504 Es llamado a través de readInt (), llamado desde https://github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetooth/BluetoothSocket.java#L319

Algunos volcados de metadatos del socket usado dieron como resultado la siguiente información. Estos son exactamente los mismos en Nexus 7 y mi teléfono 2.3.7.

Bluetooth Device 'OBDII'
Address: 11:22:33:DD:EE:FF
Bond state: 12 (bonded)
Type: 1
Class major version: 7936
Class minor version: 7936
Class Contents: 0
Contents: 0

Tengo algunos otros adaptadores OBD-II (más expansivos) y todos funcionan. ¿Hay alguna posibilidad, que me estoy perdiendo algo o podría ser un error en Android?

Author: Community, 2013-09-06

12 answers

Finalmente he encontrado una solución. La magia está escondida bajo el capó de la clase BluetoothDevice (ver https://github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetooth/BluetoothDevice.java#L1037).

Ahora, cuando recibo esa excepción, instancio un recurso alternativo BluetoothSocket, similar al código fuente a continuación. Como puede ver, invocar el método oculto createRfcommSocket a través de reflexiones. No tengo ni idea de por qué este método está oculto. El código fuente lo define como public aunque...

Class<?> clazz = tmp.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};

Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[] {Integer.valueOf(1)};

fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);
fallbackSocket.connect();

connect() entonces no falla más. He experimentado algunos problemas todavía. Básicamente, esto a veces bloquea y falla. Reiniciar el dispositivo SPP (plug off / plug in) ayuda en estos casos. A veces también recibo otra solicitud de emparejamiento después de connect() incluso cuando el dispositivo ya está enlazado.

ACTUALIZACIÓN:

Aquí hay una clase completa, que contiene algunas clases anidadas. para una implementación real, estas podrían celebrarse como clases separadas.

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.List;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

public class BluetoothConnector {

    private BluetoothSocketWrapper bluetoothSocket;
    private BluetoothDevice device;
    private boolean secure;
    private BluetoothAdapter adapter;
    private List<UUID> uuidCandidates;
    private int candidate;


    /**
     * @param device the device
     * @param secure if connection should be done via a secure socket
     * @param adapter the Android BT adapter
     * @param uuidCandidates a list of UUIDs. if null or empty, the Serial PP id is used
     */
    public BluetoothConnector(BluetoothDevice device, boolean secure, BluetoothAdapter adapter,
            List<UUID> uuidCandidates) {
        this.device = device;
        this.secure = secure;
        this.adapter = adapter;
        this.uuidCandidates = uuidCandidates;

        if (this.uuidCandidates == null || this.uuidCandidates.isEmpty()) {
            this.uuidCandidates = new ArrayList<UUID>();
            this.uuidCandidates.add(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
        }
    }

    public BluetoothSocketWrapper connect() throws IOException {
        boolean success = false;
        while (selectSocket()) {
            adapter.cancelDiscovery();

            try {
                bluetoothSocket.connect();
                success = true;
                break;
            } catch (IOException e) {
                //try the fallback
                try {
                    bluetoothSocket = new FallbackBluetoothSocket(bluetoothSocket.getUnderlyingSocket());
                    Thread.sleep(500);                  
                    bluetoothSocket.connect();
                    success = true;
                    break;  
                } catch (FallbackException e1) {
                    Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e);
                } catch (InterruptedException e1) {
                    Log.w("BT", e1.getMessage(), e1);
                } catch (IOException e1) {
                    Log.w("BT", "Fallback failed. Cancelling.", e1);
                }
            }
        }

        if (!success) {
            throw new IOException("Could not connect to device: "+ device.getAddress());
        }

        return bluetoothSocket;
    }

    private boolean selectSocket() throws IOException {
        if (candidate >= uuidCandidates.size()) {
            return false;
        }

        BluetoothSocket tmp;
        UUID uuid = uuidCandidates.get(candidate++);

        Log.i("BT", "Attempting to connect to Protocol: "+ uuid);
        if (secure) {
            tmp = device.createRfcommSocketToServiceRecord(uuid);
        } else {
            tmp = device.createInsecureRfcommSocketToServiceRecord(uuid);
        }
        bluetoothSocket = new NativeBluetoothSocket(tmp);

        return true;
    }

    public static interface BluetoothSocketWrapper {

        InputStream getInputStream() throws IOException;

        OutputStream getOutputStream() throws IOException;

        String getRemoteDeviceName();

        void connect() throws IOException;

        String getRemoteDeviceAddress();

        void close() throws IOException;

        BluetoothSocket getUnderlyingSocket();

    }


    public static class NativeBluetoothSocket implements BluetoothSocketWrapper {

        private BluetoothSocket socket;

        public NativeBluetoothSocket(BluetoothSocket tmp) {
            this.socket = tmp;
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return socket.getInputStream();
        }

        @Override
        public OutputStream getOutputStream() throws IOException {
            return socket.getOutputStream();
        }

        @Override
        public String getRemoteDeviceName() {
            return socket.getRemoteDevice().getName();
        }

        @Override
        public void connect() throws IOException {
            socket.connect();
        }

        @Override
        public String getRemoteDeviceAddress() {
            return socket.getRemoteDevice().getAddress();
        }

        @Override
        public void close() throws IOException {
            socket.close();
        }

        @Override
        public BluetoothSocket getUnderlyingSocket() {
            return socket;
        }

    }

    public class FallbackBluetoothSocket extends NativeBluetoothSocket {

        private BluetoothSocket fallbackSocket;

        public FallbackBluetoothSocket(BluetoothSocket tmp) throws FallbackException {
            super(tmp);
            try
            {
              Class<?> clazz = tmp.getRemoteDevice().getClass();
              Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};
              Method m = clazz.getMethod("createRfcommSocket", paramTypes);
              Object[] params = new Object[] {Integer.valueOf(1)};
              fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);
            }
            catch (Exception e)
            {
                throw new FallbackException(e);
            }
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return fallbackSocket.getInputStream();
        }

        @Override
        public OutputStream getOutputStream() throws IOException {
            return fallbackSocket.getOutputStream();
        }


        @Override
        public void connect() throws IOException {
            fallbackSocket.connect();
        }


        @Override
        public void close() throws IOException {
            fallbackSocket.close();
        }

    }

    public static class FallbackException extends Exception {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        public FallbackException(Exception e) {
            super(e);
        }

    }
}
 115
Author: matthes,
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-12-20 12:47:47

Bueno, tuve el mismo problema con mi código, y es porque desde Android 4.2 pila bluetooth ha cambiado. así que mi código se estaba ejecutando bien en dispositivos con Android "error de lectura, socket podría cerrado o tiempo de espera, leer ret: -1"

El problema es con el parámetro socket.mPort. Cuando crea su socket usando socket = device.createRfcommSocketToServiceRecord(SERIAL_UUID); , el mPort obtiene un valor entero"-1", y este valor parece que no funciona para Android >=4.2 , por lo que tienes que configurarlo en "1". La mala noticia es que createRfcommSocketToServiceRecord solo acepta UUID como parámetro y no mPort por lo que tenemos que usar otro enfoque. La respuesta publicada por @matthes también funcionó para mí, pero la simplifiqué: socket =(BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(device,1);. Necesitamos usar ambos atributos de socket, el segundo como alternativa.

Así que el código es (para conectarse a un SPP en un dispositivo ELM327):

BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();

    if (btAdapter.isEnabled()) {
        SharedPreferences prefs_btdev = getSharedPreferences("btdev", 0);
        String btdevaddr=prefs_btdev.getString("btdevaddr","?");

        if (btdevaddr != "?")
        {
            BluetoothDevice device = btAdapter.getRemoteDevice(btdevaddr);

            UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); // bluetooth serial port service
            //UUID SERIAL_UUID = device.getUuids()[0].getUuid(); //if you don't know the UUID of the bluetooth device service, you can get it like this from android cache

            BluetoothSocket socket = null;

            try {
                socket = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
            } catch (Exception e) {Log.e("","Error creating socket");}

            try {
                socket.connect();
                Log.e("","Connected");
            } catch (IOException e) {
                Log.e("",e.getMessage());
                try {
                    Log.e("","trying fallback...");

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

                    Log.e("","Connected");
                }
             catch (Exception e2) {
                 Log.e("", "Couldn't establish Bluetooth connection!");
              }
            }
        }
        else
        {
            Log.e("","BT device not selected");
        }
    }
 79
Author: George Dima,
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
2014-09-03 14:40:05

Primero, si necesita hablar con un bluetooth 2.x dispositivo, esta documentación establece que:

Sugerencia: Si se está conectando a una placa serie Bluetooth, intente usar el bien conocido SPP UUID 00001101-0000-1000-8000-00805F9B34FB. Obstante si se está conectando a un par de Android, por favor genere su propio UUID único.

No pensé que funcionaría, pero solo reemplazando el UUID con 00001101-0000-1000-8000-00805F9B34FB funciona. Sin embargo, este código parece maneje el problema de la versión del SDK, y solo puede reemplazar la función device.createRfcommSocketToServiceRecord(mMyUuid); con tmp = createBluetoothSocket(mmDevice); después de definir el siguiente método :

private BluetoothSocket createBluetoothSocket(BluetoothDevice device)
    throws IOException {
    if(Build.VERSION.SDK_INT >= 10){
        try {
            final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
            return (BluetoothSocket) m.invoke(device, mMyUuid);
        } catch (Exception e) {
            Log.e(TAG, "Could not create Insecure RFComm Connection",e);
        }
    }
    return  device.createRfcommSocketToServiceRecord(mMyUuid);
}

El código fuente no es mío, sino que proviene de este sitio web.

 9
Author: tobiasBora,
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-01-13 03:55:58

Usted puso registerReceiver(receiver, new IntentFilter("android.bleutooth.device.action.UUID")); con " bluetooth "escrito"bleutooth".

 6
Author: Fizz Binn,
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-04-24 19:12:27

Bueno, en realidad he encontrado el problema.

La mayoría de las personas que intentan hacer una conexión usando socket.Connect(); obtienen una excepción llamada Java.IO.IOException: read failed, socket might closed, read ret: -1.

En algunos casos también depende de su dispositivo Bluetooth, porque hay dos tipos diferentes de Bluetooth, a saber, BLE (low energy) y Classic.

Si desea comprobar el tipo de su dispositivo Bluetooth es, aquí está el código:

        String checkType;
        var listDevices = BluetoothAdapter.BondedDevices;
        if (listDevices.Count > 0)
        {
            foreach (var btDevice in listDevices)
            {
                if(btDevice.Name == "MOCUTE-032_B52-CA7E")
                {
                    checkType = btDevice.Type.ToString();
                    Console.WriteLine(checkType);
                }
            }
        }

He estado tratando durante días de resolver el problema, pero desde hoy he encontrado el problema. Desafortunadamente, la solución de @matthes todavía tiene algunos problemas, como ya dijo, pero aquí está mi solución.

Por el momento trabajo en Xamarin Android, pero esto también debería funcionar para otras plataformas.

SOLUCIÓN

Si hay más de un dispositivo emparejado, debe eliminar los otros dispositivos emparejados. Por lo tanto, mantenga solo el que desea conectar (vea la imagen correcta).

introduzca la descripción de la imagen aquí introduzca la descripción de la imagen aquí

En la imagen de la izquierda se ve que tengo dos dispositivos emparejados, a saber "MOCUTE-032_B52-CA7E"y" Blue Easy". Ese es el problema, pero no tengo idea de por qué ocurre ese problema. Tal vez el protocolo Bluetooth está tratando de obtener información de otro dispositivo Bluetooth.

Sin embargo, el socket.Connect(); funciona muy bien en este momento, sin ningún problema. Así que solo quería compartir esto, porque ese error es realmente molesto.

¡Buena suerte!

 6
Author: Jamie,
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
2016-06-02 17:10:15

Tuve los mismos síntomas descritos aquí. Pude conectarme una vez a una impresora bluetooth, pero las conexiones posteriores fallaron con "socket closed", sin importar lo que hiciera.

Me pareció un poco extraño que las soluciones descritas aquí fueran necesarias. Después de pasar por mi código me encontré con que me había olvidado de cerrar el socket InputStream y OutputSteram y no terminó el ConnectedThreads correctamente.

El ConnectedThread que uso es el mismo que en el ejemplo aquí:

Http://developer.android.com/guide/topics/connectivity/bluetooth.html

Tenga en cuenta que ConnectThread y ConnectedThread son dos clases diferentes.

Cualquier clase que inicie ConnectedThread debe llamar a interrupt() y cancel() en el hilo. He añadido mmInStream.close () y mmOutStream.close () en ConnectedTread.método cancel ().

Después de cerrar los threads/streams/sockets correctamente pude crear nuevos sockets sin ningún problema.

 5
Author: Daniel T,
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
2014-12-21 17:15:13

En las versiones más recientes de Android, estaba recibiendo este error porque el adaptador todavía estaba descubriendo cuando intenté conectarme al socket. A pesar de que llamé al método cancelDiscovery en el adaptador Bluetooth, tuve que esperar hasta que la devolución de llamada al método onReceive() de BroadcastReceiver fue llamada con la acción BluetoothAdapter.ACTION_DISCOVERY_FINISHED.

Una vez que esperé a que el adaptador detuviera el descubrimiento, entonces la llamada connect en el socket tuvo éxito.

 4
Author: kmac.mcfarlane,
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
2016-12-19 20:10:46

En caso de que alguien tenga problemas con Kotlin, tuve que seguir la respuesta aceptada con algunas variaciones:

fun print(view: View, text: String) {
    var adapter = BluetoothAdapter.getDefaultAdapter();
    var pairedDevices = adapter.getBondedDevices()
    var uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
    if (pairedDevices.size > 0) {
        for (device in pairedDevices) {
            var s = device.name
            if (device.getName().equals(printerName, ignoreCase = true)) {
                Thread {
                    var socket = device.createInsecureRfcommSocketToServiceRecord(uuid)
                    var clazz = socket.remoteDevice.javaClass
                    var paramTypes = arrayOf<Class<*>>(Integer.TYPE)
                    var m = clazz.getMethod("createRfcommSocket", *paramTypes)
                    var fallbackSocket = m.invoke(socket.remoteDevice, Integer.valueOf(1)) as BluetoothSocket
                    try {
                        fallbackSocket.connect()
                        var stream = fallbackSocket.outputStream
                        stream.write(text.toByteArray(Charset.forName("UTF-8")))
                    } catch (e: Exception) {
                        e.printStackTrace()
                        Snackbar.make(view, "An error occurred", Snackbar.LENGTH_SHORT).show()
                    }
                }.start()
            }
        }
    }
}

Espero que ayude

 2
Author: Santiago Martí Olbrich,
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
2018-03-14 18:23:10

También me enfrenté a este problema, podría resolverlo de 2 maneras, como se mencionó anteriormente use reflexión para crear el socket El segundo es, el cliente está buscando un servidor con un UUID dado y si su servidor no se está ejecutando en paralelo al cliente, esto sucede. Cree un servidor con un UUID de cliente dado y luego escuche y acepte el cliente desde el servidor side.It funcionará.

 1
Author: ireshika piyumalie,
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
2016-06-24 09:55:42

Los dispositivos Bluetooth pueden funcionar tanto en modo clásico como en modo LE al mismo tiempo. A veces usan una dirección MAC diferente dependiendo de la forma en que se conecte. Llamar a socket.connect() está usando Bluetooth Classic, por lo que debe asegurarse de que el dispositivo que recibió cuando escaneó era realmente un dispositivo clásico.

Es fácil filtrar solo para dispositivos clásicos, sin embargo:

if(BluetoothDevice.DEVICE_TYPE_LE == device.getType()){ //socket.connect() }

Sin esta comprobación, es una condición de carrera en cuanto a si un escaneo híbrido le dará el dispositivo Clásico o el dispositivo BLE primero. Puede aparecer como incapacidad intermitente para conectarse,o como ciertos dispositivos que pueden conectarse de manera confiable mientras que otros aparentemente nunca pueden.

 1
Author: kmac.mcfarlane,
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-11-17 16:37:33

Incluso tuve el mismo problema ,finalmente entender mi problema , estaba tratando de conectar desde (fuera de rango) rango de cobertura Bluetooth.

 0
Author: krishna murthy,
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
2018-06-21 09:32:31

También he recibido el mismo IOException, pero me parece que la demostración del sistema Android: "BluetoothChat" proyecto está funcionando. Determiné que el problema es el UUID.

Así que reemplazo mi UUID.fromString("00001001-0000-1000-8000-00805F9B34FB") a UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66") y funcionó la mayoría de la escena, solo a veces necesito reiniciar el dispositivo Bluetooth;

 -3
Author: taotao,
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
2014-08-11 14:59:30