[英]BluetoothSocket.connect() fails on Samsung S9 with Android 9
I am working on a native Android application that needs to be paired with a bluetooth device. 我正在开发一个本机Android应用程序,该应用程序需要与蓝牙设备配对。
Users with Samsung S9 with Android 9 are reporting that their mobiles does not pair with out bluetooth devices and after doing a long research I requested one to test it, and they are right, it works on every device but Samsung 9 with Android 9. 装有Android 9的Samsung S9的用户报告说,他们的手机无法与没有配备蓝牙的设备配对,经过长时间的研究,我要求进行测试。他们是对的,它可以在除装有Android 9的Samsung 9之外的所有设备上使用。
Here is my code 这是我的代码
try {
if (sock == null) {
final BluetoothDevice device = BT.getRemoteDevice(_btMac);
if (device == null) {
setBluetoothState(BT_DISCONNECTED, false);
return;
}
UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
sock = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
if (sock != null) {
in = sock.getInputStream();
out = sock.getOutputStream();
mBtConnectCounter = 0;
if (localConnect != null) {
if (VersionUtils.isAtLeastNougat()) {
if (localConnect.isAlive()) {
localConnect.interrupt();
}
}
}
localConnect = new Thread() {
public void run() {
try {
BluetoothAdapter bT = BluetoothAdapter.getDefaultAdapter();
if (bT != null) {
if (bT.isEnabled()) {
bT.cancelDiscovery();
Log.d(TAG, "localConnect() INI:sock.connect()");
if (sock != null) {
sock.connect();
Log.d(TAG, "localConnect() END: sock.connect()");
setBluetoothState(BT_CONNECTED, true);
startReadThread();
refreshMainActivity();
}
}
}
} catch (IOException e) {
Log.e(TAG, "localConnect() EXCEPTION: sock.connect() " + e.getMessage());
}
if (!sockedConnected) {
int localCounter = mBtConnectCounter;
int dif = 0;
while ((mBtConnectCounter < 25) && (dif < 3)) {
if (mBtConnectCounter > localCounter)
dif = mBtConnectCounter - localCounter;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
setBluetoothState(BT_DISCONNECTED, false);
}
}
};
threadPoolDevelopers.submit(localConnect);
} else
setBluetoothState(BT_DISCONNECTED, false);
return;
}
} catch (IOException e) {
setBluetoothState(BT_DISCONNECTED, false);
closeSocket();
return;
} catch (final Exception e) {
setBluetoothState(BT_DISCONNECTED, false);
return;
}
}
I suppose that the problem is on the socket instance creation. 我想问题出在套接字实例创建上。
I tried also with... 我也尝试过...
sock = device.createRfcommSocketToServiceRecord(MY_UUID);
and with... 与...
Method m = device.getClass().getMethod("createRfcommSocket", int.class);
sock = (BluetoothSocket) m.invoke(device, 1);
But anything is working, here are some logs: 但是一切正常,这是一些日志:
D/BluetoothAdapter: cancelDiscovery
D/bt_ifac: localConnect() INI: sock.connect()
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
E/bt_ifac: cerrarSocketBluetooth()
D/BluetoothSocket: close() this: android.bluetooth.BluetoothSocket@befe2cd, channel: -1, mSocketIS: android.net.LocalSocketImpl$SocketInputStream@3cc3782, mSocketOS: android.net.LocalSocketImpl$SocketOutputStream@7696e93mSocket: android.net.LocalSocket@470ed0 impl:android.net.LocalSocketImpl@9a4dec9 fd:java.io.FileDescriptor@f8a49ce, mSocketState: INIT
D/BluetoothSocket: close() this: android.bluetooth.BluetoothSocket@befe2cd, channel: -1, mSocketIS: android.net.LocalSocketImpl$SocketInputStream@3cc3782, mSocketOS: android.net.LocalSocketImpl$SocketOutputStream@7696e93mSocket: null, mSocketState: CLOSED
E/bt_ifac: localConnect() EXCEPTION: sock.connect() read failed, socket might closed or timeout, read ret: -1
Any idea? 任何想法?
Thank you so much. 非常感谢。
Mauricio 毛
finally found a solution. 终于找到了解决方案。 Probably someone will have a similar problem with similar code (classic copy paste from Github sample...) so here is my solution. 可能有人会用类似的代码(Github示例中的经典复制粘贴...)遇到类似的问题,所以这是我的解决方案。
try {
if (sock == null) {
if (isWorkAroundSamsungS9()) {
initLocalConnectionS9();
} else {
initLocalConnectionStandard();
}
} else
setBluetoothState(BT_DISCONNECTED, false);
return;
} catch (final IOException e) {
setBluetoothState(BT_DISCONNECTED, false);
closeSocket();
return;
} catch (final Exception e) {
setBluetoothState(BT_DISCONNECTED, false);
return;
}
Where isWorkAroundSamsungS9() is... isAroundSamsungS9()在哪里...
private boolean isWorkAroundSamsungS9() {
return Build.MANUFACTURER.toLowerCase().contains("samsung") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
}
initLocalConnectionStandard() uses the old code and initLocalConnectionS9() has a few changes... initLocalConnectionStandard()使用旧代码, initLocalConnectionS9()进行了一些更改...
private synchronized void initLocalConnectionS9() {
localConnect = new Thread() {
public void run() {
final BluetoothDevice btDevice;
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
int connectionRetries = 0;
while (bluetoothState != BT_CONNECTED && connectionRetries < 3) {
try {
bluetoothState = BT_CONNECTING;
sock = null;
final BluetoothAdapter BT = BluetoothAdapter.getDefaultAdapter();
btDevice = BT.getRemoteDevice(btMac);
final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
sock = btDevice
.createInsecureRfcommSocketToServiceRecord(MY_UUID);
in = sock.getInputStream();
out = sock.getOutputStream();
Log.d(TAG, "localConnect() INI: sock.connect()");
sock.connect();
Log.d(TAG, "localConnect() END: sock.connect()");
setBluetoothState(BT_CONNECTED, true);
startReadThread();
refreshMainActivity();
} catch (final Exception e) {
connectionRetries++;
closeSocket();
bluetoothState = BT_DISCONNECTED;
Log.e(TAG, "localConnect() EXCEPTION: sock.connect()" + e);
if (connectionRetries >= 3) {
setBluetoothState(BT_DISCONNECTED, false);
} else {
Log.d(TAG, "Bluetooth connection retries: " + connectionRetries);
delay(500);
}
}
}
}
};
threadPoolDevelopers.submit(localConnect);
}
Seems that making initLocalConnectionS9() synchronized and adding most of the code in the thread localConnect has solved the problem. 似乎使initLocalConnectionS9()同步并在线程localConnect中添加大多数代码已解决了该问题。
Cheers! 干杯!
Mauricio 毛
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.