蓝牙SDP和UUID如何工作? (专门针对Android)

时间:2015-06-13 00:11:06

标签: android bluetooth

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

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

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

1 个答案:

答案 0 :(得分:8)

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

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

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

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

这就是你设置"你的UUID。 Android蓝牙API会为您创建由您的应用程序的UUID和名称组成的SDP条目。其他设备现在可以检索此条目。 Androids蓝牙堆栈现在将蓝牙通道与您的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-Records,查找与您服务的UUID对应的蓝牙通道,并使用此信息进行连接。

这里有一个常见的代码片段就是SO,建议你使用"反射"获取类似于此代码的隐藏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查找,检索要与您的服务一起使用的正确蓝牙通道,并且最终将连接到通道1.如果您在设备上运行了多个服务,在这种情况下,事情将会横向进行,您将最终调试地狱; - )

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

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