Android BLE错误java.io.IOException:读取失败,socket可能关闭或超时,读取ret:-1

时间:2017-11-24 19:35:36

标签: android bluetooth-lowenergy

我正在尝试与JDY-10(JDY-10-V2.1)和android(Samsung SM-G920K,Android 7.0,API24)进行通信。

我从来没有能够配对它,因为每当我尝试在默认设置窗口中与JDY-10配对时,"无法与JDY-10"进行通信。吐司出现了。

但它在JDY-10和Android之间在其他聊天应用程序中进行了很好的沟通。

因为我无法与JDY-10配对,所以我尝试将其连接为不安全。

这里是错误日志和代码。

代码来自" https://github.com/arissa34/Android-Multi-Bluetooth-Library Android"这里。

Android错误日志

com.ramimartin.sample.multibluetooth E/BT: Fallback failed. Cancelling.

java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:907)
at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:866)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:540)
at com.ramimartin.multibluetooth.bluetooth.client.BluetoothConnector$FallbackBluetoothSocket.connect(BluetoothConnector.java:220)
at com.ramimartin.multibluetooth.bluetooth.client.BluetoothConnector.connect(BluetoothConnector.java:60)
at com.ramimartin.multibluetooth.bluetooth.client.BluetoothClient.waitForConnection(BluetoothClient.java:47)
at com.ramimartin.multibluetooth.bluetooth.BluetoothRunnable.run(BluetoothRunnable.java:60)
at java.lang.Thread.run(Thread.java:762)                                                                  
===> mSocket IOException : ===> Could not connect to device: A4:C1:38:77:27:E5

 com.ramimartin.sample.multibluetooth W/System.err: java.io.IOException: ===> Could not connect to device: A4:C1:38:77:27:E5
com.ramimartin.sample.multibluetooth W/System.err: at com.ramimartin.multibluetooth.bluetooth.client.BluetoothConnector.connect(BluetoothConnector.java:75)
com.ramimartin.sample.multibluetooth W/System.err:     
at com.ramimartin.multibluetooth.bluetooth.client.BluetoothClient.waitForConnection(BluetoothClient.java:47)
com.ramimartin.sample.multibluetooth W/System.err:     
at com.ramimartin.multibluetooth.bluetooth.BluetoothRunnable.run(BluetoothRunnable.java:60)
com.ramimartin.sample.multibluetooth W/System.err: at java.lang.Thread.run(Thread.java:762)
com.ramimartin.sample.multibluetooth E/BT: ===> Attempting to connect to Protocol: f520cf2c-6487-1

BluetoothConnector.java

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 uuid a list of UUIDs. if null or empty, the Serial PP id is used
 */
public BluetoothConnector(BluetoothDevice device, boolean secure, BluetoothAdapter adapter,
                          UUID uuid) {
    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"));
        this.uuidCandidates.add(UUID.fromString("00000000-0000-1000-8000-00805F9B34FB"));
        this.uuidCandidates.add(UUID.fromString("00000001-0000-1000-8000-00805F9B34FB"));
        this.uuidCandidates.add(UUID.fromString("00000002-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.createInsecureRfcommSocketToServiceRecord(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);
    }

}

BluetoothClient.java

public class BluetoothClient extends BluetoothRunnable {

private static final String TAG = BluetoothClient.class.getSimpleName();

private UUID mUUID;
private BluetoothDevice mBluetoothDevice;
private BluetoothConnector mBluetoothConnector;

private boolean KEEP_TRYING_CONNEXION;

public BluetoothClient(BluetoothAdapter bluetoothAdapter, String uuiDappIdentifier, String adressMacServer, Activity activity, BluetoothManager.MessageMode messageMode) {
    super(bluetoothAdapter, uuiDappIdentifier, activity, messageMode);
    mServerAddress = adressMacServer;
    mUUID = UUID.fromString(uuiDappIdentifier + "-" + mMyAdressMac.replace(":", ""));
    KEEP_TRYING_CONNEXION = true;
}

@Override
public void waitForConnection() {

    mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(mServerAddress);

    while (mInputStream == null && CONTINUE_READ_WRITE && KEEP_TRYING_CONNEXION) {
        mBluetoothConnector = new BluetoothConnector(mBluetoothDevice, false, mBluetoothAdapter, mUUID);

        try {
            mSocket = mBluetoothConnector.connect().getUnderlyingSocket();
            mInputStream = mSocket.getInputStream();
        } catch (IOException e1) {
            Log.e("", "===> mSocket IOException : "+ e1.getMessage());
            //EventBus.getDefault().post(new ClientConnectionFail(mServerAddress));
            e1.printStackTrace();
        }
    }

    if (mSocket == null) {
        Log.e("", "===> mSocket IS NULL");
        return;
    }
}

@Override
public void intiObjReader() throws IOException {
}

@Override
public void onConnectionSucess() {
    EventBus.getDefault().post(new ClientConnectionSuccess());
}

@Override
public void onConnectionFail() {
    EventBus.getDefault().post(new ClientConnectionFail(mServerAddress));
}

@Override
public void closeConnection() {
    KEEP_TRYING_CONNEXION = false;
    super.closeConnection();
  }
}

BluetoothRunnable.java

公共抽象类BluetoothRunnable实现了Runnable {

private static final String TAG = BluetoothRunnable.class.getSimpleName();

public boolean CONTINUE_READ_WRITE = true;

public String mUuiDappIdentifier;
public BluetoothAdapter mBluetoothAdapter;
public BluetoothSocket mSocket;
public InputStream mInputStream;
public String mClientAddress;
public String mServerAddress;
public String mMyAdressMac;
private OutputStreamWriter mOutputStreamWriter;
private ObjectOutputStream mObjectOutputStream;
private ObjectInputStream mObjectInputStream;
private BluetoothManager.MessageMode mMessageMode;
private int mCountObjectInputStreamExection;
private boolean mIsConnected;

public BluetoothRunnable(BluetoothAdapter bluetoothAdapter, String uuiDappIdentifier, Activity activity, BluetoothManager.MessageMode messageMode) {
    mBluetoothAdapter = bluetoothAdapter;
    mUuiDappIdentifier = uuiDappIdentifier;
    mMessageMode = messageMode;
    mMyAdressMac = bluetoothAdapter.getAddress();
    if (mMyAdressMac.equals("02:00:00:00:00:00")) {
        mMyAdressMac = android.provider.Settings.Secure.getString(activity.getContentResolver(), "bluetooth_address");
    }
    mIsConnected = false;
    mCountObjectInputStreamExection = 0;
}

@Override
public void run() {

    waitForConnection();

    try {

        intiObjReader();

        mIsConnected = true;
        int bufferSize = 1024;
        int bytesRead = -1;
        byte[] buffer = new byte[bufferSize];

        if(mSocket == null) return;
        mOutputStreamWriter = new OutputStreamWriter(mSocket.getOutputStream());
        if(mSocket == null) return;
        mObjectOutputStream = new ObjectOutputStream(mSocket.getOutputStream());

        mOutputStreamWriter.flush();
        mObjectOutputStream.reset();

        onConnectionSucess();

        // I DONT KNOW WHY BUT ALWAYS THE FIRST MESSAGE SENT HAS UNWANTED CHARACTERS OR CHARACTERS MISSING
        // SO FOR CLEANING IT I SEND MESSAGE ON THE CONNECTION
        writeString("Connected");

        while (CONTINUE_READ_WRITE) {

            synchronized (this) {

                switch (mMessageMode){

                    case Serialized:

                        try {
                            if(mInputStream == null) return;
                            mObjectInputStream = new ObjectInputStream(mInputStream);
                            Object messageObj = mObjectInputStream.readUnshared();    // read from the object stream,
                            EventBus.getDefault().post(new BluetoothCommunicatorObject(messageObj));
                            if(mInputStream == null) return;
                            bytesRead = mInputStream.read(buffer);
                            if (bytesRead != -1) {
                                while ((bytesRead == bufferSize) && (buffer[bufferSize] != 0)) {
                                    bytesRead = mInputStream.read(buffer);
                                }
                            }
                        } catch (ClassNotFoundException e) {
                            Log.e(TAG, "===> Error Received ObjectInputStream ClassNotFoundException : " + e.getLocalizedMessage());
                        } catch (IOException e) {
                            Log.e(TAG, "===> Error Received ObjectInputStream IOException : " + e.getMessage());
                            lifeline();
                            if(mIsConnected && null != e.getMessage() && e.getMessage().contains("bt socket closed") && mIsConnected){
                                onConnectionFail();
                                mIsConnected = false;
                            }
                        }

                        break;

                    case String:

                        try {
                            final StringBuilder sb = new StringBuilder();
                            if(mInputStream == null) return;
                            bytesRead = mInputStream.read(buffer);
                            if (bytesRead != -1) {
                                String result = "";
                                while ((bytesRead == bufferSize) && (buffer[bufferSize] != 0)) {
                                    result = result + new String(buffer, 0, bytesRead);
                                    if(mInputStream == null) return;
                                    bytesRead = mInputStream.read(buffer);
                                }
                                result = result + new String(buffer, 0, bytesRead);
                                sb.append(result);
                            }
                            EventBus.getDefault().post(new BluetoothCommunicatorString(sb.toString()));
                        } catch (IOException e) {
                            Log.e(TAG, "===> Error Received String IOException : " + e.getMessage());
                        }

                        break;

                    case Bytes:
                        try {
                            if(mInputStream == null) return;
                            bytesRead = mInputStream.read(buffer);
                            ByteBuffer bbuf = ByteBuffer.allocate(bytesRead);
                            if (bytesRead != -1) {
                                while ((bytesRead == bufferSize) && (buffer[bufferSize] != 0)) {
                                    bbuf.put(buffer, 0, bytesRead);
                                    if(mInputStream == null) return;
                                    bytesRead = mInputStream.read(buffer);
                                }
                                bbuf.put(buffer, 0, bytesRead);
                            }
                            EventBus.getDefault().post(new BluetoothCommunicatorBytes(bbuf.array()));
                        } catch (IOException e) {
                            Log.e(TAG, "===> Error Received Bytes IOException  : " + e.getMessage());
                        }

                        break;
                }

            }
        }

    } catch (IOException e) {
        Log.e("", "===> ERROR thread bluetooth : " + e.getMessage());
        e.printStackTrace();
        if (mIsConnected) {
            onConnectionFail();
        }
        mIsConnected = false;
    }
}

public void lifeline(){
    mCountObjectInputStreamExection++;
    if(mCountObjectInputStreamExection>100){
        CONTINUE_READ_WRITE = false;
        this.closeConnection();
    }
}

public abstract void waitForConnection();

public abstract void intiObjReader() throws IOException;

public abstract void onConnectionSucess();

public abstract void onConnectionFail();

public void writeString(String message) {
    try {
        if (mOutputStreamWriter != null) {
            mOutputStreamWriter.write(message);
            mOutputStreamWriter.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void writeBytes(byte[] message) {
    try {
        if (mSocket != null) {
            mSocket.getOutputStream().write(message);
            mSocket.getOutputStream().flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void writeSerialized(Object obj) {
    try {
        if (mObjectOutputStream != null) {
            mObjectOutputStream = new ObjectOutputStream(mSocket.getOutputStream());
            mObjectOutputStream.writeUnshared(obj);
            mObjectOutputStream.reset();
        }
    } catch (Exception e) {
        Log.e(TAG, "Error ObjectOutputStream: " + e.getMessage());
    }
}

public String getClientAddress() {
    return mClientAddress;
}

public void closeConnection() {
    if (mSocket != null) {
        try {
            CONTINUE_READ_WRITE = false;
            mInputStream.close();
            mInputStream = null;
            mOutputStreamWriter.close();
            mOutputStreamWriter = null;
            mObjectOutputStream.close();
            mObjectOutputStream = null;
            mObjectInputStream.close();
            mObjectInputStream = null;
            mSocket.close();
            mSocket = null;
            mIsConnected = false;
        } catch (Exception e) {
            Log.e("", "===+++> closeConnection Exception e : "+e.getMessage());
        }
    }
}

public boolean isConnected() {
    return mIsConnected;
  }
}

0 个答案:

没有答案