![](/img/trans.png)
[英]In Android's bluetooth, does BluetoothSocket.connect invoke SDP to get fresh channel
[英]BluetoothSocket.connect() fails on Samsung S9 with Android 9
我正在开发一个本机Android应用程序,该应用程序需要与蓝牙设备配对。
装有Android 9的Samsung S9的用户报告说,他们的手机无法与没有配备蓝牙的设备配对,经过长时间的研究,我要求进行测试。他们是对的,它可以在除装有Android 9的Samsung 9之外的所有设备上使用。
这是我的代码
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;
}
}
我想问题出在套接字实例创建上。
我也尝试过...
sock = device.createRfcommSocketToServiceRecord(MY_UUID);
与...
Method m = device.getClass().getMethod("createRfcommSocket", int.class);
sock = (BluetoothSocket) m.invoke(device, 1);
但是一切正常,这是一些日志:
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
任何想法?
非常感谢。
毛
终于找到了解决方案。 可能有人会用类似的代码(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;
}
isAroundSamsungS9()在哪里...
private boolean isWorkAroundSamsungS9() {
return Build.MANUFACTURER.toLowerCase().contains("samsung") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
}
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);
}
似乎使initLocalConnectionS9()同步并在线程localConnect中添加大多数代码已解决了该问题。
干杯!
毛
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.