问题描述
I have the following setup:
An Android device uses a 'Client' socket to connect to a remote embedded device, The Android application uses the following code snippet to connect to the embedded device.
On the embedded device uses MindTree BT stack, where server serial socket is prepared according to some properties in the device, which the Android application is familiar with, the connection defined on the embedded device, is not secured!!
The combination of both applications works on:
- 2 LG phones different models (version code < 10 uses the "Normal method")
- 2 HTC's different models (version code < 10 uses the "Workaround method")
- Pantech Tablet (version code < 13 uses the "Workaround method")
Today, I've tried the application on Samsung S3, Motorola MB886, and a Nexus 7... All resulted in a "Permission Denied" when calling to socket.connect()... (I have the proper permissions in the manifest, otherwise it would not work on the other devices.)
All the new devices I've tested on are version code > 4.0, so I'm wondering:
Does anyone know about any changes in the API? Perhaps Android 4.0+ forces security?
It seem that the error occur in the Bonding state, since I can see on the embedded program logs...
Any insights?
The code:
public final synchronized int connectToDevice(int connectingMethod)
throws BluetoohConnectionException {
if (socket != null)
throw new BadImplementationException("Error socket is not null!!");
connecting = true;
logInfo("+---+ Connecting to device...");
try {
lastException = null;
lastPacket = null;
if (connectingMethod == BluetoothModule.BT_StandardConnection
|| connectingMethod == BluetoothModule.BT_ConnectionTBD)
try {
socket = fetchBT_Socket_Normal();
connectToSocket(socket);
listenForIncomingSPP_Packets();
onConnetionEstablished();
return BluetoothModule.BT_StandardConnection;
} catch (BluetoohConnectionException e) {
socket = null;
if (connectingMethod == BluetoothModule.BT_StandardConnection) {
throw e;
}
logWarning("Error creating socket!", e);
}
if (connectingMethod == BluetoothModule.BT_ReflectiveConnection
|| connectingMethod == BluetoothModule.BT_ConnectionTBD)
try {
socket = fetchBT_Socket_Reflection(1);
connectToSocket(socket);
listenForIncomingSPP_Packets();
onConnetionEstablished();
return BluetoothModule.BT_ReflectiveConnection;
} catch (BluetoohConnectionException e) {
socket = null;
if (connectingMethod == BluetoothModule.BT_ReflectiveConnection) {
throw e;
}
logWarning("Error creating socket!", e);
}
throw new BluetoohConnectionException("Error creating RFcomm socket for BT Device:" + this
+ "
BAD connectingMethod==" + connectingMethod);
} finally {
connecting = false;
}
}
protected void onConnetionEstablished() {
logInfo("+---+ Connection established");
}
private synchronized void listenForIncomingSPP_Packets() {
if (socketListeningThread != null)
throw new BadImplementationException("Already lisening on Socket for BT Device" + this);
logInfo("+---+ Listening for incoming packets");
socketListeningThread = new Thread(socketListener, "Packet Listener - " + bluetoothDevice.getName());
socketListeningThread.start();
}
private BluetoothSocket fetchBT_Socket_Normal()
throws BluetoohConnectionException {
try {
logInfo("+---+ Fetching BT RFcomm Socket standard for UUID: " + uuid + "...");
return bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
} catch (Exception e) {
throw new BluetoohConnectionException("Error Fetching BT RFcomm Socket!", e);
}
}
private BluetoothSocket fetchBT_Socket_Reflection(int connectionIndex)
throws BluetoohConnectionException {
Method m;
try {
logInfo("+---+ Fetching BT RFcomm Socket workaround index " + connectionIndex + "...");
m = bluetoothDevice.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
return (BluetoothSocket) m.invoke(bluetoothDevice, connectionIndex);
} catch (Exception e) {
throw new BluetoohConnectionException("Error Fetching BT RFcomm Socket!", e);
}
}
private void connectToSocket(BluetoothSocket socket)
throws BluetoohConnectionException {
try {
logInfo("+---+ Connecting to socket...");
socket.connect();
logInfo("+---+ Connected to socket");
} catch (IOException e) {
try {
socket.close();
} catch (IOException e1) {
logError("Error while closing socket", e1);
} finally {
socket = null;
}
throw new BluetoohConnectionException("Error connecting to socket with Device" + this, e);
}
}
After very long long time of investigating the matter I've found one reason for the error... on some Android devices the auto Bluetooth peering is not enabled/allowed.
So, apparently except for two connection method, there are also two Bluetooth adapter enabling method, one would be to throw an intent to ask the system to turn the adapter on, and the other is to call onto the BluetoothAdapter.enable() method, which enables the Bluetooth silently.
The first method, pops a confirmation dialog, and require user interaction while the other does not, and while not showing the Bluetooth enabling confirmation dialog, also the peering confirmation is not shown, which causes the connection error.
Using the first adapter enabling method solves the problem on most of the devices, like the Nexus 7, Samsung S3, and a few others, but on some devices there is still an issue, and I'm not really sure why, but this is much better since many devices are now working with the new implementation.
这篇关于Android 4.0+ 与嵌入式设备的蓝牙连接错误:“Permission Denied"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!