无法接受Android中的传入蓝牙连接

时间:2011-12-14 07:53:12

标签: android bluetooth

可能类似于未答复的帖子here,但我们有一个Android应用程序(在多个手机和多个Android 2.1+版本上测试),需要监听并接受来自远程蓝牙设备的连接。远程设备是一个数字笔,但重点是笔与手机配对,然后通过SPP发送数据,SPP使用OBEX,使用RFComm所以这一切都应该没问题。

目前,该应用程序的工作原理是允许Android设备接收OBEX有效负载,然后让应用程序查看蓝牙文件夹以获取有效负载,但我们希望应用程序能够直接与远程设备通信。 请记住远程连接到Android手机,手机无法连接到笔。

我们的测试代码基于Android示例中提供的示例BluetoothChat应用程序,但基本上adapter.listenUsingRfcommWithServiceRecord永远不会被调用,我们在 Motorola Defy + DDMS日志中看到的最佳效果是:

INFO/BtOppRfcommListener(2577): Accepted connectoin from 00:07:CF:55:94:FB
INFO/BtOpp Service(2577): Start Obex Server
DEBUG/Obex ServerSession(2577): java.io.IOException: Software caused connection abort

这似乎表明Android已接受该连接,但该应用程序无法使用该连接。使用的UUID与同一应用程序的JME版本中使用的UUID相同,由笔供应商提供。

2 个答案:

答案 0 :(得分:1)

Android开发人员在复制BluetoothChat应用程序代码时最常犯的错误是我们不遵循该应用程序的流程。

实现此代码时的常见错误,如“服务发现失败”,“软件导致连接中止”,“连接中止连接”,“无法启动服务发现”,“连接丢失”等因素忽略了流动。

我在我的应用程序中实现BluetoothChat代码时遇到了所有这些问题,解决方案是纠正流程。

例如在我的情况下:

        OnCreate:

            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        OnStart:

        if(this.mChatService == null)
                this.mChatService = new BluetoothChatService(this, mHandler);

        OnResume:
        if ((mChatService != null) &&  (mBluetoothAdapter.isEnabled())) {
    // Only if the state is STATE_NONE, do we know that we haven't started already
            if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
                        // Start the Bluetooth chat services
                        mChatService.start();
                    }
                }
        OnDestroy:
        if(mTransferService != null) mTransferService.stop();

   onActivityResult:
    case REQUEST_CONNECT_DEVICE:
    // When DeviceListActivity returns with a device to connect
    if (resultCode == Activity.RESULT_OK) {
    if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
            // Start the Bluetooth chat services
            mChatService.start();
            }
    if(mChatService .getState() != BluetoothChatService.STATE_CONNECTED){
    String address = data.getExtras().getString(ViewContactList.EXTRA_DEVICE_ADDRESS);
        // Get the BLuetoothDevice object
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        device = mBluetoothAdapter.getRemoteDevice(address);
        // Attempt to connect to the device
        mChatService.connect(device);
        }
        else{
        if(messageString.length() > 0)
        MyCurrentActivity.this.sendMessage(messageString);
        }

简单来说,在你调用之前,以两种设备都处于mState = STATE_LISTEN的方式实现代码

mChatService.connect(device);

答案 1 :(得分:1)

在我们的案例中,我们发现唯一能够可靠地接受来自远程设备的蓝牙OPP数据的解决方案是使用“隐藏的”Android API。如果您检查Android源代码,则会定义其他注释@hide的方法,这些方法会从导出的Android jar和API文档中排除它们。

如果可能,应避免使用这些方法,并且不保证在Android版本中保持一致。

有两种方法可以在代码中包含这些内容:

  1. 使用反射
  2. 在编译时包含一个额外的开发JAR,它公开了这些方法,但要确保这个JAR没有与你的应用程序一起打包。
  3. 我们选择了#1,因为我们的要求很少。

    访问方法

    Class<?>[] args = new Class[] { int.class };
    Method listenMethod = BluetoothAdapter.class.getMethod(listenMethod, args);
    

    方法名称是(按优先顺序排列)listenUsingEncryptedRfcommOnlistenUsingRfcommOnlistenUsingUnencrytptedRfcommOn

    之一

    创建服务器套接字

    BluetoothAdapter target = *your adapter, probably the default one*;
    BluetoothServerSocket sock = (BluetoothServerSocket) (listenMethod.invoke(target, new Object[] { channel }));
    

    在我们的情况下,OPP频道 12

    如果您设法获得BluetoothServerSocket返回(省略例外处理,您的里程可能会有所不同,建议用户自行决定,不提供保证等等),您应该能够使用它来收听传入的OPP数据。