当前位置: 首页 > 知识库问答 >
问题:

Android滞后/不稳定的蓝牙连接

韩涵衍
2023-03-14

我在使用不安全的RFCOMM连接连接WML-C46 AH蓝牙芯片时遇到问题。我写了一个Android应用程序,里面只有相关的代码,可以告诉你我的问题。

应用程序

这个应用只有一个按钮。如果单击此按钮,蓝牙设备发现将启动。在发现完成后,应用程序将连接到蓝牙设备(我只使用一个蓝牙设备进行测试,所以它找不到任何其他设备)。然后,它打开一个输入流来读取该设备的数据。如果连接中断(引发ioexception)或再次单击按钮,则连接将关闭(关闭所有线程、套接字和流)。如果再次单击按钮,将启动新的设备发现,依此类推。。。

问题所在

连接不正常。数据输入流似乎有点滞后,有时连接中断,没有任何可观察到的原因(IOExc0019:软件导致连接中止或IOExc0019:重试)。这几乎是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)

谢谢

共有1个答案

蓟浩旷
2023-03-14

找到问题了。蓝牙设备没有按预期工作,几秒钟后关闭了连接。然而,代码工作正常。

 类似资料:
  • 每当设备断开连接时,我确保对BluetoothGatt对象调用close()并将其设置为null。有什么见解吗? 编辑: 日志转储:对于这些日志,我将我的电话根目录化,并提高了/etc/bluetooth/bt_stack.conf中相关项的跟踪级别 成功连接-重新启动手机并安装应用程序后的第一次尝试。我能够连接,发现所有的服务/特性,并读/写。

  • Hy,我们正在通过蓝牙开发android多人游戏。这是一款多人LUDO游戏,其中4名玩家相互连接并进行游戏。 我们被困在第三和第四名球员的连接。 上面是建立连接的示例代码。但是在连接服务类中,我们有以下代码 当移动设备连接到第三个或第四个设备时,它返回myBSock==null。但是如果代码正常工作,它必须返回设备的地址,并且应该将mBtDeviceAddresses.add(设备);添加到服务器

  • 问题内容: 我正在开发一个使用蓝牙连接到设备并发送/接收数据的应用程序。我正在使用Nexus One手机进行所有测试。 我从手机到任何设备都无法建立SPP(串行端口)连接。不过,我 已经 能够从一个设备(我的笔记本电脑)连接到使用Mac相当于腻子我的手机(唯一的例外是从市场上的“蓝牙文件传输”应用程序似乎是工作,但我不认为使用RFCOM / SPP …)。 我在LogCat日志中始终看到此消息:

  • 我如何获得Android所有已连接蓝牙设备的列表,而不考虑配置文件? 或者,我看到您可以通过BluetoothManager获取特定配置文件的所有连接设备。获取连接的设备。 我想我可以通过ACTION_ACL_CONNECTED/ACTION_ACL_DISCONNECTED监听连接/断开来查看哪些设备连接...似乎容易出错。 但我想知道是否有更简单的方法来获取所有已连接蓝牙设备的列表。

  • 我有一个android应用程序,它将所有配对的设备放在一个列表视图中。当您单击其中一个列表项时,它将发起连接到该蓝牙设备的请求。 我可以得到设备的列表和他们的地址没有问题。问题是,一旦我尝试连接,我会在socket.connect()上得到一个IOException; 错误消息如下:“连接读取失败,套接字可能关闭或超时,读取RET:-1” 请注意,在“尝试连接到设备”和“连接失败”之间有大约20秒

  • 我正在开发一个蓝牙应用程序来控制Arduino板,但现在我犯了一些错误:当我试图从手机连接时,它会显示一个(没关系)和许多祝酒(它们是从调用的)。BT模块连接到板子是可以的(测试与其他应用程序),所以问题是Java:我不能建立一个连接到我的BT模块。不幸的是,Android Studio没有给我任何日志或错误。这是我的代码: