Wie kann man einen InputStream über bluetooth und in einem Textview?

Dies ist meine erste Frage in SO. Ich bin neu (und aufgeregt) in Android-Programmierung und hier ist mein PROBLEM: ich Baue ein Projekt mit meinem android-Handy und einem mikrocontroller. Der mikrocontroller hat einen Distanz-sensor und überträgt seinen Wert. Ich habe es geschafft, verbunden mit dem mikrocontroller und senden die richtigen Signale, aber ich kann nicht den Abstand mesurment, oder irgendetwas anderes. Die Anwendung stürzt nicht ab oder alles, was es einfach nicht die Daten vom mikrocontroller (mein Rechner bekommt die Daten von microcontroler (Daten string)). Meinen code aus der android app ist dies:

public class Beschleunigungsmesser erstreckt Aktivität {

//Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
private static final int RECIEVE_MESSAGE = 3;

//Program variables
private byte microcOut;
private boolean ledStat;
private boolean connectStat = false;
private Button btnled;
private Button connect_button;
private TextView yAccel, xAccel, incoming;
protected static final int MOVE_TIME = 80;
private long lastWrite = 0;
OnClickListener myClickListener;
ProgressDialog myProgressDialog;
private Toast failToast;
private Handler mHandler,h;
private StringBuilder sb = new StringBuilder();

//Sensor object used to handle accelerometer
private SensorManager mySensorManager; 
private List<Sensor> sensors; 
private Sensor accSensor;

//Bluetooth Stuff
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null; 
private OutputStream outStream = null;
private InputStream inStream = null;
private ConnectThread mConnectThread = null;
private ConnectedThread mConnectedThread;

private String deviceAddress = null;
//Well known SPP UUID (will *probably* map to RFCOMM channel 1 (default) if not in use); 
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

//Sound Clip to make app prettier
MediaPlayer myclip;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.activity_accelerometer);
    myclip = MediaPlayer.create(this, R.raw.cartcar);
    myclip.start();
     //Finds buttons in .xml layout file
    btnled = (Button) findViewById(R.id.led_button1);
    connect_button = (Button) findViewById(R.id.connect_button1);
    yAccel = (TextView) findViewById(R.id.accText1);
    xAccel = (TextView) findViewById(R.id.accText2);
    incoming = (TextView) findViewById(R.id.incoming);
    //Set Sensor
    mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); 
    sensors = mySensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
    if(sensors.size() > 0) accSensor = sensors.get(0);

    myProgressDialog = new ProgressDialog(this);
    failToast = Toast.makeText(this, R.string.failedToConnect, Toast.LENGTH_SHORT);
    mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
         if (myProgressDialog.isShowing()) {
                myProgressDialog.dismiss();
            }

         //Check if bluetooth connection was made to selected device
            if (msg.what == 1) {
                //Set button to display current status
                connectStat = true;
                connect_button.setText(R.string.connected);

                //Reset the BluCar
                microcOut = 0;
                ledStat = false;
                write(microcOut);
            }else {
                //Connection failed
             failToast.show();
            }
        }
    };


    h = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case RECIEVE_MESSAGE:                                                   //if receive massage
                byte[] readBuf = (byte[]) msg.obj;
                String strIncom = new String(readBuf, 0, msg.arg1);                 //create string from bytes array
                sb.append(strIncom);                                                //append string
                int endOfLineIndex = sb.indexOf("\r\n");                            //determine the end-of-line
                if (endOfLineIndex > 0) {                                            //if end-of-line,
                    String sbprint = sb.substring(0, endOfLineIndex);               //extract string
                    sb.delete(0, sb.length());                                      //and clear
                    incoming.setText("Data from Arduino: " + sbprint);            //update TextView 
                }
                //Log.d(TAG, "...String:"+ sb.toString() +  "Byte:" + msg.arg1 + "...");
                break;
            }
        };
    };
 //Check whether bluetooth adapter exists
    btAdapter = BluetoothAdapter.getDefaultAdapter(); 
    if (btAdapter == null) { 
         Toast.makeText(this, R.string.no_bt_device, Toast.LENGTH_LONG).show(); 
         finish(); 
         return; 
    } 

    //If BT is not on, request that it be enabled.
    if (!btAdapter.isEnabled()) {
        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
    }
    /**********************************************************************
     * Buttons for controlling BluCar
     */
    connect_button.setOnClickListener(new View.OnClickListener() {

        //Connect to Bluetooth Module
        @Override
        public void onClick(View v) {
            if (connectStat) {
                //Attempt to disconnect from the device
                disconnect();
            }else{
                //Attempt to connect to the device
                connect();
            }
        }
    });

    //Toggle Headlights
    btnled.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (ledStat) {
                microcOut = (byte) (microcOut & 124);
                btnled.setText(R.string.ledbuttonON);
                ledStat = false;
            }else{
                microcOut = (byte) (microcOut | 128);
                btnled.setText(R.string.ledbuttonOFF);
                ledStat = true;
            }
            write(microcOut);
        }
    });

}
/** Thread used to connect to a specified Bluetooth Device */
public class ConnectThread extends Thread {
private String address;
private boolean connectionStatus;

    ConnectThread(String MACaddress) {
        address = MACaddress;
        connectionStatus = true;
}

    public void run() {
    //When this returns, it will 'know' about the server, 
       //via it's MAC address. 
        try {
            BluetoothDevice device = btAdapter.getRemoteDevice(address);

            //We need two things before we can successfully connect 
            //(authentication issues aside): a MAC address, which we 
            //already have, and an RFCOMM channel. 
            //Because RFCOMM channels (aka ports) are limited in 
            //number, Android doesn't allow you to use them directly; 
            //instead you request a RFCOMM mapping based on a service 
            //ID. In our case, we will use the well-known SPP Service 
            //ID. This ID is in UUID (GUID to you Microsofties) 
            //format. Given the UUID, Android will handle the 
            //mapping for you. Generally, this will return RFCOMM 1, 
            //but not always; it depends what other BlueTooth services 
            //are in use on your Android device. 
            try { 
                 btSocket = device.createRfcommSocketToServiceRecord(SPP_UUID); 
            } catch (IOException e) { 
                connectionStatus = false;
            } 
        }catch (IllegalArgumentException e) {
            connectionStatus = false;
        }

       //Discovery may be going on, e.g., if you're running a 
       //'scan for devices' search from your handset's Bluetooth 
       //settings, so we call cancelDiscovery(). It doesn't hurt 
       //to call it, but it might hurt not to... discovery is a 
       //heavyweight process; you don't want it in progress when 
       //a connection attempt is made. 
       btAdapter.cancelDiscovery(); 

       //Blocking connect, for a simple client nothing else can 
       //happen until a successful connection is made, so we 
       //don't care if it blocks. 
       try {
            btSocket.connect(); 
       } catch (IOException e1) {
            try {
                 btSocket.close(); 
            } catch (IOException e2) {
            }
       }

       //Create a data stream so we can talk to server. 
       try { 
        outStream = btSocket.getOutputStream(); 
       } catch (IOException e2) {
        connectionStatus = false;
       }

       //Send final result
       if (connectionStatus) {
        mHandler.sendEmptyMessage(1);
       }else {
        mHandler.sendEmptyMessage(0);
       }
    }
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
     switch (requestCode) {
       case REQUEST_CONNECT_DEVICE:
         //When DeviceListActivity returns with a device to connect
           if (resultCode == Activity.RESULT_OK) {
            //Show please wait dialog
            myProgressDialog = ProgressDialog.show(this, getResources().getString(R.string.pleaseWait), getResources().getString(R.string.makingConnectionString), true);

            //Get the device MAC address
            deviceAddress = data.getExtras().getString(DeviceList.EXTRA_DEVICE_ADDRESS);
            //Connect to device with specified MAC address
              mConnectThread = new ConnectThread(deviceAddress);
              mConnectThread.start();

           }else {
             //Failure retrieving MAC address
             Toast.makeText(this, R.string.macFailed, Toast.LENGTH_SHORT).show();
           }
           break;
       case REQUEST_ENABLE_BT:
           //When the request to enable Bluetooth returns
           if (resultCode == Activity.RESULT_OK) {
               //Bluetooth is now enabled
           } else {
               //User did not enable Bluetooth or an error occured
               Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
               finish();
           }
        }
   }

public void write(byte data) {
     if (outStream != null) {
          try {
             outStream.write(data);
          } catch (IOException e) {
          }
      }
  }

  public void emptyOutStream() {
     if (outStream != null) {
          try {
             outStream.flush();
          } catch (IOException e) {
          }
      }
  }

  public void connect() {
     //Launch the DeviceListActivity to see devices and do scan
      Intent serverIntent = new Intent(this, DeviceList.class);
      startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
  }

  public void disconnect() {
     if (outStream != null) {
         try {
                outStream.close();
                connectStat = false;
                connect_button.setText(R.string.disconnected);
            } catch (IOException e) {
            }
     } 
  }
  private final SensorEventListener mSensorListener = new SensorEventListener() {

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {}

        @Override
        public void onSensorChanged(SensorEvent event) {
            //Checks whether to send steering command or not
            long date = System.currentTimeMillis();
            if (date - lastWrite > MOVE_TIME) {
                yAccel.setText(" " + event.values[1]);
                xAccel.setText(" " + event.values[0]);
                if (event.values[1] > 2.5) {
                    //Turn right
                    microcOut = (byte) (microcOut & 248);
                    microcOut = (byte) (microcOut | 4);
                }else if (event.values[1] < -2.5) {
                    //Turn left
                    microcOut = (byte) (microcOut & 244);
                    microcOut = (byte) (microcOut | 8);
                }else {
                    //Center the steering servo
                    microcOut = (byte) (microcOut & 240);
                }
                write(microcOut);
                lastWrite = date;
            }
        }
      };

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    //Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_accelerometer, menu);
    return true;
}
public void onResume() { 
     super.onResume();
     mySensorManager.registerListener(mSensorListener, accSensor, SensorManager.SENSOR_DELAY_GAME);
}
@Override 
public void onDestroy() { 
     emptyOutStream();
     disconnect();
     if (mSensorListener != null) {
         mySensorManager.unregisterListener(mSensorListener);
     }
     super.onDestroy(); 
     myclip.release();
} 
private class ConnectedThread extends Thread {
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        //Get the input and output streams, using temp objects because
        //member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        byte[] buffer = new byte[256];  //buffer store for the stream
        int bytes; //bytes returned from read()

        //Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                //Read from the InputStream
                bytes = mmInStream.read(buffer);        //Get number of bytes and message in "buffer"
                h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget();     //Send to message queue Handler
            } catch (IOException e) {
                break;
            }
        }
    }

    /* Call this from the main activity to send data to the remote device */
    public void write(String message) {

        byte[] msgBuffer = message.getBytes();
        try {
            mmOutStream.write(msgBuffer);
        } catch (IOException e) {

          }
    }
}

}

Ich habe alles gelesen über das Thema (BluetoothChat, Projekte von Menschen über das internet ...) und ich bin sehr müde. Jede Hilfe wird sehr geschätzt.

--EDIT--

Habe ich es geschafft, den inputstream in meine texteview. Mein problem ist jetzt, dass meine Anwendung, wenn es versucht, eine Verbindung zu meinem Gerät (mikrocontroller oder meinem pc) stecken in der progressdialog (es ist an das Gerät angeschlossen, aber der progressdialog wird nicht Weg)und wartet auf etwas zu kommen. Nach einer Weile (wie 5-6 Sek.), selbst wenn etwas kommt, bleibt stecken und ich muss ihn mit Gewalt zu schließen. Ich denke, das problem ist die Art der handler verarbeitet die thread. Im debugger ist es kein problem, alle Gewinde ok.

Die Veränderungen in meinem code sind:
In meinem ConnectThread:
` /* * - Thread verwendet, um eine Verbindung zu einem festgelegten Bluetooth-Gerät */
public class ConnectThread extends Thread {
private String Adresse;
private boolean connectionStatus;

    ConnectThread(String MACaddress) {
        address = MACaddress;
        connectionStatus = true;
}

    public void run() {
    //When this returns, it will 'know' about the server, 
       //via it's MAC address. 
        try {
            BluetoothDevice device = btAdapter.getRemoteDevice(address);

            //We need two things before we can successfully connect 
            //(authentication issues aside): a MAC address, which we 
            //already have, and an RFCOMM channel. 
            //Because RFCOMM channels (aka ports) are limited in 
            //number, Android doesn't allow you to use them directly; 
            //instead you request a RFCOMM mapping based on a service 
            //ID. In our case, we will use the well-known SPP Service 
            //ID. This ID is in UUID (GUID to you Microsofties) 
            //format. Given the UUID, Android will handle the 
            //mapping for you. Generally, this will return RFCOMM 1, 
            //but not always; it depends what other BlueTooth services 
            //are in use on your Android device. 
            try { 
                 btSocket = device.createRfcommSocketToServiceRecord(SPP_UUID); 
            } catch (IOException e) { 
                connectionStatus = false;
            } 
        }catch (IllegalArgumentException e) {
            connectionStatus = false;
        }

       //Discovery may be going on, e.g., if you're running a 
       //'scan for devices' search from your handset's Bluetooth 
       //settings, so we call cancelDiscovery(). It doesn't hurt 
       //to call it, but it might hurt not to... discovery is a 
       //heavyweight process; you don't want it in progress when 
       //a connection attempt is made. 
       btAdapter.cancelDiscovery(); 

       //Blocking connect, for a simple client nothing else can 
       //happen until a successful connection is made, so we 
       //don't care if it blocks. 
       try {
            btSocket.connect(); 
       } catch (IOException e1) {
            try {
                 btSocket.close(); 
            } catch (IOException e2) {
            }
       }

       //Create a data stream so we can talk to server. 
       try { 
            outStream = btSocket.getOutputStream(); 
          } catch (IOException e2) {
            connectionStatus = false;
          }
       try{
        inStream = btSocket.getInputStream();
    }catch (IOException e2){
        connectionStatus = false;
    }
        int bytes; //bytes returned from read()
       //Keep listening to the InputStream until an exception occurs
       while (connectionStatus) {
           try {
               byte[] b = new byte[64];  //buffer store for the stream
               //Read from the InputStream
               bytes = inStream.read(b);        //Get number of bytes and message in "buffer"
               mHandler.obtainMessage(RECIEVE_MESSAGE, bytes, -1, b).sendToTarget();     //Send to message queue Handler
           } catch (IOException e) {
               break;
           }
       }
       //Send final result
       if (connectionStatus) {
        mHandler.obtainMessage(1);
       }else {
        mHandler.sendEmptyMessage(0);
       }
    }
}

`
Und in meinem mHandler in meiner onCreate Methode:

 mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
         if (myProgressDialog.isShowing()) {
                myProgressDialog.dismiss();
            }

         //Check if bluetooth connection was made to selected device
            if (msg.what == 1) {
                //Set button to display current status
                connectStat = true;
                connect_button.setText(R.string.connected);
                //Reset the BluCar
                microcOut = 0;
                ledStat = false;
                write(microcOut);
            }else if (msg.what == 2){
                byte[] readBuf = (byte[]) msg.obj;
                String strIncom = new String(readBuf, 0, msg.arg1);                 //create string from bytes array
                sb.append(strIncom);                                                //append string
                int endOfLineIndex = sb.indexOf(".");                            //determine the end-of-line
                if (endOfLineIndex > 0) {                                            //if end-of-line,
                    String sbprint = sb.substring(0, endOfLineIndex);               //extract string
                    sb.delete(0, sb.length());                                      //and clear
                    incoming.setText(sbprint);            //update TextView
                    connectStat = true;
                    connect_button.setText(R.string.connected);
                }else{
                    incoming.setText("Problem!");
                }
            }else {
                //Connection failed
             failToast.show();
            }
        }
    };

Andere Sache, die ich brauche, ist, wie um den Puffer zu leeren, wenn es voll ist.

PS: vielen Dank an ALLE, die für seine/Ihre Hilfe bin ich wirklich dankbar.

Haben Sie ging durch den code mit einem debugger? Das wäre der Weg zu gehen, um zu sehen, bis wo alles so funktioniert wie es sollte und wo die Dinge anfangen schief zu gehen. Ich soll Ihnen helfen, lokalisieren das Problem, das uns hilft, Ihnen besser helfen können. Auch, nur eine Empfehlung: nicht fangen-und-vergessen-Ausnahmen - vor allem in der Entwicklungsphase, werden Sie wollen, um zu wissen, über diese. Jetzt der code könnte scheitern, an mehreren stellen, ohne dass Sie jemals zu wissen, das sehr gut der Grund sein, warum Sie gerade stecken.
Danke für Eure Antworten. Ich weiß, dass mein code so funktioniert wie es sollte (wenn es um das senden der microcOut byte). Zum senden des byte brauche ich nicht die Letzte Klasse ConnectedThread und das zweite hf. h. Diese wurden Ergänzungen zu meinem code von dem, was ich im Internet gefunden. Sie benötigen die DeviceList auch, um mir zu helfen? Nochmals vielen Dank.
Wieder, Sie wollen Schritt für Schritt durch den code mit einem debugger; vor allem die run() Methode in Ihrem ConnectedThread. Prüfen Sie, ob bytes = mmInStream.read(buffer) immer wieder sinnvoll ist (und ob es getroffen wird!). Es ist nicht unwahrscheinlich, dass eine Ausnahme geworfen wird, die man fangen und dann brechen aus der Schleife. Wenigstens drucken Sie die Ausnahmen, die Sie fangen, anstatt Sie zu ignorieren Sie, damit Sie wissen, was möglicherweise falsch läuft, wo. Sobald Sie über diese Informationen verfügen, können wir Ihnen besser helfen können.

InformationsquelleAutor user2149122 | 2013-03-14

Schreibe einen Kommentar