区分 "out of range" 或 "in range, but no listening server socket"? (蓝牙)
Differentiate between "out of range" or "in range, but no listening server socket"? (Bluetooth)
问题
我如何区分无法与远程 Android 设备建立蓝牙连接,因为:
- 场景 1:远程设备超出范围,或者其蓝牙被禁用。
- 场景2:远程设备在范围内,但远程设备上没有服务器套接字来接受我的连接。
我试过的
我无法区分连接时抛出的异常,因为它在两种情况下抛出相同的异常:
java.io.IOException: read failed, socket might closed or timeout, read ret -1
我无法使用fetchUuidsWithSdp()
检查远程设备是否支持我的 UUID,因为它在任何一种情况下的行为方式都相同。 .according to the documentation:
This API is asynchronous and {@link #ACTION_UUID} intent is sent, with the UUIDs supported by the remote end. If there is an error in getting the SDP records or if the process takes a long time, {@link #ACTION_UUID} intent is sent with the UUIDs that is currently present in the cache...
根据 this SO thread,它的行为似乎也有点不可预测。
最后,我不想使用sdpSearch
来区分两者,因为那是在API中添加的23,我希望能撑到API 19.
您可以通过尝试连接到通常在 Android 设备上可用的标准 UUID 来确定设备是否在范围内。如果呼叫连接:
- 失败,则远程设备超出范围或蓝牙被禁用。
- 成功,则远程设备在范围内,您应该关闭连接,然后尝试连接到您应用的 UUID...如果失败,则没有侦听套接字...如果成功,则一切都很好。
示例代码:
public BluetoothSocket connect(BluetoothDevice remoteDevice) throws IOException
{
OPP_UUID = UUID.fromString("00001105-0000-1000-8000-00805f9b34fb");
// check if remote device is in range...throw exception if out of range
try
{
BluetoothSocket socket = remoteDevice
.createRfcommSocketToServiceRecord(OPP_UUID);
socket.connect();
socket.close();
}
catch(IOException ex)
{
throw new IOException("out of range",ex);
}
// try to connect to service on remote device...throw exception if UUID
// is not available
try
{
BluetoothSocket socket = remoteDevice
.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
return socket;
}
catch(IOException ex)
{
throw new IOException("no listening server socket",ex);
}
}
我使用 BluetoothDevice.getUuids()
在我的 Android 设备之一上获取可用的 UUID。它给了我这个列表:
0000110a-0000-1000-8000-00805f9b34fb - Advanced Audio Distribution Profile (0x110a)
00001105-0000-1000-8000-00805f9b34fb - Object Push Profile (0x1105) // least invasive one...it seems
00001115-0000-1000-8000-00805f9b34fb - Personal Area Networking Profile (0x1115)
0000112f-0000-1000-8000-00805f9b34fb - Phonebook Access (0x112f) // this works!
00001112-0000-1000-8000-00805f9b34fb - Headset - Audio Gateway (0x1112)
0000111f-0000-1000-8000-00805f9b34fb - Handsfree Audio Gateway (0x111f)
00001132-0000-1000-8000-00805f9b34fb - Message Access Profile (0x1132) // this works too!
00000000-0000-1000-8000-00805f9b34fb - Base UUID (0x0000) // couldn't get this to work :(
问题
我如何区分无法与远程 Android 设备建立蓝牙连接,因为:
- 场景 1:远程设备超出范围,或者其蓝牙被禁用。
- 场景2:远程设备在范围内,但远程设备上没有服务器套接字来接受我的连接。
我试过的
我无法区分连接时抛出的异常,因为它在两种情况下抛出相同的异常:
java.io.IOException: read failed, socket might closed or timeout, read ret -1
我无法使用
fetchUuidsWithSdp()
检查远程设备是否支持我的 UUID,因为它在任何一种情况下的行为方式都相同。 .according to the documentation:This API is asynchronous and {@link #ACTION_UUID} intent is sent, with the UUIDs supported by the remote end. If there is an error in getting the SDP records or if the process takes a long time, {@link #ACTION_UUID} intent is sent with the UUIDs that is currently present in the cache...
根据 this SO thread,它的行为似乎也有点不可预测。
最后,我不想使用
sdpSearch
来区分两者,因为那是在API中添加的23,我希望能撑到API 19.
您可以通过尝试连接到通常在 Android 设备上可用的标准 UUID 来确定设备是否在范围内。如果呼叫连接:
- 失败,则远程设备超出范围或蓝牙被禁用。
- 成功,则远程设备在范围内,您应该关闭连接,然后尝试连接到您应用的 UUID...如果失败,则没有侦听套接字...如果成功,则一切都很好。
示例代码:
public BluetoothSocket connect(BluetoothDevice remoteDevice) throws IOException
{
OPP_UUID = UUID.fromString("00001105-0000-1000-8000-00805f9b34fb");
// check if remote device is in range...throw exception if out of range
try
{
BluetoothSocket socket = remoteDevice
.createRfcommSocketToServiceRecord(OPP_UUID);
socket.connect();
socket.close();
}
catch(IOException ex)
{
throw new IOException("out of range",ex);
}
// try to connect to service on remote device...throw exception if UUID
// is not available
try
{
BluetoothSocket socket = remoteDevice
.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
return socket;
}
catch(IOException ex)
{
throw new IOException("no listening server socket",ex);
}
}
我使用 BluetoothDevice.getUuids()
在我的 Android 设备之一上获取可用的 UUID。它给了我这个列表:
0000110a-0000-1000-8000-00805f9b34fb - Advanced Audio Distribution Profile (0x110a)
00001105-0000-1000-8000-00805f9b34fb - Object Push Profile (0x1105) // least invasive one...it seems
00001115-0000-1000-8000-00805f9b34fb - Personal Area Networking Profile (0x1115)
0000112f-0000-1000-8000-00805f9b34fb - Phonebook Access (0x112f) // this works!
00001112-0000-1000-8000-00805f9b34fb - Headset - Audio Gateway (0x1112)
0000111f-0000-1000-8000-00805f9b34fb - Handsfree Audio Gateway (0x111f)
00001132-0000-1000-8000-00805f9b34fb - Message Access Profile (0x1132) // this works too!
00000000-0000-1000-8000-00805f9b34fb - Base UUID (0x0000) // couldn't get this to work :(