【问题标题】:How to make a Bluetooth SPP connection process more reliable?如何让蓝牙 SPP 连接过程更可靠?
【发布时间】:2018-10-07 09:40:35
【问题描述】:

我们即将发布我们软件的新版本,对于之后的版本,我们的目标是让我们的蓝牙 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: XXXX 是一个在每次尝试连接时递增的数字)。

接着是: Failed to connect to Bluetooth device: read failed, socket might closed or timeout, read ret: -1

有谁知道如何避免这些错误。

有趣的是,为了比较。我正在两个平板电脑上进行测试。一款平板电脑,三星 Galaxy Tab 4 似乎工作得非常好,而另一款平板电脑,Astro Tab A10,似乎有点断断续续,除非你在连接和断开之间等待几秒钟。

【问题讨论】:

    标签: android bluetooth android-bluetooth rfcomm spp


    【解决方案1】:

    为了更可靠的连接意味着即使应用程序关闭,蓝牙也应在后台保持连接。 以下是我在我的应用程序中遵循的工作解决方案,以保持蓝牙连接背景。 首先创建一个扩展服务的类,因为服务在后台运行,即使应用程序关闭,直到您调用 stopService 或 stopSelf 方法

    在启动 BluetoothService 类时,通过蓝牙 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地址识别到蓝牙设备中。

       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();
    
    }
    

    这是我在 BluetoothService 中的 Thread 类,它在单独的线程中运行 代码:

     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();
            }
        }
    }
    

    它非常适合我们的应用程序。 如果您想访问服务方法,请将此服务绑定到您的活动

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-05
      • 2011-10-26
      • 2020-04-30
      • 2017-12-14
      • 1970-01-01
      相关资源
      最近更新 更多