Şu anda Android 4.3 ile Nexus 7 (2012) cihazımda bir BluetoothSocket açarken garip bir İstisna ile başa çıkmaya çalışıyorum (Derleme JWR66Y, sanırım ikinci 4.3 güncellemesi). Bazı ilgili gönderiler gördüm (ör. Https://stackoverflow.com/questions/13648373/bluetoothsocket-connect-throwing-exception-read-failed ), ancak hiçbiri bu sorun için bir çözüm sağlamıyor gibi görünüyor. Ayrıca, bu konu başlıklarında önerildiği gibi, yeniden eşleştirme yardımcı olmuyor ve sürekli bağlanmaya çalışmanın (aptal bir döngü aracılığıyla) da hiçbir etkisi yok.
Gömülü bir cihazla uğraşıyorum ( http://images04.olx.com/ui/15/53/76/1316534072_254254776_2-OBD-II-BLUTOOTH-ADAPTERSCLEAR-CHECK-ENGINE- benzeri, isimsiz bir OBD-II araç adaptörü TELEFONUNUZLA-IŞIKLARI-Oceanside.jpg ). Android 2.3.7 telefonumun bağlantı sorunu yok ve bir iş arkadaşımın Xperia'sı (Android 4.1.2) da çalışıyor. Başka bir Google Nexus ("Bir" mi yoksa "S" mi bilmiyorum ama "4" değil) Android 4.3 ile başarısız oluyor.
İşte bağlantı kuruluşunun Parçacığı. Bir Hizmet içinde oluşturulan kendi İş Parçacığı içinde çalışır.
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;
}
}
Kod başarısız oluyor bluetoothSocket.connect()
. Bir alıyorum java.io.IOException: read failed, socket might closed, read ret: -1
. Bu, GitHub'daki ilgili kaynaktır: https://github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetooth/BluetoothSocket.java#L504
Onun çağrılabilir readInt () aracılığıyla denilen https : //github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetooth/BluetoothSocket.java#L319
Kullanılan soketin bazı meta veri dökümü aşağıdaki bilgilerle sonuçlandı. Bunlar Nexus 7 ve 2.3.7 telefonumda tamamen aynı.
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
Başka OBD-II adaptörüm var (daha geniş kapsamlı) ve hepsi çalışıyor. Bir şeyi kaçırma şansım var mı yoksa bu Android'de bir hata olabilir mi?