Java 在 Android 上使用蓝牙服务发现失败异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3397071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Service discovery failed exception using Bluetooth on Android
提问by TxAg
I'm currently working on an Android application that connects to an instrument via Bluetooth and need to write string commands and receive string responses back. Currently I have the connect/read/write working for TCP/IP over Wi-Fi and now trying to implement Bluetooth. But I am running into some roadblocks. I have been searching the web trying to find examples of something similar and haven't had any luck. I have been using the Android developer resource example: Bluetooth Chat as my main reference point.
我目前正在开发一个通过蓝牙连接到仪器的 Android 应用程序,需要编写字符串命令并接收字符串响应。目前,我通过 Wi-Fi 为 TCP/IP 进行连接/读/写工作,现在正在尝试实现蓝牙。但我遇到了一些障碍。我一直在网上搜索,试图找到类似的例子,但没有任何运气。我一直在使用 Android 开发人员资源示例:Bluetooth Chat 作为我的主要参考点。
My current code seems to work.. Then it throws a Service Discovery Failed exception at the point of the connection. I am using the DeviceListActivity
class to do the discovery and selecting of the device I want to connect to. It returns anActivityResult and then my Bluetooth class waits for it to handle that and then does the connect to it. The code beneath is almost identical to the Bluetooth Chat App.
我当前的代码似乎工作.. 然后它在连接点抛出一个服务发现失败异常。我正在使用DeviceListActivity
该类来发现和选择要连接的设备。它返回一个ActivityResult,然后我的蓝牙类等待它处理它,然后连接到它。下面的代码几乎与蓝牙聊天应用程序相同。
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(!m_BluetoothAdapter.isEnabled())
{
m_BluetoothAdapter.enable();
}
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = m_BluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
connect(device);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
}
else {
// User did not enable Bluetooth or an error occured
Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_SHORT).show();
finish();
}
}
}
This is my connect function:
这是我的连接功能:
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private void connect(BluetoothDevice device) {
m_Device = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
}
catch (IOException e) {
}
m_Socket = tmp;
m_BluetoothAdapter.cancelDiscovery();
try {
// This is a blocking call and will only return on a
// successful connection or an exception
m_Socket.connect();
}
catch (IOException e) {
try {
m_Socket.close();
}
catch (IOException e2) {
}
return;
}
}
Hopefully, whatever I am doing wrong is simple, but I'm afraid it's never that easy. This is my first time doing any Bluetooth development, and maybe I'm doing something blatantly wrong... But I'm not sure why I get the service discovery failed exception.
希望无论我做错什么都很简单,但恐怕从来没有那么容易。这是我第一次做任何蓝牙开发,也许我在做一些明显错误的事情......但我不确定为什么我会得到服务发现失败的异常。
You can pair/find the device at all times manually on the phone... It does require a passcode, but I don't think that is the problem that I am having.
您可以随时在手机上手动配对/查找设备...它确实需要密码,但我认为这不是我遇到的问题。
采纳答案by TxAg
After three days I got it figured out thanks to some very helpful posts.
三天后,由于一些非常有用的帖子,我弄明白了。
I had to replace:
我不得不更换:
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
with:
和:
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(device, 1);
and voilà it works!
瞧它的工作原理!
回答by Rup
This was a suggested edit from an anonymous userattempting to reply to the accepted answer.
这是来自试图回复已接受答案的匿名用户的建议编辑。
One big difference between your before and after code is the UUID you are passing. I found my answer here: http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord(java.util.UUID)
前后代码之间的一大区别是您传递的 UUID。我在这里找到了我的答案:http: //developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord(java.util.UUID)
I had to replace:
我不得不更换:
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
with:
和:
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
tmp = device.createRfcommSocketToServiceRecord(SPP_UUID);
and voila it works! The original code is for a peer to peer android app. It makes no sense to use the app UUID when connecting to a simple serial bluetooth device. Thats why discovery fails.
瞧,它起作用了!原始代码用于点对点 android 应用程序。连接到简单的串行蓝牙设备时,使用应用程序 UUID 毫无意义。这就是发现失败的原因。
回答by Muzikant
As of API 15 you can use the following method:
从 API 15 开始,您可以使用以下方法:
Try replacing your UUID with the return value of getUuids() method of BluetoothDevice
class.
What worked for me was something like this:
尝试用类的getUuids() 方法的返回值替换您的 UUID BluetoothDevice
。对我有用的是这样的:
UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
The reason this works is that different devices support different UUIDs and by getting the UUIDs of the device using getUuidsyou are supporting all features and devices.
这样做的原因是不同的设备支持不同的 UUID,并且通过使用getUuids获取设备的 UUID,您可以支持所有功能和设备。
Another interesting new method (supported since API 14) is this: BluetoothHealth.getConnectionState. Haven't tried it but looks promising...
另一个有趣的新方法(自 API 14 起支持)是:BluetoothHealth.getConnectionState。没试过,但看起来很有希望......
回答by Devgrapher
So as it mentioned above, the point is that you need to use the UUID that the server is waiting for.
所以正如上面提到的,关键是你需要使用服务器正在等待的 UUID。
If you are connecting to a bluetooth device, such as a headset or mouse, you need to check which UUIDs the device is listening for. You can see the UUIDs like this.
如果您连接到蓝牙设备,例如耳机或鼠标,则需要检查设备正在侦听哪些 UUID。您可以像这样看到 UUID。
UUID[] uuids = bluetoothDevice.getUuids();
And if you want to know what these UUIDs mean, see this.
如果您想知道这些 UUID 的含义,请参阅此。
回答by animalito maquina
This is a realy old one question but i found that using the createInsecureRfcommSocketToServiceRecord()
instead of createRfcommSocketToServiceRecord()
along with the getUuids()
previously mentioned do the trick for me
这是一个非常古老的问题,但我发现使用createInsecureRfcommSocketToServiceRecord()
而不是createRfcommSocketToServiceRecord()
与getUuids()
前面提到的一起使用对我有用
UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);