Bluetooth im Projekt richtig einbingen...

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Bluetooth im Projekt richtig einbingen...

    Hallo Leute,

    ich bin gerade dabei meine ersten "richtige" App zu schreiben.
    Als Anfänger habe ich mit Hilfe von vielen Beispielen etc. meine App zusammengebastelt dass sie läuft.
    Auch die Kommunikation mit Bluetooth habe ich schon hinbekommen, aber bin mir hier nicht sicher ob das alles so richtig ist.

    Zudem habe ich nun versucht auf Orientierungswechsel des Tablets zu reagieren Aber da stürtzt meine App ab wenn ich den
    Empfang der Daten neu starten möchte.



    Die Frag ist jetzt wie binde ich das gane "Bluetooth-Zeugs" richtig in die App ein.
    Vor allem wenn ich eine andere Activity (Einstellungsfenster) starte oder
    wenn ich den Bidschirm drehe und meine MainActivity zerstört und wieder gestartet wird.





    Aber vielleicht mal von vorn, was macht die App:

    Die App soll sich sich mit einem Microkontroller über Bluetooth verbinden, und Daten (Strings) an diese sendet und empfängt.

    Im OnCreate prüfe ich ob Bluetooth überhaupt vorhanden, wenn ja dann kommt die Prüfung ob Bluetooth an ist.
    Wenn nicht wird dies gestartet. (Intent turnBTon = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);)

    Wenn Bluetooth erst aktiviert werden muss kommt ja eine Abfrage die dann ein "Callback" aufruft.

    Wenn Bluetooth aktiviert ist, wird die Verbindung aufgebaut
    Hierzu startet im Hintergrund ein AsyncTask der die Bluetoothverbindung herstellt (die Geräte sind schon gekoppelt, es muss also nur verbunden werden)



    Bei erfolgreicher Verbindung, wird ein Listener (Thread?) gestartet, welcher dann die Daten empfängt.
    Das senden von Strings ist auch kein Problem.

    Aber was mache ich nun wenn ich eine andere Activity (Eigenschaften) aufrufe, oder
    wenn ich das Tablet drehe und meine Main-Activity zerstört und wieder neu geladen wird.

    Muss ich dann die Bluetoothverbindung, den Socket und den Stream etc. schließen und später wieder aufbauen?
  • Hallo,

    mittlerweile läuft die App, allerdings bin ich mir nicht sicher ob das alles richtig ist.

    Ich kann gern mein Code auch hier auflisten, wollte aber im 1. Schritt halt erst mal fragen wie die generelle Vorgehensweise sein sollte.

    ich habe es derzeit so gelößt, dass ich im OnCreate die Verbindung aufbaue und den "Listener" starte.
    In OnDestroy wird der "Lister" und die Bluetoothverbindung beendet.

    Die Frage wäre halt, wenn nun das Tablet gedreht wird, und sich "nur" die Orientierung ändert, muss dann die Verbindung und der Listener beendet werden?

    Also hier mal der Code, der mit Bluetooth zusammenhängt.
    (aus vielen Beispielen zusammengetragen)

    OnCreate:

    Java-Quellcode

    1. myBluetooth = BluetoothAdapter.getDefaultAdapter();
    2. if(myBluetooth == null)
    3. {
    4. msg("Bluetooth Device Not Available");
    5. } else if (!myBluetooth.isEnabled()) {
    6. classCarrera.isBtOn=false;
    7. Intent turnBTon = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    8. startActivityForResult(turnBTon, requCodeBluetooth);
    9. } else {
    10. if(!classCarrera.isOrientationChanging){
    11. classCarrera.isBtOn=true;
    12. }
    13. if(!classCarrera.isBtConnected){ verbinden();}
    14. }
    15. classCarrera.isOrientationChanging=false;
    Alles anzeigen

    Java-Quellcode

    1. protected void onStart()
    2. {
    3. if (!classCarrera.isListening && classCarrera.isBtConnected){beginListenForData();}
    4. if (classCarrera.Menueaufruf && classCarrera.isBtConnected){
    5. classCarrera.Menueaufruf=false;
    6. OptionenSenden();
    7. }
    8. super.onStart();
    9. }

    Java-Quellcode

    1. protected void onDestroy() {
    2. super.onDestroy();
    3. stopWorker=true;
    4. try {
    5. Thread.sleep(500, 0);
    6. }
    7. catch (Exception e){
    8. }
    9. Disconnect();
    10. if (isFinishing()) {
    11. classCarrera.opt.schreiben(this);
    12. if(myBluetooth != null)
    13. {
    14. if (!classCarrera.isBtOn) {
    15. myBluetooth.disable();
    16. }
    17. }
    18. } else {
    19. classCarrera.isOrientationChanging=true;
    20. }
    21. }
    Alles anzeigen

    Wenn der Bluetooth-Adapter nicht aktiviert war, wird in OnCreate ja die Abfrage gestartet ob aktivieren, wenn ja wird dies hier abgefangen.

    Quellcode

    1. public void onActivityResult(int requestCode, int resultCode, Intent data) {
    2. if(resultCode == RESULT_OK){
    3. switch (requestCode) {
    4. case requCodeBluetooth:
    5. verbinden();
    6. break;
    7. ...
    8. }
    9. }
    10. }

    Hier der Aufruf zum Verbinden:

    Java-Quellcode

    1. private void verbinden()
    2. {
    3. pairedDevices = myBluetooth.getBondedDevices();
    4. DeviceFound=false;
    5. if (pairedDevices.size()>0)
    6. {
    7. for(BluetoothDevice bt : pairedDevices)
    8. {
    9. String s=bt.getName();
    10. if (classCarrera.opt.o104_BlueToothName.equals(s)) {
    11. DeviceFound=true;
    12. address=bt.getAddress();
    13. }
    14. }
    15. if (DeviceFound)
    16. {
    17. new ConnectBT().execute(); //Call the class to connect
    18. }
    19. else
    20. {
    21. msg( classCarrera.opt.o104_BlueToothName + " ist nicht gekoppelt");
    22. }
    23. }
    24. else
    25. {
    26. msg("No Paired Bluetooth Devices Found.");
    27. }
    28. }
    Alles anzeigen

    der eigentliche Verbdungsaufruf läuft ja "asyncron" bzw. in einem eigenen "Thread":

    Java-Quellcode

    1. private class ConnectBT extends AsyncTask<Void, Void, Void> // UI thread
    2. {
    3. private boolean ConnectSuccess = true; //if it's here, it's almost connected
    4. @Override
    5. protected void onPreExecute()
    6. {
    7. progress = ProgressDialog.show(LayoutMainActivity.this, "Connecting...", "Please wait!!!"); //show a progress dialog
    8. }
    9. @Override
    10. protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
    11. {
    12. try
    13. {
    14. if (btSocket == null || !classCarrera.isBtConnected)
    15. {
    16. myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
    17. BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
    18. btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
    19. BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
    20. btSocket.connect();//start connection
    21. }
    22. }
    23. catch (Exception e)
    24. {
    25. ConnectSuccess = false;//if the try failed, you can check the exception here
    26. }
    27. return null;
    28. }
    29. @Override
    30. protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
    31. {
    32. super.onPostExecute(result);
    33. if (!ConnectSuccess)
    34. {
    35. msg("Connection Failed.");
    36. btnVerbinden.setBackgroundColor(0xFFF87A7A);
    37. //finish();
    38. }
    39. else
    40. {
    41. msg("Verbunden.");
    42. btnVerbinden.setBackgroundColor(0xFF87F671);
    43. btnVerbinden.setText(R.string.cbVerbunden);
    44. classCarrera.isBtConnected = true;
    45. if (!classCarrera.isListening ){beginListenForData();}
    46. OptionenSenden();
    47. }
    48. progress.dismiss();
    49. }
    50. }
    Alles anzeigen

    Falls Verbindung erfolgreich, wird der Listener aktiviert und einige Optionen gesendet.

    Java-Quellcode

    1. private void OptionenSenden(){
    2. //if (btSocket!=null) {
    3. if (classCarrera.isBtConnected) {
    4. btSenden(getResources().getString(R.string.o1_minGesch_Key) + ";" + Byte.toString(classCarrera.opt.o1_minGeschw));
    5. ...
    6. }
    7. }
    8. private void btSenden(String text)
    9. {
    10. if (btSocket!=null)
    11. {
    12. try
    13. {
    14. String s= text+"\n";
    15. btSocket.getOutputStream().write(s.getBytes());
    16. }
    17. catch (IOException e)
    18. {
    19. msg("Fehler beim Senden" + e.toString());
    20. }
    21. }
    22. }
    Alles anzeigen

    Hier nun der Listener (Verarbeitend der Daten gekürzt)

    Java-Quellcode

    1. private void beginListenForData() {
    2. final Handler handler = new Handler();
    3. final byte delimiter = 10; //This is the ASCII code for a newline character
    4. //private boolean stopWorker=false;
    5. //private int readBufferPosition;
    6. stopWorker = false;
    7. classCarrera.isListening=true;
    8. readBufferPosition = 0;
    9. final byte[] readBuffer = new byte[1024];
    10. Thread workerThread = new Thread(new Runnable() {
    11. public void run() {
    12. if (stopWorker){classCarrera.isListening=false;}
    13. while(!Thread.currentThread().isInterrupted() && !stopWorker) {
    14. try {
    15. int bytesAvailable = btSocket.getInputStream().available();
    16. if(bytesAvailable > 0) {
    17. byte[] packetBytes = new byte[bytesAvailable];
    18. btSocket.getInputStream().read(packetBytes);
    19. for(int i=0;i<bytesAvailable;i++) {
    20. byte b = packetBytes[i];
    21. if(b == delimiter) {
    22. byte[] encodedBytes = new byte[readBufferPosition];
    23. System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
    24. final String data = new String(encodedBytes, "US-ASCII");
    25. readBufferPosition = 0;
    26. handler.post(new Runnable() {
    27. public void run() {
    28. if (data.contains(";"))
    29. {
    30. int i=0;
    31. String[] s = data.substring(0,data.length()-1).split(";");
    32. //........
    33. }
    34. }
    35. });
    36. }else {
    37. readBuffer[readBufferPosition++] = b;
    38. }
    39. }
    40. }
    41. }catch (IOException ex) {
    42. stopWorker = true;
    43. classCarrera.isListening=false;
    44. }
    45. }
    46. }
    47. });
    48. workerThread.start();
    49. }
    Alles anzeigen

    Java-Quellcode

    1. private void Disconnect()
    2. {
    3. if (btSocket!=null)
    4. {
    5. try
    6. {
    7. btSocket.close(); //close connection
    8. classCarrera.isBtConnected=false;
    9. classCarrera.isListening=false;
    10. btnVerbinden.setBackgroundColor(0xFFF87A7A);
    11. btnVerbinden.setText(R.string.cbVerbinden);
    12. }
    13. catch (IOException e)
    14. { msg("Fehler beim Trennen" + e.toString());}
    15. btSocket=null ;
    16. }
    17. }
    Alles anzeigen