Hiện tại, tôi đang cố gắng đối phó với một Ngoại lệ lạ khi mở BluetoothSocket trên Nexus 7 (2012) của tôi, với Android 4.3 (Bản dựng JWR66Y, tôi đoán là bản cập nhật 4.3 thứ hai). Tôi đã thấy một số bài đăng có liên quan (ví dụ: /programming/13648373/bl Bluetoothsocket-connect-throwing-exception-read-failed ), nhưng dường như không có giải pháp nào cung cấp giải pháp cho vấn đề này. Ngoài ra, như được đề xuất trong các chuỗi này, việc ghép nối lại không giúp ích gì và việc liên tục cố gắng kết nối (thông qua một vòng lặp ngu ngốc) cũng không có tác dụng.
Tôi đang xử lý một thiết bị nhúng (bộ điều hợp ô tô noname OBD-II, tương tự như http://images04.olx.com/ui/15/53/76/1316534072_254254776_2-OBD-II-BLUTOOTH-ADAPTORSCLEAR-CHECK-ENGINE- LIGHTS-VỚI-ĐIỆN THOẠI CỦA BẠN-Oceanside.jpg ). Điện thoại Android 2.3.7 của tôi không có bất kỳ sự cố kết nối nào và Xperia của một đồng nghiệp (Android 4.1.2) cũng hoạt động. Một chiếc Nexus khác của Google (tôi không biết liệu 'One' hay 'S', nhưng không phải '4') cũng không thành công với Android 4.3.
Đây là Đoạn mã của thiết lập kết nối. Nó đang chạy trong Thread của chính nó, được tạo trong một Dịch vụ.
private class ConnectThread extends Thread {
private static final UUID EMBEDDED_BOARD_SPP = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
private BluetoothAdapter adapter;
private boolean secure;
private BluetoothDevice device;
private List<UUID> uuidCandidates;
private int candidate;
protected boolean started;
public ConnectThread(BluetoothDevice device, boolean secure) {
logger.info("initiliasing connection to device "+device.getName() +" / "+ device.getAddress());
adapter = BluetoothAdapter.getDefaultAdapter();
this.secure = secure;
this.device = device;
setName("BluetoothConnectThread");
if (!startQueryingForUUIDs()) {
this.uuidCandidates = Collections.singletonList(EMBEDDED_BOARD_SPP);
this.start();
} else{
logger.info("Using UUID discovery mechanism.");
}
/*
* it will start upon the broadcast receive otherwise
*/
}
private boolean startQueryingForUUIDs() {
Class<?> cl = BluetoothDevice.class;
Class<?>[] par = {};
Method fetchUuidsWithSdpMethod;
try {
fetchUuidsWithSdpMethod = cl.getMethod("fetchUuidsWithSdp", par);
} catch (NoSuchMethodException e) {
logger.warn(e.getMessage());
return false;
}
Object[] args = {};
try {
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
BluetoothDevice deviceExtra = intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
Parcelable[] uuidExtra = intent.getParcelableArrayExtra("android.bluetooth.device.extra.UUID");
uuidCandidates = new ArrayList<UUID>();
for (Parcelable uuid : uuidExtra) {
uuidCandidates.add(UUID.fromString(uuid.toString()));
}
synchronized (ConnectThread.this) {
if (!ConnectThread.this.started) {
ConnectThread.this.start();
ConnectThread.this.started = true;
unregisterReceiver(this);
}
}
}
};
registerReceiver(receiver, new IntentFilter("android.bleutooth.device.action.UUID"));
registerReceiver(receiver, new IntentFilter("android.bluetooth.device.action.UUID"));
fetchUuidsWithSdpMethod.invoke(device, args);
} catch (IllegalArgumentException e) {
logger.warn(e.getMessage());
return false;
} catch (IllegalAccessException e) {
logger.warn(e.getMessage());
return false;
} catch (InvocationTargetException e) {
logger.warn(e.getMessage());
return false;
}
return true;
}
public void run() {
boolean success = false;
while (selectSocket()) {
if (bluetoothSocket == null) {
logger.warn("Socket is null! Cancelling!");
deviceDisconnected();
openTroubleshootingActivity(TroubleshootingActivity.BLUETOOTH_EXCEPTION);
}
// Always cancel discovery because it will slow down a connection
adapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
bluetoothSocket.connect();
success = true;
break;
} catch (IOException e) {
// Close the socket
try {
shutdownSocket();
} catch (IOException e2) {
logger.warn(e2.getMessage(), e2);
}
}
}
if (success) {
deviceConnected();
} else {
deviceDisconnected();
openTroubleshootingActivity(TroubleshootingActivity.BLUETOOTH_EXCEPTION);
}
}
private boolean selectSocket() {
if (candidate >= uuidCandidates.size()) {
return false;
}
BluetoothSocket tmp;
UUID uuid = uuidCandidates.get(candidate++);
logger.info("Attempting to connect to SDP "+ uuid);
try {
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(
uuid);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(
uuid);
}
bluetoothSocket = tmp;
return true;
} catch (IOException e) {
logger.warn(e.getMessage() ,e);
}
return false;
}
}
Mã không thành công tại bluetoothSocket.connect()
. Tôi đang nhận được một java.io.IOException: read failed, socket might closed, read ret: -1
. Đây là nguồn tương ứng tại GitHub: https://github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bl
Bluetooth/Bl BluetoothSocket.java#L504 Nó được gọi thông qua readInt (), được gọi từ https : //github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bl Bluetooth/BluetoothSocket.java#L319
Một số kết xuất siêu dữ liệu của ổ cắm đã sử dụng dẫn đến thông tin sau. Chúng hoàn toàn giống nhau trên Nexus 7 và điện thoại 2.3.7 của tôi.
Bluetooth Device 'OBDII'
Address: 11:22:33:DD:EE:FF
Bond state: 12 (bonded)
Type: 1
Class major version: 7936
Class minor version: 7936
Class Contents: 0
Contents: 0
Tôi có một số bộ điều hợp OBD-II khác (mở rộng hơn) và chúng đều hoạt động. Có bất kỳ cơ hội nào mà tôi đang thiếu thứ gì đó hoặc đây có thể là một lỗi trong Android không?