After Bluetooth connection is lost. Bluetooth stack on HTC Legend is
messed up. Nothing works till Bluetooth is turned off and on. Here is
the sample, the problem is blocking read on the thread but
InputStream.available call always returns 0 and cannot be used to
implement some ugly, busy-waiting workaround.

package com.example.android.disconnectproblem;

import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.OutputStream;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

public class MainActivity extends Activity {
        private ArrayAdapter<String> messages = null;
        private BluetoothAdapter adapter = null;
        private BluetoothDevice device = null;
        private BluetoothSocket socket = null;
        private ConnectedThread thread = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        try {
                super.onCreate(savedInstanceState);
                super.setContentView(R.layout.main);
        }
        catch (Throwable throwable) {
        }
    }

    @Override
    public void onStart () {
        try
        {
                super.onStart();

                // setup click handler
                Button btnConnect = (Button)
super.findViewById(R.id.btnConnect);
                btnConnect.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                        try {
                                MainActivity.this.doConnect();
                        }
                        catch (Throwable throwable) {
                                MainActivity.this.handleThrowable("doConnect
failed", throwable);
                        }
                }
            });

                Button btnDisconnect = (Button)
super.findViewById(R.id.btnDisconnect);
                btnDisconnect.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                        try {
                                MainActivity.this.doDisconnect();
                        }
                        catch (Throwable throwable) {
                                MainActivity.this.handleThrowable("doDisconnect
failed", throwable);
                        }
                }
            });

                // setup messages
                this.messages = new ArrayAdapter<String>(this,
R.layout.message);
 
((ListView)super.findViewById(R.id.lstMessages)).setAdapter(this.messages);
        }
        catch (Throwable throwable) {
                this.handleThrowable("onStart failed", throwable);
        }
    }

    private void doConnect () throws Throwable{
        if (this.adapter == null) {
                this.adapter = BluetoothAdapter.getDefaultAdapter();
                this.addMessage("adapter retrieved");
        }

        if (this.device == null) {
                this.device = adapter.getRemoteDevice("00:18:9A:01:3E:7E");
                this.addMessage("device retrieved");
        }

        if (this.socket != null) {
                throw new InvalidObjectException("Socket already retrieved");
        }
        else {
                this.socket =
device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                this.addMessage("socket retrieved");
        }

        socket.connect();
        this.addMessage("connected");

        this.thread = new ConnectedThread(this.socket);
        this.thread.start();
        /*
        InputStream input = socket.getInputStream();
        this.addMessage("input stream opened");

        OutputStream output = socket.getOutputStream();
        this.addMessage("output stream opened");
        Thread.sleep(2000);

        output.close();
        this.addMessage("output stream closed");

        input.close();
        this.addMessage("input stream closed");

        socket.close ();
        this.addMessage("closed");
        */
    }

    private void doDisconnect () throws Throwable {
        this.thread.cancel();
        this.socket.close();
        this.socket = null;
    }
    private void addMessage (String message) {
        this.messages.add(message);
    }

    Handler addMessageHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
                MainActivity.this.addMessage ((String)msg.obj);
        }
        };

    protected void handleThrowable (String message, Throwable
throwable) {
                if (Log.isLoggable(
                        "Disconnect Problem",
                        Log.ERROR) == false) {
                        return;
                }

                Log.e(
                        "Disconnect Problem",
                        message,
                        throwable);

                String errorMessage = throwable.getMessage();

                if (errorMessage == null) {
                        // no error message provided, display something
                        errorMessage = String.format(
                                "An error occurred %s",
                                throwable.getClass().getName());
                }

                this.addMessage(errorMessage);
        }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket clientSocket;
        private InputStream inStream;
        private OutputStream outStream;

        public ConnectedThread(BluetoothSocket socket) {
            Log.d("Disconnect Problem", "create ConnectedThread");
            clientSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e("Disconnect Problem", "temp sockets not
created", e);
            }

            inStream = tmpIn;
            outStream = tmpOut;
        }

        private void releaseStreams () {
                try {
                        if (this.outStream != null) {
                                this.outStream.close ();
                                this.sendMessage("output stream closed");
                                this.outStream = null;
                        }

                        if (this.inStream != null) {
                                this.inStream.close ();
                                this.sendMessage("input stream closed");
                                this.inStream = null;
                        }
                }
                catch (Exception exception) {
                        Log.e("Disconnect Problem", "releaseStreams", 
exception);
                }
        }

        public void run() {
            Log.i("Disconnect Problem", "BEGIN mConnectedThread");
            byte[] buffer = new byte[1024];
            int bytes;

            // Keep listening to the InputStream while connected
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = inStream.read(buffer);
                } catch (IOException e) {
                    Log.e("Disconnect Problem", "disconnected", e);
                    this.releaseStreams();
                    this.sendMessage("connection lost");
                    break;
                } catch (Exception e) {
                        Log.e("Disconnect Problem", "diconnected", e);
                        this.releaseStreams();
                        this.sendMessage("connection lost");
                    break;
                }
            }
        }

        public void cancel() {
            try {
                if (this.outStream != null) {
                                this.outStream.close ();
                                this.sendMessage("output stream closed - 
cancelled");
                                this.outStream = null;
                        }

                        if (this.inStream != null) {
                                this.inStream.close ();
                                this.sendMessage("input stream closed - 
cancelled");
                                this.inStream = null;
                        }

                this.clientSocket.close();
            } catch (IOException e) {
                Log.e("Disconnect Problem", "close() of connect socket
failed", e);
            }
        }

        private void sendMessage (String message) {
                MainActivity.this.addMessageHandler.obtainMessage(1,
message).sendToTarget();
        }
    }
}

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

To unsubscribe, reply using "remove me" as the subject.

Reply via email to