android - 蓝牙 SDP 和 UUID 如何工作? (专门针对安卓)

标签 android bluetooth

我的理解是,SDP 是其他设备可以获取的 UUID 列表。

根据麻省理工学院的这个 PDF,“一种更通用的思考方式 SDP 就像一个信息数据库。”这是否意味着我可以向 SDP 添加多个值?由于 Android 具有 BluetoothDevice.fetchUuidsWithSdp(),我该如何设置设备的 UUID?

此外,UUID 的每个部分是什么意思? UUID 看起来像 00000000-0000-1000-8000-00805F9B34FB,但这传达了什么信息?

最佳答案

UUID 标识在特定设备上可用的服务。因此,如果您调用 BluetoothDevice.fetchUUidsWithSdp(),您的 BroadcastReceiver 将收到相关的 Intent ACTION_UUID。包含设备和服务 UUID。 蓝牙规范defines some common UUIDs .

如果您不想连接到这些众所周知的服务之一,但打算实现您自己的蓝牙应用程序,那么您必须生成自己的 UUID(从 unix 控制台或 online generator 使用 uuidgen)标识您的应用程序/服务。 您可以在 java 中创建 UUID 实例,如下所示 UUID uuid = UUID.fromString("785da8ea-1220-11e5-9493-1697f925ec7b");

因此,如果您在 Android 上为蓝牙应用程序创建服务器端,您通常会做 this

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
BluetoothServerSocket serverSocket = adapter.listenUsingRfcommWithServiceRecord("YourHumanReadableServiceName", uuid);

这是您“设置”您的 UUID 的地方。 Android 蓝牙 API 为您创建包含应用程序 UUID 和名称的 SDP 条目。其他设备现在可以检索此条目。 Android 的蓝牙堆栈现在会将蓝牙 channel 关联​​到您的 BluetoothServerSocket。如果你想连接到这个 ServerSocket,连接端通常会做 this 连接。 :

// you will most likely already have this instance from a discovery or paired device list
BluetoothDevice serverDevice = adapter.getRemoteDevice(bluetoothMacAddress);
// connect to your ServerSocket using the uuid
BluetoothSocket socket = serverDevice.createRfcommSocketToServiceRecord(uuid);
socket.connect();

Android 将再次为您完成繁重的工作:它检查远程设备上的 SDP 记录,查找与您服务的 UUID 相对应的蓝牙 channel ,并使用此信息进行连接。

SO 上有一个常见的代码 fragment ,它建议您使用“反射”来获取类似于此代码的隐藏 API:

 try {
     // this is the way to go
     socket = device.createRfcommSocketToServiceRecord(uuid);
     socket.connect( );
 } catch ( IOException exception ) {
     // don't do that! You will bypass SDP and things will go sideways.
     Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
     socket = (BluetoothSocket) m.invoke(device, 1);
     socket.connect();
 }

大多数人都尝试过这个并且它在他们的开发环境中“正常工作”但是你应该知道你用它做什么。您主动绕过 SDP 查找,检索正确的蓝牙 channel 以与您的服务一起使用,您最终将连接到 channel 1。如果您的设备上运行了多个服务,在这种情况下,事情会发生变化,您将最终陷入调试 hell ;-)

我开发了一个 small middleware called Blaubot使用蓝牙/wifi/nfc 创建小型网络,并在我用来测试的设备(12 个型号)上遇到了各种问题。通常情况下,如果蓝牙堆栈有一些负载或经过多次连接/断开连接(如果您正在开发您的应用程序,您通常会遇到这种情况),则蓝牙堆栈不再完全正常运行。在这些情况下,device.createRfcommSocketToServiceRecord(uuid) 偶尔会失败,只有关闭蓝牙适配器并再次打开才有助于使蓝牙适配器恢复正常(在某些情况下仅在完全电源循环后) .如果发生这种情况并且您使用反射方法,您可能不会有太多的蓝牙乐趣。

但如果您知道这一点并在一定范围内保持对 BluetoothAdapter 的并发调用,蓝牙连接和适配器将非常稳定。

关于android - 蓝牙 SDP 和 UUID 如何工作? (专门针对安卓),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30813854/

相关文章:

android - Android Studio-Gradle-根据每个Android Studio安装而不是每个项目设置代理

java - Android AWS S3 Upload TransferUtility错误上传部分中断: time out and socket is closed

android - 蓝牙是多人回合制游戏的可行选择吗?

Android打开XLSX文件

java - 如何将 Image View 和 TexView 左右对齐?

java - Android JNI 检测到应用程序错误 : JNI GetMethodID called with pending exception

python - 如何通过 Arduino 蓝牙模块将数据实时传递到运行 python 脚本的 PC?

android - 如何减少android中的BLE连接间隔时间

ios - iPhone 应用程序 - 与蓝牙设备通信

android - 为蓝牙聊天示例将 PC 与 Android 2.1 手机连接时出现问题