Android中连接蓝牙设备时遇到createRfcommSocketToServiceRecord的UUID问题和BluetoothSocket的connect失败...

【问题】

折腾:

【记录】编写Android中的蓝牙模块驱动和底层HART设备

期间,参考:

Bluetooth | Android Developers – ManagingAConnection

参考“Connecting as a client”中的:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

遇到UUID不懂的问题。

然后随便去

http://www.guidgenerator.com/online-guid-generator.aspx

弄了个UUID:

e214d9ae-c3ba-4e25-abb5-299041353bc3

结果运行到:

            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket.connect();
            } catch (IOException connectException) {
                // Unable to connect; close the socket and get out
                try {
                    mmSocket.close();
                } catch (IOException closeException) { }
                return;
            }

中的:

mmSocket.connect(); 

时就抛异常了。

即:

遇到createRfcommSocketToServiceRecord的UUID不懂,以及BluetoothSocket的connect失败。

 

【解决过程】

1.参考:

android – Why can’t HTC Droid running OTA 2.1 communicate with RFCOMM? – Stack Overflow

去试试:

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
mBTSocket = (BluetoothSocket) m.invoke(device, 1);

结果看着就不太对啊。。就不继续试了。

2.参考:

Need Bluetooth UUID clarification – Google Groups

去试试:

00001101-0000-100­0-8000-00805F9B34FB

结果直接挂掉。

3.再去试试:

00000003-0000-100­0-8000-00805F9B34FB

也会挂掉。

4.后来再去搜:

android bluetooth connect fail

然后去参考:

android bluetooth can’t connect – Stack Overflow

和:

The Missing Manual: Android Bluetooth RFCOMM « Wires Are Obsolete

去试试,用代码:

 // Create a BroadcastReceiver for ACTION_FOUND
 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
     public void onReceive(Context context, Intent intent) {
//	 BluetoothDevice deviceExtra = intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
//	 Parcelable[] uuidExtra = intent.getParcelableArrayExtra("android.bluetooth.device.extra.UUID");

         String action = intent.getAction();
         // When discovery finds a device
         if (BluetoothDevice.ACTION_FOUND.equals(action)) {
             // Get the BluetoothDevice object from the Intent
             BluetoothDevice btDev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             Parcelable[] btDevUuid = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);

调试得到的btDevUuid都是null的。

5.换用:

         if (BluetoothDevice.ACTION_FOUND.equals(action)) {
             // Get the BluetoothDevice object from the Intent
             BluetoothDevice btDev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             //Parcelable[] btDevUuid = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
             UUID btDevUuid = intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID);

还是不行。

6.参考:

Issue 15919 – android – Bluetooth connect fails under 2.3.3 for SPP devices using secure comms

中提到的:

BluetoothDevice | Android Developers

中提示的:

Hint: If you are connecting to a Bluetooth serial board then try using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB. However if you are connecting to an Android peer then please generate your own unique UUID.

所以再去试试这个UUID:

00001101-0000-1000-8000-00805F9B34FB

最终是可以了:

android bluetooth ssp uuid 00001101-0000-1000-8000-00805F9B34FB connect ok

对应的相关代码为:

 private String mactekHartModemName;
 private UUID mactekHartModemUuid;
    
 //void afterFoundBtHartModem(BluetoothDevice btDev, Parcelable[] btDevUuid){
 void afterFoundBtHartModem(BluetoothDevice btDev, UUID btDevUuid){
  if(null != btDevUuid){
      
  }
  
     //mactekHartModemName = btDev.getName(); //"MACTekViator75FE"
     //mactekHartModemUuid = UUID.fromString(mactekHartModemName);
  
  String uuidValue;
  //http://www.guidgenerator.com/online-guid-generator.aspx
  //uuidValue = "e214d9ae-c3ba-4e25-abb5-299041353bc3";
  
  //https://groups.google.com/forum/#!topic/android-developers/vyTEJOXELos
  //uuidValue = "00001101-0000-100­0-8000-00805F9B34FB";
  //uuidValue = "00000003-0000-100­0-8000-00805F9B34FB";
  uuidValue = "00001101-0000-1000-8000-00805F9B34FB";

  mactekHartModemUuid = UUID.fromString(uuidValue);

     ConnectThread connectBtThread = new ConnectThread(btDev);
     connectBtThread.start();
 }

    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
     
        public ConnectThread(BluetoothDevice device) {
            // Use a temporary object that is later assigned to mmSocket,
            // because mmSocket is final
            BluetoothSocket tmp = null;
            mmDevice = device;
     
            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {
                // MY_UUID is the app's UUID string, also used by the server code
                tmp = device.createRfcommSocketToServiceRecord(mactekHartModemUuid);//00001101-0000-1000-8000-00805F9B34FB

            } catch (IOException e) { }
            mmSocket = tmp;
        }
     
        public void run() {
            // Cancel discovery because it will slow down the connection
            mBluetoothAdapter.cancelDiscovery();
     
            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket.connect();
            } catch (IOException connectException) {
                // Unable to connect; close the socket and get out
                try {
                    mmSocket.close();
                } catch (IOException closeException) { }
                return;
            }
     
            // Do work to manage the connection (in a separate thread)
            manageConnectedSocket(mmSocket);
        }
     
        /** Will cancel an in-progress connection, and close the socket */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }

 

【总结】

此处,必须使用Android的SSP(协议栈默认)的UUID:

00001101-0000-1000-8000-00805F9B34FB

才能正常和外部的,也是SSP串口的蓝牙设备去连接。

<think>嗯,用户遇到了Android蓝牙连接BluetoothSocket.connect()方法超问题,需要解决。首先,我得回忆一下常见的蓝牙连接问题及解决方法。根据提供的引用内容,尤其是引用[2]提到的,创建BluetoothSocket的方式可能有问题,常规的createRfcommSocketToServiceRecord会出错,而改用反射调用createRfcommSocket方法可能更可靠。这可能是一个关键点。 然后,用户提到连接,可能的原因包括设备未准备好、UUID不匹配、或者物理距离过远。需要检查设备是否处于可发现或配对状态,但Android的蓝牙连接通常不需要设备可见,只要已配对。不过,有些设备可能需要特定的模式。另外,UUID是否正确非常重要,特别是SPP(串行端口)常用的UUID是否正确,比如00001101-0000-1000-8000-00805F9B34FB。 另外,引用[2][3]都提到了不同的创建socket的方法,比如使用反射或者createInsecureRfcommSocketToServiceRecord。这些方法可能有助于绕过某些系统限制或兼容性问题。可能需要建议用户尝试不同的创建方式,并处理可能发生的异常。 接下来,超问题可能需要设置连接机制。因为原生的connect()方法是阻塞的,没有超参数,所以需要在子线程中执行,并手动设置超。例如,启动一个线程执行connect(),然后主线程等待一段间,如果超则中断连接尝试。这需要处理线程可能的InterruptedException。 还有,物理因素如距离过远或干扰也需要考虑,用户应确保设备在有效范围内,并减少障碍物。此外,重试机制也很重要,因为蓝牙连接不稳定,多次尝试可能成功。 另外,检查设备是否支持所需的蓝牙协议,比如SPP或其他配置文件。不同的设备可能有不同的支持情况,使用正确的协议UUID是关键。 最后,用户可能需要更新固件或检查系统权限,比如确保在AndroidManifest中声明了蓝牙权限,并在运行请求必要的权限,如ACCESS_FINE_LOCATION,这在较新的Android版本中是必须的。 综合这些因素,解决方案应包括正确的socket创建方法、超处理、异常捕获、重试机制以及环境检查。需要分步骤说明,并参考提供的引用内容中的方法,特别是使用反射创建socket适当延迟关闭连接的建议。</think>### BluetoothSocket.connect()蓝牙连接解决方案 #### 1. 检查设备状态与兼容性 - 确保目标设备已处于 **可配对/可连接状态**(部分设备需要特定模式) - 确认双方设备支持相同 **蓝牙协议版本**(如SPP协议需要UUID为`00001101-0000-1000-8000-00805F9B34FB`[^3]) - 检查设备是否在有效通信范围内(建议距离小于10米) #### 2. 优化Socket创建方式 使用反射创建更稳定的Socket连接: ```java try { Method m = device.getClass().getMethod("createRfcommSocket", int.class); BluetoothSocket socket = (BluetoothSocket) m.invoke(device, 1); } catch (Exception e) { e.printStackTrace(); } ``` 此方法相比`createRfcommSocketToServiceRecord`更可靠[^2] #### 3. 添加超控制机制 ```java ExecutorService executor = Executors.newSingleThreadExecutor(); Future<?> future = executor.submit(() -> { try { socket.connect(); // 在子线程执行连接 } catch (IOException e) { e.printStackTrace(); } }); try { future.get(10, TimeUnit.SECONDS); // 设置10秒超 } catch (TimeoutException e) { socket.close(); // 超后立即关闭 future.cancel(true); } ``` #### 4. 异常处理建议 - 捕获`IOException`后增加 **重试机制**(建议最多3次) - 连接成功后增加 **200ms延** 再发送数据,避免缓冲区未就绪[^2] - 使用`createInsecureRfcommSocketToServiceRecord`尝试非安全连接 #### 5. 其他注意事项 ```xml <!-- AndroidManifest.xml需添加权限 --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ``` Android 6.0+需要动态申请定位权限才能扫描蓝牙设备
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值