Comment obtenir un InputStream via bluetooth et le mettre dans un Textview?

C'est ma première question. Je suis nouveau (et passionnant) dans la programmation Android et voici mon PROBLÈME: je suis en construction d'un projet à l'aide de mon téléphone android et un microcontrôleur. Le microcontrôleur dispose d'un capteur de distance et transmet sa valeur. J'ai réussi à obtenir connecté au microcontrôleur et d'envoyer des signaux corrects, mais je ne peux pas obtenir la distance mesurment, ou quoi que ce soit d'autre. L'application ne plante pas ou quoi que ce soit il ne comprend pas les données du microcontrôleur (mon ordinateur reçoit les données du microcontrôleur (données est une chaîne)). Mon code à partir de l'application android est ceci:

public class Accéléromètre s'étend de l'Activité {

//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) {
}
}
}

}

J'ai tout lu sur le sujet (BluetoothChat, les projets de personnes sur l'internet ...) et je suis très fatigué. Toute aide est très appréciée.

--EDIT--

J'ai réussi à obtenir l'inputstream dans mon texteview. Mon problème maintenant c'est que mon application quand il tente de se connecter à mon appareil (microcontrôleur ou mon pc) coincée dans la progressdialog (il est connecté à l'appareil, mais les progressdialog ne va pas disparaître)et attend quelque chose à venir. Après un certain temps (comme 5-6 secondes), même si quelque chose arrive, reste coincé et je dois forcer la fermeture. Je pense que le problème est dans la façon dont le gestionnaire gère le fil. Dans le débogueur, il n'y a pas de problème, tous les threads s'exécutent sur ok.

Les changements dans mon code:
Dans mon ConnectThread:
`/** Filet utilisé pour se connecter à un Périphérique Bluetooth */
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);
}
}
}

`
Et dans mon mHandler dans ma méthode onCreate:

 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();
}
}
};

Une autre chose que j'ai besoin est de savoir comment vider la mémoire tampon, quand il est plein.

PS: Merci tout le monde pour son aide, je suis vraiment reconnaissante.

Avez vous franchi le code avec un débogueur? Ce serait la voie à suivre pour voir jusqu'où tout fonctionne comme il faut et là où les choses commencent à aller mal. Je devrait vous aider à identifier le problème, qui va nous aider à mieux vous aider. Aussi, juste une recommandation: ne pas attraper-et-oublier exceptions, en particulier dans la phase de développement, vous aurez envie de savoir à propos de ceux-ci. Droit maintenant, votre code peut être en défaut à plusieurs endroits sans vous jamais savoir à ce sujet, qui peut très bien être la raison pour laquelle vous êtes actuellement bloqué.
Je vous remercie pour votre réponse. Je sais que mon code fonctionne comme il se doit (quand il s'agit de l'envoi de la microcOut octet). Pour envoyer l'octet je n'ai pas besoin de la dernière classe ConnectedThread et le deuxième gestionnaire d'h. Ceux qui ont été ajoutés à mon code à partir de ce que j'ai trouvé sur Internet. Vous avez besoin de la DeviceList aussi pour m'aider? Merci encore.
Encore une fois, vous aurez envie de parcourir votre code avec un débogueur, en particulier pour les run() méthode à l'intérieur de votre ConnectedThread. Vérifier si bytes = mmInStream.read(buffer) jamais renvoie raisonnable de la valeur (et si il est touché à tout!). Il n'est pas rare qu'une exception est levée, ce qui vous rattraper et puis sortir de la boucle. Au moins imprimer les exceptions que vous attraper plutôt que de les ignorer, de sorte que vous savez ce qui pourrait aller mal où. Une fois que vous avez cette information, nous pouvons être en mesure de mieux vous aider.

OriginalL'auteur user2149122 | 2013-03-14