Ich muss einige Daten von meiner Android App über Bluetooth (zu Arduino) übertragen. Ich lese/empfange nichts von Arduino zurück. Für meine Single-Thread-Bedürfnisse ging ich mit einem IntentService. Nach dem Pairing funktioniert mein Code zum ersten Mal, wenn ich Daten anschließe und sende. Ich trenne nach dem Senden von Daten ohne Fehler. Aber wenn ich versuche weiter, um das zweite Mal zu verbinden, ich die folgende Fehlermeldung erhalten, wenn ich versuche myBluetoothSocket.connect():Bluetooth Verbindungsprobleme mit IntentService
Lese fehlgeschlagen ist, Socket geschlossen oder Timeout könnte, lesen Sie ret: -1
Einzige Lösung ist, das Arduino-Gerät auszuschalten und die Verbindung wiederherzustellen (es hilft nicht, wenn ich zwinge, die App zu stoppen und eine erneute Verbindung herzustellen).
Beachten Sie, dass alles funktioniert, wenn ich 2 Threads spawnen (eines zum Lesen und Schreiben) unabhängig davon, wie oft ich verbinde und Daten sende (dadurch beweist, dass auf der Arduino-Seite nichts falsch ist, ein altes "zurückhalten") Verbindung).
Hier mein Android-Code ist:
import android.app.IntentService;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.Context;
import android.os.Build;
import android.os.ParcelUuid;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.UUID;
public class DataTransmissionService extends IntentService {
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final String TAG = "DataTransmissionService";
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private BluetoothDevice device = null;
public DataTransmissionService() {
super("DataTransmissionService");
}
@Override
protected void onHandleIntent(Intent intent) {
cleanup();
if (intent != null){
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDeviceAddress = "already_paired_device_mac_addr";
try {
log.d(TAG, pairedDeviceAddress);
device = btAdapter.getRemoteDevice(pairedDeviceAddress);
log.d(TAG, "Device bond state : " + device.getBondState());
} catch (Exception e) {
log.e(TAG, "Invalid address: " + e.getMessage());
return;
}
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
log.e(TAG, "Socket creation failed: " + e.getMessage());
return;
}
try {
if (!btSocket.isConnected()) {
btSocket.connect();
log.d(TAG, "Connected");
} else {
log.d(TAG, "Already Connected"); //flow never reaches here for any use case
}
} catch (IOException e) {
log.e(TAG, "btSocket.connect() failed : " + e.getMessage());
return;
}
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
log.e(TAG, "Failed to get output stream:" + e.getMessage());
return;
}
sendData("test");
//cleanup(); called in onDestroy()
}
}
@Override
public void onDestroy(){
cleanup();
//notify ui
super.onDestroy();
}
private void cleanup(){
try {
if (outStream != null) {
outStream.close();
outStream = null;
}
} catch (Exception e) {
log.e(TAG, "Failed to close output stream : " + e.getMessage());
}
try {
if (btSocket != null) {
btSocket.close();
btSocket = null;
}
}catch (Exception e) {
log.e(TAG, "Failed to close connection : " + e.getMessage());
}
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
/*if(Build.VERSION.SDK_INT >= 10){
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
return (BluetoothSocket) m.invoke(device, MY_UUID);
} catch (Exception e) {
log.e(TAG, "Could not create Insecure RFComm Connection",e);
}
}*/
return device.createRfcommSocketToServiceRecord(MY_UUID);
}
private void sendData(String message) {
byte[] msgBuffer = message.getBytes();
log.d(TAG, "Sending : " + message);
try {
outStream.write(msgBuffer);
} catch (IOException e) {
log.e(TAG, "failed to write " + message);
}
}
}
ich auf Nexus 5 und Samsung S5 Geräte getestet (Lauf 5.1 und 5.0 beziehungsweise).
Ich habe das Gefühl, Ihr Problem liegt eine 'IntentService' eher als ein normales' Service' und/oder kundenspezifische 'Thema bei der Verwendung '. Aus dem 'IntentService'-Dokument: * Der Dienst wird nach Bedarf gestartet, behandelt jede Absicht der Reihe nach mit einem Arbeitsthread und stoppt sich selbst, wenn er keine Arbeit mehr hat. * Dies wird wahrscheinlich Chaos verursachen, wenn Sie versuchen, ein BT zu verwalten Verbindung über Intents. – pathfinderelite
Genau das brauche ich. Verbinden, Daten senden und Verbindung beenden. Die nächste Verbindung würde wahrscheinlich nach sehr langer Zeit stattfinden und einen neuen Dienst hervorbringen. Die Pflege von Threads scheint für einen einfachen Anwendungsfall wie diesen umständlich zu sein. Dies gewährleistet auch automatisch die Behandlung von jeweils einem Gerät (Teil meines Anwendungsfalls). – SlowAndSteady
Was Sie über das Arduino nicht "zurückhalten" sagen, scheint die Verbindung vernünftig, aber die Tatsache, dass Sie den Arduino aus- und wieder einschalten müssen, um sich wieder verbinden zu können, lässt mich wundern. Vielleicht geht der Arduino irgendwie in einen anderen Zustand, wenn Sie auf demselben Thread lesen und schreiben? (Ich weiß, klingt seltsam.) Was passiert, wenn Sie mit einem Telefon mit dem Arduino verbinden, trennen, dann versuchen, mit dem zweiten Telefon zu verbinden? Haben Sie auch eine Möglichkeit, den Status des Arduino Bluetooth-Modems zu sehen, um zu sehen, ob es irgendwie anders ist, nachdem Sie das erste Mal trennen, im Vergleich zu vorher? – hBrent