ขณะนี้ฉันกำลังพยายามจัดการกับข้อยกเว้นแปลก ๆ เมื่อเปิด BluetoothSocket บน Nexus 7 (2012) ด้วย Android 4.3 (สร้าง JWR66Y ฉันเดาว่าอัปเดต 4.3 ครั้งที่สอง) ฉันได้เห็นโพสต์ที่เกี่ยวข้องบางรายการ (เช่น/programming/13648373/bluetoothsocket-connect-throwing-exception-read-failed ) แต่ดูเหมือนจะไม่มีวิธีแก้ปัญหาสำหรับปัญหานี้ ตามที่แนะนำในเธรดเหล่านี้การจับคู่ใหม่ไม่ได้ช่วยอะไรและการพยายามเชื่อมต่อตลอดเวลา (ผ่านการวนซ้ำโง่ ๆ ) ก็ไม่มีผลเช่นกัน
ฉันกำลังจัดการกับอุปกรณ์ฝังตัว (อะแดปเตอร์ในรถยนต์ที่ไม่ใช่ชื่อ OBD-II คล้ายกับhttp://images04.olx.com/ui/15/53/76/1316534072_254254776_2-OBD-II-BLUTOOTH-ADAPTERSCLEAR-CHECK-ENGINE- ไฟพร้อมโทรศัพท์ของคุณ -Oceanside.jpg ) โทรศัพท์ Android 2.3.7 ของฉันไม่มีปัญหาในการเชื่อมต่อและ Xperia ของเพื่อนร่วมงาน (Android 4.1.2) ก็ใช้งานได้เช่นกัน Google Nexus อีกเครื่อง (ฉันไม่รู้ว่า 'One' หรือ 'S' แต่ไม่ใช่ '4') ก็ล้มเหลวด้วย Android 4.3
นี่คือตัวอย่างของการสร้างการเชื่อมต่อ กำลังทำงานในเธรดของตัวเองซึ่งสร้างขึ้นภายในบริการ
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;
}
}
bluetoothSocket.connect()
รหัสเป็นความล้มเหลวที่ ฉันได้รับjava.io.IOException: read failed, socket might closed, read ret: -1
. นี่คือแหล่งที่มาที่สอดคล้องกันใน GitHub: https://github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetooth/BluetoothSocket.java#L504
ซึ่งเรียกว่าผ่าน readInt () เรียกจากhttps : //github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetooth/BluetoothSocket.java#L319
การถ่ายโอนข้อมูลเมตาบางส่วนของซ็อกเก็ตที่ใช้แล้วส่งผลให้เกิดข้อมูลต่อไปนี้ สิ่งเหล่านี้เหมือนกันทุกประการใน Nexus 7 และโทรศัพท์ 2.3.7 ของฉัน
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
ฉันมีอะแดปเตอร์ OBD-II อื่น ๆ (ขยายได้มากขึ้น) และใช้งานได้ทั้งหมด มีโอกาสไหมที่ฉันทำบางอย่างหายไปหรืออาจเป็นข้อบกพร่องใน Android