Подтвердить что ты не робот

Проблема с подключением Bluetooth для Android

Я пытаюсь настроить соединение Bluetooth следующим образом:

    private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;
    BluetoothSocket connection = null;

    public ConnectThread(BluetoothDevice device) {
        mmDevice = device;
        // Get a BluetoothSocket for a connection with the
        // given BluetoothDevice            
        try {


            if(D) Log.i(TAG, "createRfcommSocket");
            Method m = mmDevice.getClass().getMethod("createRfcommSocket",new Class[] { int.class });
            connection = (BluetoothSocket) m.invoke(mmDevice, 1);

            Utils.pause(100);
        } catch (Exception e) {
            Log.e(TAG, "create() failed", e);
        }
        if(D) Log.i(TAG,"Bluetooth socket initialised");
        mmSocket = connection;
    }

    public void run() {
        if(D) Log.i(TAG, "BEGIN mConnectThread on Device : " + mmDevice);
        setName("ConnectThread");

        if (mmSocket != null) {
            // Always cancel discovery because it will slow down a connection
            if(mAdapter.isDiscovering()) {
                if(D) Log.i(TAG, "stop discovering before trying to connect");
                mAdapter.cancelDiscovery();
            }

            // Make a connection to the BluetoothSocket
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                if(D) Log.i(TAG, "start Bluetooth socket connection");
                mmSocket.connect();
                if(D) Log.i(TAG, "end of Bluetooth socket connection");
            } catch (Exception e1) {
                Log.e(TAG, "connect failed", e1);
                connectionFailed();
                // Reset the socket
                resetConnection(mmSocket);
                // Start the service over to restart listening mode
                if(D) Log.i(TAG, "restart connection");
                BluetoothConnectionService.this.start();
                if(D) Log.i(TAG, "return");
                return;
            }

            // Start the connected thread
            if(D) Log.i(TAG, "The device is considered as connected, call connected thread");
            connected(mmSocket, mmDevice);
        } else {
            if(D) Log.i(TAG, "connection fail");
            connectionFailed();
            BluetoothConnectionService.this.start();
        }
    }

    public void cancel() {
        if(D) Log.i(TAG,"connect thread cancel");
        resetConnection(mmSocket);
    }
}

Соединение кажется ОК, я получаю этот журнал:

DEBUG/BluetoothConnectionService(3439): **connect to: 00:18:E4:21:8B:5E**
INFO/BluetoothConnectionService(3439): createRfcommSocket
INFO/BluetoothConnectionService(3439): Bluetooth socket initialised
INFO/BluetoothConnectionService(3439): BEGIN mConnectThread on Device : 00:18:E4:21:8B:5E
INFO/BluetoothConnectionService(3439): **start Bluetooth socket connection**
INFO/BluetoothConnectionService(3439): setState() 1 -> 2
INFO/ProtectionService(3439): MESSAGE_STATE_CHANGE: 1
DEBUG/ProtectionService(3439): STATE_CHANGED to STATE_LISTEN
INFO/ProtectionService(3439): MESSAGE_STATE_CHANGE: 2
DEBUG/abtfilt(2772): **Conn complete**
INFO/bluetoothd(2776): link_key_request (sba=24:21:AB:F4:69:25, dba=00:18:E4:21:8B:5E)
INFO/bluetoothd(2776): link_key_request (sba=24:21:AB:F4:69:25, dba=00:18:E4:21:8B:5E)
INFO/BluetoothConnectionService(3439): **end of Bluetooth socket connection**
INFO/BluetoothConnectionService(3439): **The device is considered as connected, call connected thread**

Возврат BluetoothSocket.connect() без ошибок.

Затем я управляю соединением с этим:

    private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        if(D) Log.d(TAG, "create ConnectedThread");
        mmSocket = socket;

        // Get the BluetoothSocket input and output streams
        try {
            if(D) Log.i(TAG, "Get input stream");
            tmpIn = socket.getInputStream();
            if(D) Log.i(TAG, "Get output stream");
            tmpOut = socket.getOutputStream();
            if(D) Log.i(TAG, "isConnected = true");
            isConnected = true;
        } catch (IOException e) {
            Log.e(TAG, "Input and Output sockets not created", e);
            isConnected = false;
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        if(D) Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[1024]; //buffer store for the stream
        int bytes; //bytes returned from read()

        // Keep listening to the InputStream until an exception occurs
        while(true) {
            try {
                // Read from the InputStream
                if(D) Log.i(TAG, "start read mmInStream");
                bytes = mmInStream.read(buffer);
                if(D) Log.i(TAG, "Bytes read : "+bytes);

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "ConnectedThread : disconnected", e);
                break;
            }
        }
    }

    /**
     * Write to the connected OutStream.
     * 
     * @param buffer
     *            The bytes to write
     */
    public void write(byte[] buffer) {
        try {
            mmOutStream.write(buffer);

            // Share the sent message back to the UI Activity
            mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
            // mmOutStream.flush();
        } catch (IOException e) {
            Log.e(TAG, "Exception during write", e);
            connectionFailed();
        }
    }

    public void cancel() {
        if(D) Log.i(TAG,"connected Thread cancel");
        resetConnection(mmSocket);

    }
}

И я получаю эту ошибку:

DEBUG/BluetoothConnectionService(3439): create ConnectedThread
INFO/BluetoothConnectionService(3439): Get input stream
INFO/BluetoothConnectionService(3439): Get output stream
INFO/BluetoothConnectionService(3439): isConnected = true
INFO/BluetoothConnectionService(3439): BEGIN mConnectedThread
INFO/BluetoothConnectionService(3439): start read mmInStream
INFO/BluetoothConnectionService(3439): setState() 2 -> 3
INFO/ProtectionService(3439): MESSAGE_STATE_CHANGE: 3
DEBUG/ProtectionService(3439): connectionEstablished
**ERROR/BluetoothConnectionService(3439): ConnectedThread : disconnected
ERROR/BluetoothConnectionService(3439): java.io.IOException: Software caused connection abort
ERROR/BluetoothConnectionService(3439):     at android.bluetooth.BluetoothSocket.readNative(Native Method)
ERROR/BluetoothConnectionService(3439):     at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:307)
ERROR/BluetoothConnectionService(3439):     at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)
ERROR/BluetoothConnectionService(3439):     at java.io.InputStream.read(InputStream.java:133)**
INFO/ProtectionService(3439): Send Bluetooth message
**ERROR/BluetoothConnectionService(3439): Exception during write
ERROR/BluetoothConnectionService(3439): java.io.IOException: Transport endpoint is not connected
ERROR/BluetoothConnectionService(3439):     at android.bluetooth.BluetoothSocket.writeNative(Native Method)
ERROR/BluetoothConnectionService(3439):     at android.bluetooth.BluetoothSocket.write(BluetoothSocket.java:317)**

Ошибка возникает, когда я делаю это:

bytes = mmInStream.read(buffer);

Что я делаю неправильно? Я работаю над этой ошибкой в ​​течение недели, и я не могу пройти...

Любая помощь будет очень оценена!

4b9b3361

Ответ 1

У меня была очень похожая проблема несколько дней назад...

Попробуйте добавить эту проверку в свой код:

if(mmInStream.available() > 0){
   bytes = mmInStream.read(buffer);
   mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
}

Это устранило мою проблему...

Удачи;)

Ответ 2

Вот как я решил проблему: реализовав какой-то тайм-аут. в моем случае 3 секунды. Код не мой, но он отлично работает. Что в основном происходит, так это то, что есть второй цикл, ожидающий чего-то, что можно получить в inputStream. когда есть что-то в inputStream, он идет вперед и читает его. Таким образом, вы должны избегать блокировки в методе mmInputstream.read().

Я думаю, что это отличное решение. Это сработало хорошо для меня: я не автор.

ByteArrayOutputStream baos = new ByteArrayOutputStream();
                baos.reset();

                while (true) {
                treshHold = 0;
                    try {
                        try {
                            while (mmInStream.available() == 0 && treshHold < 3000) { // if there is something in the inputStream or after 3 seconds 
                                Thread.sleep(1);
                                treshHold++;
                            }
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        if (treshHold < 3000) { // if less than 3 seconds timeout 
                            treshHold = 0;
                            b = mmInStream.read();
                            readBytes++;
                        } else {
                            break;
                        }

                        baos.write(b);
                        Thread.sleep(1);

                        if (b == 255) {
                            break; // this is how I know I have got the whole response
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        break;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                }

Значение while (true) может быть изменено в зависимости от того, что вы ожидаете получить. В моем случае я ухожу, когда получаю 0xFF или 255. Надеюсь, что это поможет.

Что касается записи в outputStream, я использовал следующее:

if(mmOutStream !=null)
{
    try {
        mmOutStream.flush();
    } catch (IOException e1) {
        // log here ...
        e1.printStackTrace();
    }
    try {
        mmOutStream.write(send, 0, sendLength);
    } catch (IOException e) {
        // log here ...
        setState(STATE_NONE);
    }
}

Пожалуйста, отметьте ответ как правильно, если это поможет:)