как решить Bluetooth Connect () не удается сокет может быть близко - PullRequest
0 голосов
/ 03 июля 2019

Я пытаюсь создать приложение, которое связывается с соседними устройствами. Мое приложение состоит из основного действия, которое запрашивает включение Bluetooth и устанавливает режим обнаружения, поэтому оно ожидает установления соединения.

Второе занятие занимается поиском ближайших устройств и установкой сопряжения. После сопряжения происходит обмен некоторыми сообщениями о конфигурации, а затем оба запускают ThirdActivity, который касается связи между двумя устройствами.

Я могу успешно обмениваться этими сообщениями, но проблема в том, что мне нужно передать объект BluetoothService (который хранит информацию о связи) в Третье действие.

Поскольку я не думаю, что смогу реализовать parcelable, тогда я просто закрыл соединение, не устраняя сопряжение, а затем заново создал AcceptThread и ConnectThread в третьем действии, создав новый объект BluetoothService, но всегда передавая один и тот же BluetoothDevice.

Из различных журналов происходит то, что AcceptThread ожидает функции accept (), в то время как ConnectThread не выполняет connect (), сообщая об этой ошибке.

W/System.err: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
        at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:762)
        at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:776)
        at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:399)
        at com.crossthebox.progetto.BluetoothService$ConnectThread.run(BluetoothService.java:118)

Что я могу сделать?

Это класс BluetoothService

public class BluetoothService {
    private UUID myid = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
    private static final String appName = "myapp";

    private static final int STATE_NONE = 0;       // we're doing nothing
    private static final int STATE_LISTEN = 1;     // now listening for incoming connections
    private static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
    private static final int STATE_CONNECTED = 3;
    private static final int STATE_BUFFER_NOT_EMPTY = 4;
    private String message ="";

    private int mState;
    private final BluetoothAdapter mBluetoothAdapter;
    Context mContext;

    private AcceptThread mAcceptThread;

    private ConnectThread mConnectThread;
    private BluetoothDevice mDevice;
    private UUID deviceUUID;


    private ConnectedThread mConnectedThread;

    public BluetoothService(Context context) {
        mContext = context;
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mState = STATE_NONE;
    }

    private class AcceptThread extends Thread {

        private final BluetoothServerSocket bluetoothServerSocket;

        public AcceptThread(){
            BluetoothServerSocket tmp = null;

            try{
                tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(appName, myid);
            }catch (IOException e){

            }
            bluetoothServerSocket = tmp;
            mState  = STATE_LISTEN;
        }

        public void run() {
            BluetoothSocket socket = null;

            try {
                socket = bluetoothServerSocket.accept();

            } catch (IOException e) {

            }
            if (socket != null) {
                mState = STATE_CONNECTING;
                connected(socket);
            }
        }

        public void cancel() {
            try {
                bluetoothServerSocket.close();
            } catch (IOException e) {
            }
        }
    }

    private class ConnectThread extends Thread {
        private BluetoothSocket mSocket;

        public ConnectThread(BluetoothDevice device, UUID uuid) {
            mDevice = device;
            deviceUUID = uuid;
        }

        public void run(){
            BluetoothSocket tmp = null;
            // Get a BluetoothSocket for a connection with the
            // given BluetoothDevice
            try {
               tmp = mDevice.createRfcommSocketToServiceRecord(deviceUUID);
            } catch (IOException e) {

            }
            mSocket = tmp;

            mBluetoothAdapter.cancelDiscovery();

            try {
                mSocket.connect(); //this throws exception for socket close ( but only the second time)
            } catch (IOException e) {
                // Close the socket
                try {
                    mSocket.close();
                } catch (IOException e1) {
                }
                e.printStackTrace();
            }
            connected(mSocket);
        }
        public void cancel() {
            try {
                mSocket.close();
            } catch (IOException e) {
            }

        }
    }

    public synchronized void start() {
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }
        if (mAcceptThread == null) {
            mAcceptThread = new AcceptThread();
            mAcceptThread.start();
        }
    }


    public void startClient(BluetoothDevice device,UUID uuid){
        mConnectThread = new ConnectThread(device, uuid);
        mConnectThread.start();
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mSocket;
        private final InputStream mInStream;
        private final OutputStream mOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = mSocket.getInputStream();
                tmpOut = mSocket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }

            mInStream = tmpIn;
            mOutStream = tmpOut;
        }

        public void run(){
            byte[] buffer = new byte[1024];

            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                // Read from the InputStream
                try {
                    bytes = mInStream.read(buffer);
                    if(bytes != 0) {
                        String incomingMessage = new String(buffer, 0, bytes);
                        message = incomingMessage;
                        System.out.println("HO LETTO " + message);
                        mState = STATE_BUFFER_NOT_EMPTY;
                    }
                } catch (IOException e) {
                    break;
                }
            }
        }

        //Call this from the main activity to send data to the remote device
        public void write(byte[] bytes) {
            try {
                mOutStream.write(bytes);
            } catch (IOException e) {

            }
        }

        //termina la connessione
        public void cancel() {
            try {
                mSocket.close();
            } catch (IOException e) { }
        }
    }

    private void connected(BluetoothSocket mSocket) {
        // Start the thread to manage the connection and perform transmissions
        mConnectedThread = new ConnectedThread(mSocket);
        mConnectedThread.start();
        mState = STATE_CONNECTED;

    }

    public void write(byte[] out) {
        // Create temporary object
        ConnectedThread r;
        // Synchronize a copy of the ConnectedThread
        synchronized (this) {
            if (mState != STATE_CONNECTED) {
                return;}
            r = mConnectedThread;
        }
        // Perform the write unsynchronized
        r.write(out);
    }

    public int getState(){

        return mState;
    }
    public String getMessage(){
        String tmp = null;
        if(!message.equals("")){
            tmp = message;
            message = "";
        }
        mState = STATE_CONNECTED;
        return tmp;
    }
    public void setState(int state){
        this.mState = state;
    }

    public void cancel(){
        if(mAcceptThread != null) {
            mAcceptThread.cancel();
            mAcceptThread = null;
        }
        if(mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }
        if(mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        /* * */

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        /* * */
        if(requestCode == DISCOVER_REQUEST){
            if(resultCode ==  120){

                bluetoothService = new BluetoothService(this);
                bluetoothService.start();

                //after receiving some message correctly
                Intent thirdActivity = new Intent(this, com.project.ThirdActivity.class);
                bluetoothService.cancel();
                this.startActivity(thirdActivity);
                finish();
            }
            if(resultCode == RESULT_CANCELED){
                finish();
            }
        }
    }

}

SecondActivity, как я отменяю соединение, практически совпадает с MainActivity. Я закрываю сокет после некоторого сообщения и затем запускаю ThirdActivity

ThirdActivity

if(mode == CLIENT){
    BluetoothDEvice bluetoothDevice = getIntent().getExtras().getParcelable("btdevice");
    bluetoothService.startClient(bluetoothDevice,myid);
}else //SERVER
    bluetoothService.start();

1 Ответ

0 голосов
/ 03 июля 2019

Возможное решение:

  1. Передача выбранного MAC-адреса из Activity2 в Activity3
  2. В Activity3 Запустите ConnectThread в службе Bluetooth.
  3. Использование обработчика для связи между службой и Activity3.
  4. Убедитесь, что вы закрываете нить, когда разъемы отсоединяются.

Яркий пример по следующей ссылке:

https://github.com/googlesamples/android-BluetoothChat

...