Ho un progetto che si collega a un dispositivo tramite Bluetooth. Funzionava in modo abbastanza affidabile, ma ora fallisce la chiamata BluetoothSocket.connect()
ogni volta. (Beh, ho avuto modo di connetterti una volta durante le migliaia di tentativi per un periodo di 4 ore.) La maggior parte del codice è stata presa dal codice di esempio standard di chat nell'API, ad eccezione della modifica comune nell'ottenere il dispositivo BluetoothSocket
stessa:BluetoothSocket.connect() eccezione di lancio "lettura non riuscita"
Method m = device.getClass().getMethod(
"createRfcommSocket", new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
Ecco il metodo di interesse, che viene eseguito una volta al BluetoothSocket
si ottiene:
public void run() {
setName("ConnectThread" + mSocketType);
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
mmSocket.connect();
} catch (Exception e) {
Log.e(TAG, "Connection to " + mmDevice.getName() + " at "
+ mmDevice.getAddress() + " failed:" + e.getMessage());
// Close the socket
try {
mmSocket.close();
} catch (Exception e2) {
Log.e(TAG, "unable to close() " + mSocketType
+ " socket during connection failure", e2);
}
connectionFailed(e.getMessage());
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothChatService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType);
}
la voce del registro in questione (stampato quando l'eccezione e 'colto durante la chiamata connect()
) è questa:
11-30 10: 23: 51,685: E/BluetoothChatService (2870): Connessione a ZYNO-700091 a 00: 06: 66: 42: 8E: 01 non riuscito: lettura non riuscita, socket chiuso, lettura ret: -1
Questo errore si verificava una volta ogni tanto. Ho un sistema di ricollegamento aggressivo - fondamentalmente martella la connessione più e più volte fino a quando non si connette, e se dovesse mai disconnettere, inizia a martellare di nuovo. Quindi, uccide il thread di connessione e inizia da zero costantemente. Avevo considerato che ci potrebbe essere un problema lì - forse un multithreading, o forse nel gestire la pulizia del socket/inizializzazione. Tuttavia, se così fosse, mi aspetterei comunque che il primo tentativo di connessione abbia esito positivo, dal momento che quel sistema non entra in azione finché non si verifica un tentativo di connessione fallito.
Ho esaminato l'eccezione source code. Il problema sembra essere che il sottostante InputStream
non ha dati. Certo, non è davvero una risposta, solo un passo avanti. Perché lo stream non ha dati?
Sto cercando di mantenere una mente aperta sul potenziale problema. Sto ricevendo correttamente il BluetoothSocket
? Il fatto che fosse una volta un problema intermittente ed è ora quasi costante mi fa sospettare il multithreading, ma questo è un argomento relativamente semplice in Java rispetto al C++ - difficile da rovinare se sai cosa stai facendo. Inoltre, la maggior parte di questo codice (in particolare, le parti che trattano la sincronizzazione dei thread) è direttamente fuori dal codice di esempio.
Il dispositivo all'altra estremità è un dispositivo Bluetooth incorporato, quindi non c'è molta speranza di eseguire il debug del problema da quella parte.
UPDATE ===========================
mi venne in mente che potrebbe essere a causa di un aggiornamento del sistema operativo (Sono in esecuzione sui telefoni Galaxy Nexus: ne ho diversi da testare). Così ho spacchettato un nuovo telefono con 4.0.4 e ha funzionato! Quindi sono tornati e testati sui due telefoni di prova originali, entrambi in esecuzione 4.2, aspettando il fallimento che ho visto in tutto questo tempo. Stranamente, ora funziona anche su quei telefoni. Mi piacerebbe dire che ho fatto qualcosa per farlo funzionare di nuovo, ma non l'ho fatto. Sono ancora confuso e ora anche diffidente che questa cosa funzionerà quando ne avrò davvero bisogno.
Mi chiedo se ci sia una possibilità che in qualche modo la connessione usando 4.0.4 possa avere impostato correttamente lo stato del modulo server, rendendolo ricettivo ai dispositivi 4.2? Solo uno sparo nel buio, suppongo ...
UPDATE 2 ===========================
ho trovato che disaccoppiare e ri-accoppiamento consentirà al dispositivi da connettere. È una soluzione, ma è meglio di niente.
Ho lo stesso problema, ho un codice per la stampa via bluetooth con una stampante APEX4 Datamax o'neil. Funziona bene su un Galaxy Tab 7 plus con Honeycomb 3.2. Ma in altri dispositivi con ICS o superiore, non funzionano. Sto confrontando l'oggetto BluetoothSocket e sono molto diversi. Sei sicuro di non aver aggiunto alcun codice? – ClarkXP
Jellybean ha uno stack Bluetooth completamente diverso, quindi le differenze di versione potrebbero certamente innescare qualcosa, ma questo di per sé non spiegherebbe perché rimane funzionante o non funzionante dopo la connessione con un dispositivo precedente. Potrebbe essere fare con l'accoppiamento? Se succede di nuovo, prova ad annullare l'accoppiamento dal dispositivo e ad accoppiare di nuovo, e guarda cosa succede. –
@DanHulme Penso che tu abbia ragione, è il diverso stack Bluetooth che lo sta causando. Ho fatto alcuni test con 4.1, e funziona bene lì. Se vuoi scrivere questo come risposta, sarei felice di accettarlo. –