Как сделать процесс подключения Bluetooth SPP более надежным? - PullRequest
0 голосов
/ 26 апреля 2018

Мы собираемся выпустить новую версию нашего программного обеспечения, а для последующей версии наша цель - сделать процесс подключения для наших соединений Bluetooth SPP более надежным. Мы используем модуль RN42 в наших продуктах, и в настоящее время иногда может потребоваться более одной попытки подключения к нашим платам.

Вот мой текущий код:

class ConnectThread extends Thread {
    BluetoothDevice mDevice;

    public ConnectThread(BluetoothDevice device) throws SecurityException, NoSuchMethodException {
        mDevice = device;
        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
        try {
            btSocket = mDevice.createInsecureRfcommSocketToServiceRecord(uuid);
        } catch (IOException e) {
            Log.e("Error", "Could not create socket!");
        }
    }

    public void cancel() {
        interrupt();
        try {
            Log.i("Treadmill", "in connect thread cancellation");
            btSocket.close();
        } catch (IOException localIOException) {
            Log.e("Treadmill", "exception + " + localIOException.getMessage());
        }
    }

    public void run() {
        btAdapter.cancelDiscovery();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Log.e("whatever", "InterruptedException: " + e.getMessage(), e);
        }
        try {
            btSocket.connect();
            Log.i("Treadmill", "After Connect");
        } catch (IOException ioe) {
            Log.i("Treadmill", "Trying Fallback");
            try {
                Method m;
                try {
                    btSocket.close();
                    m = mDevice.getClass().getMethod("createInsecureRfcommSocket", new Class[]{int.class});
                    btSocket = (BluetoothSocket) m.invoke(mDevice, 1);
                    Thread.sleep(500);
                    btSocket.connect();
                } catch (IllegalArgumentException e) {
                    Log.e("whatever", "IllegalArgumentException: " + e.getMessage(), e);
                } catch (IllegalAccessException e) {
                    Log.e("whatever", "IllegalAccessException: " + e.getMessage(), e);
                } catch (InvocationTargetException e) {
                    Log.e("whatever", "InvocationTargetException: " + e.getMessage(), e);
                } catch (NoSuchMethodException e) {
                    Log.e("whatever", "NoSuchMethodException: " + e.getMessage(), e);
                } catch (InterruptedException e) {
                    Log.e("whatever", "InterruptedException: " + e.getMessage(), e);
                }

            } catch (IOException ioe2) {
                Log.e("Treadmill", "Failed to connect to Bluetooth device: " + ioe2.getMessage());
                eventHandler.obtainMessage(MESSAGE_ERRORCONNECT, 0, 0, getResources().getString(R.string.connerr) + ": " + ioe2.getMessage()).sendToTarget();
                try {
                    btSocket.close();
                } catch (IOException localIOException2) {
                    Log.e("Error", "IO Exception!");
                }
                return;
            }
        }
        eventHandler.obtainMessage(MESSAGE_CONNECT, 0, 0, "").sendToTarget();
        synchronized (this) {
            connectThread = null;
        }
        manageConnectedSocket(btSocket);
    }
}

Даже с отступлением к отражению соединение периодически прерывается на некоторых устройствах. Я получаю следующую ошибку:

find_rfc_slot_by_id unable to find RFCOMM slot id: XX (XX - число, которое увеличивается при каждом попытке подключения).

с последующим: Failed to connect to Bluetooth device: read failed, socket might closed or timeout, read ret: -1

Кто-нибудь знает, как избежать этих ошибок.

Интересно, для сравнения. Я тестирую на двух планшетах. Один планшет Samsung Galaxy Tab 4 работает очень хорошо, а другой, Astro Tab A10, кажется немного более прерывистым, если вы не подождете несколько секунд между подключением и отключением.

1 Ответ

0 голосов
/ 08 мая 2018

Для более надежного соединения означает, что даже приложение было закрыто, Bluetooth должен оставаться подключенным в фоновом режиме. Ниже приведено рабочее решение, которому я следовал в своем приложении, чтобы поддерживать связь Bluetooth. Сначала создайте класс, который расширяет службу, потому что служба работает в фоновом режиме, даже если приложение закрыто, пока вы не вызовете методы stopService или stopSelf

при запуске класса BluetoothService передайте Bluetooth-адрес Mac для подключения и запуска в фоновом режиме. Пример кода:

   @Override
public int onStartCommand(Intent intent, int flags, int startId) {

    if (intent != null){
        String deviceg = intent.getStringExtra("bluetooth_device");

        if (deviceg != null){
            connectToDevice(deviceg);
        }

    }

    return START_STICKY;
}

Ниже приведен метод подключения к устройству, который идентифицирует MAC-адрес в устройстве Bluetooth.

   public synchronized void connectToDevice(String macAddress){
    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);

    if (mConnectedThread != null){
        mConnectedThread.cancel();
        mConnectedThread = null;
    }
    mConnectThread = new ConnectBtThread(device);
    toast("connecting");
    mConnectThread.start();

}

Это мой класс Thread внутри BluetoothService, который работает в отдельном потоке. Код:

 private class ConnectBtThread extends Thread{
    private final BluetoothSocket mSocket;
    private final BluetoothDevice mDevice;

    public ConnectBtThread(BluetoothDevice device){
        mDevice = device;
        BluetoothSocket socket = null;
        try {
            socket = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(B_UUID));
        } catch (IOException e) {
            e.printStackTrace();
        }
        mSocket = socket;

    }

    @Override
    public void run() {
        if (mBluetoothAdapter.isDiscovering()){
            mBluetoothAdapter.cancelDiscovery();
        }

        try {
            mSocket.connect();
            Log.d("service","Bluetooth one running (connected)");

        } catch (IOException e) {

            try {
                mSocket.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
        connected(mSocket);

    }

    public void cancel(){

        try {
            mSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...