Отставание / нестабильное соединение Bluetooth с Android

У меня проблемы с подключением к WML-C46 AH Bluetooth Chip с помощью небезопасное соединение RFCOMM. Я написал приложение для Android с соответствующим кодом, чтобы показать вам мою проблему.

Приложение

В приложении всего одна кнопка. Если вы нажмете на эту кнопку, начнется обнаружение устройства Bluetooth. После завершения обнаружения приложение подключается к устройству Bluetooth (я использую только одно устройство Bluetooth для тестирования, поэтому оно не может найти другие устройства). Затем он открывает поток ввода для чтения данных этого устройства. Если соединение разрывается (генерируется ioexception) или снова нажимается кнопка, соединение разрывается (закрываются все потоки, сокеты и потоки). Если вы снова нажмете на кнопку, начнется обнаружение нового устройства и так далее ...

Проблема

Соединение не работает должным образом. Поток ввода данных кажется немного запаздывающим, и иногда соединение прерывается без видимой причины (IOException: программное обеспечение вызвало прерывание соединения или IOException: попробуйте еще раз). Это в значительной степени упрощенная версия примера чата Bluetooth для Android, в котором используется обнаружение устройств вместо сопряженных устройств и только одно действие.

Код

public class MainActivity extends Activity implements View.OnClickListener {

    BluetoothDevice btDevice;
    BluetoothSocket btSocket;
    InputStream inStream;
    OutputStream outStream;
    Object lock = new Object();
    boolean connected = false;
    boolean canceled = false;

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

        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        getApplicationContext().registerReceiver(btReceiver, filter);
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        getApplicationContext().registerReceiver(btReceiver, filter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onClick(View arg0) {
        if (!connected) {
            connected = true;
            canceled = false;

            new Thread(new Runnable() {
                @Override
                public void run() {
                    BluetoothAdapter btAdapter = BluetoothAdapter
                            .getDefaultAdapter();

                    try {
                        if (btAdapter.isDiscovering())
                            btAdapter.cancelDiscovery();
                        btAdapter.startDiscovery();

                        // block until device discovery has finished
                        synchronized (lock) {
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                Log.d("EXCEPTION", "", e);
                            }
                        }

                        btSocket = btDevice.createInsecureRfcommSocketToServiceRecord(UUID
                                .fromString("00001101-0000-1000-8000-00805F9B34FB"));
                        btSocket.connect();

                        inStream = btSocket.getInputStream();
                        outStream = btSocket.getOutputStream();

                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                while (!canceled) {
                                    try {
                                        int in;
                                        while ((in = inStream.read()) != -1) {
                                            Log.d("Received new byte: ", in
                                                    + "");
                                        }
                                    } catch (IOException e) {
                                        Log.d("EXCEPTION IN LISTENER", "", e);
                                        disconnect();
                                    }
                                }
                            }
                        }).start();
                    } catch (IOException e) {
                        Log.d("", "", e);
                    }
                }
            }).start();
        } else {
            disconnect();
        }
    }

    private void disconnect() {
        connected = false;
        canceled = true;

        try {
            btSocket.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }
        try {
            inStream.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }
        try {
            outStream.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }

        btDevice = null;
        btSocket = null;
        inStream = null;
        outStream = null;
    }

    private final BroadcastReceiver btReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            try {
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    synchronized (lock) {
                        lock.notifyAll();
                    }
                }
            } catch (Exception e) {
                Log.d(this.getClass().getName(), "", e);
            }
        }
    };
}

Я использую только методы блокировки или сам блокирую. Таким образом, установка соединения проходит довольно процедурно. Я, вероятно, потерял поток соединения в примере с Android, когда адаптировал его, но я не могу найти проблему.

Результат

Установление связи:

01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketNative
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): ...fd 47 created (RFCOMM, lm = 0)
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketFromFdNative
01-16 16:52:46.257: D/BluetoothUtils(6961): isSocketAllowedBySecurityPolicy start : device null
01-16 16:52:47.171: V/BluetoothSocket.cpp(6961): connectNative
01-16 16:52:47.570: V/BluetoothSocket.cpp(6961): ...connect(47, RFCOMM) = 0 (errno 115)

Разрывы соединения:

01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): java.io.IOException: Software caused connection abort
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothSocket.readNative(Native Method)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:388)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:60)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at com.example.bttest.MainActivity$2$1.run(MainActivity.java:100)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at java.lang.Thread.run(Thread.java:856)

Спасибо!


person Horrorente    schedule 16.01.2014    source источник


Ответы (1)


Нашел проблему. Устройство Bluetooth не работало должным образом и через несколько секунд отключило соединение. Однако код работает нормально.

person Horrorente    schedule 22.01.2014
comment
Какая у вас андроид версия ?? Вы нашли решение ?? - person Bomberlatinos9; 20.02.2014
comment
Проблемы были вызваны реальным устройством bluetooth, а не android или классом BluetoothDevice;) - person Horrorente; 26.02.2014