在Android上连接到蓝牙设备的特定蓝牙端口

4
有没有办法让Android使用指定的端口连接到蓝牙设备而不是使用服务UUID?我知道其他提供蓝牙支持的平台(例如Java ME)提供了此选项,通过指定“btspp://”样式的URL来实现。谢谢!
3个回答

10

好的,虽然有一段时间了,但我找到了解决问题的方法。 我实际上打算放弃并使用UUID,但是我一直收到“服务发现失败(IO)异常”,当我试图找到解决服务发现问题的方法时,我找到了我的原始问题的解决方法... 生活不是很奇妙吗?:)

无论如何,这是我偶然发现的链接,尽管您应该注意答案中有一个错误(他们实际上只连接到端口1,而没有使用服务UUID)。

在这个简短的历史课之后,下面是解决方案:

使用反射,可以创建连接到端口号而不是UUID的Rfcomm socket:

int bt_port_to_connect = 5; // just an example, could be any port number you wish
BluetoothDevice device = ... ; // get the bluetooth device (e.g., using bt discovery)
BluetoothSocket deviceSocket = null;
...
// IMPORTANT: we create a reference to the 'createInsecureRfcommSocket' method
// and not(!) to the 'createInsecureRfcommSocketToServiceRecord' (which is what the 
// android SDK documentation publishes
Method m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class});

deviceSocket = (BluetoothSocket) m.invoke(device,bt_port_to_connect);

需要注意以下几点:

  1. 由于我们使用了Invoke,第一个参数是我们要调用方法的对象,invoke的第二个参数实际上是第一个函数参数
  2. 还有一个安全版本可用('createRfcommSocket'),它接受蓝牙通道号作为单个参数(同样,由于这是调用样式,您需要传递对象以调用该方法,如-1-中所述)
  3. 我找到了一个似乎是这些函数原型的链接

祝大家好运。


0

我正在使用bluecove,它允许我使用函数Connector.open()来实现。

我使用以下URL:btspp://" + phoneID + ":" + phonePort

注意:可以添加一些选项(例如:authenticate=false;encrypt=false;)。

phoneID是蓝牙地址,phonePort是端口号。

如何找到蓝牙地址? 从这个链接

  1. 从主屏幕打开应用抽屉,然后打开“设置”。
  2. 选择“系统”。 (在某些型号上跳过此步骤)
  3. 向下滚动到底部,点击“关于手机”,“关于设备”或“关于平板电脑”。
  4. 向下滚动并点击“状态”。
  5. 向下滚动,列表中将显示“蓝牙地址”。

如何找到端口号? 我还没有找到应该使用哪个端口号... 我用了5,它可以工作,但我需要研究为什么,如果我想更换手机,我需要知道是否也需要更改端口。


0

蓝牙 Android 连接是通过 UUID 独占完成的。每个蓝牙设备都有一个 UUID,用于运行每个服务(请参见蓝牙 SDP)。

您只需向 Android 提供要监视的 UUID,在客户端模式下,它将自动找到要连接的套接字(包括端口)。在服务器模式下,它将等待指定的设备使用指定的 UUID 发起连接。 当建立连接时,BluetoothSocket 对象也是有效的(使用 getInput/Output Stream) 请参阅 Server Socket documentationClient Socket documentation


如果你真的想要检查所有内容,你可以查看Android从其他设备的SDP和你提供的UUID解码出来的内容。

使用这个教程获取蓝牙接口(非常容易)。 然后代码应该类似于这样:

IBluetooth ib =getIBluetooth();
Int otherDevicePort = ib.getRemoteServiceChannel(otherDeviceAddress, UUID);

谢谢!我实际上已经找到了解决问题的方法(现在作为下面的答案)。当我尝试使用UUID时,我一直收到“服务发现失败”的IOException,但我会检查您的建议并看看是否解决了这个异常。 - dcoder
我不知道这个......我的意思是,它确实解决了你的问题,但是,如果没有SDP,你怎么知道另一个设备的端口呢?你只是假设它总是1(因为你在蓝牙上没有其他与另一个设备的交互吗?) - Radu
我的问题确实是不常见且非常特定的,因为我需要与一个自定义设备通信,该设备始终在特定端口上侦听,并且不公开服务记录UUID。你说得对,在大多数情况下,标准(并且可能是推荐的)方法是使用SDP查找设备公开的服务记录,并根据该记录查找端口。 - dcoder
@radu 我正在尝试将Android应用程序连接到Linux计算机。不幸的是,Python蓝牙API通过端口号连接,而不是UUID。在旧版本的Android BluetoothDevice API中,它也允许RFCOMMs连接到端口号。然而,在当前的Kotlin版本中,这已经被淘汰了。 - Stigma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接