0

I want to create two apps, one to just send text over Bluetooth and the other to just receive it. But the problem is that even though both devices are connected successfully no text is being transferred. Particularly the outStream.write(bytes) in Messages activity is no working.

Unlike most questions, I just want one-way simplex chat from Sender to Receiver; not a two-way chat.

Any help would be appreciated.

This is the sender code:

//member variables
private BluetoothAdapter btAdapter=null;
private ConnectThread btConnectThread;
private ConnectedThread btConnectedThread;
private int btState;

// Constants that indicate the current connection state
public static final int STATE_NONE = 0;       // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3;  // now connected to a remote device

//dev name to be returned to UI
private static final int DEVICE_NAME=0;
//sent message returned to UI
private static final int SENT_MESSAGE=1;
private static final int STATUS=2;


/**
 * Return Intent extra
 */
public static String EXTRA_DEVICE_ADDRESS = "device_address";
// Unique UUID for this application
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

//handler for UI thread
private final Handler handle=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);

        TextView dvNm=(TextView) findViewById(R.id.connectedTo);
        TextView sntMsg=(TextView) findViewById(R.id.sentMessage);
        TextView stat=(TextView) findViewById(R.id.statusTest);
        EditText tyMsg=(EditText) findViewById(R.id.typedMessage);
        String temp;

        switch (msg.what)
        {
            case DEVICE_NAME:
            {
                temp=dvNm.getText().toString();
                dvNm.setText(temp+": "+msg.obj.toString());
                break;
            }

            case SENT_MESSAGE:
            {
                temp=msg.obj.toString();
                sntMsg.setText("Sent: "+temp);
                tyMsg.setText("");
                break;
            }

            case STATUS:
            {
                temp=msg.obj.toString();
                stat.setText(temp);
            }
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_messages);

    btAdapter=BluetoothAdapter.getDefaultAdapter();
}

@Override
protected void onStart() {
    super.onStart();

    Intent dList=getIntent();
    String macAddr=dList.getStringExtra(EXTRA_DEVICE_ADDRESS);

    if(btState==STATE_NONE)
    {
        connect(macAddr);
    }

}

@Override
protected void onDestroy() {
    super.onDestroy();

    if(btState!=STATE_NONE)
        stop();
}

//button listener for sending message
public void onSend(View v)
{
    //get the typed message
    EditText tyMsg=(EditText) findViewById(R.id.typedMessage);
    //convert it to byte format
    byte[] send=tyMsg.getText().toString().getBytes();

    // Create temporary object
    ConnectedThread cThrd;

    // Synchronize a copy of the ConnectedThread
    synchronized (this) {
        if (btState != STATE_CONNECTED) return;
        cThrd = btConnectedThread;
    }
    // Perform the write asynchronized
    cThrd.write(send);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_messages, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

/**
 * Bluetooth Client component code
 */
private class ConnectThread extends Thread {
    private final BluetoothSocket btSocket;
    private final BluetoothDevice btDevice;

    public ConnectThread(BluetoothDevice device) {
        // Use a temporary object that is later assigned to btSocket,
        // because btSocket is final
        BluetoothSocket tmp = null;
        btDevice = device;

        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        btSocket = tmp;
    }

    public void run() {
        // Cancel discovery because it will slow down the connection
        btAdapter.cancelDiscovery();

        try {
            // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            btSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and get out
            try {
                btSocket.close();
            } catch (IOException closeException) { }
            return;
        }

        // Do work to manage the connection (in a separate thread)
        connected(btSocket,btDevice);
    }

    /** Will cancel an in-progress connection, and close the socket */
    public void cancel() {
        try {
            btSocket.close();
        } catch (IOException e) { }
    }
}


/**
 * Code to manage the connected socket
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket btSocket;
    private final OutputStream outStream;

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

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

        outStream = tmpOut;
    }

    public void run() { }

    /* Call this from the main activity to send data to the remote device */
    public void write(byte[] bytes) {
        try {

            Message msg2=handle.obtainMessage(STATUS,"Inside write of connectedthread");
            handle.sendMessage(msg2);

            outStream.write(bytes);
            outStream.flush();

            Message msg1=handle.obtainMessage(STATUS,"Wrote to outstream");
            handle.sendMessage(msg1);

            Message msg=handle.obtainMessage(SENT_MESSAGE,bytes);
            handle.sendMessage(msg);

        } catch (IOException e) { }
    }

    /* Call this from the main activity to shutdown the connection */
    public void cancel() {
        try {
            btSocket.close();
        } catch (IOException e) { }
    }
}

/**
 * Start the ConnectThread to initiate a connection to a remote device.
 *
 * @param macAddr is the mac-address The BluetoothDevice to connect
 */
public synchronized void connect(String macAddr) {

    //get Bluetooth device from mac-address
    BluetoothDevice device = btAdapter.getRemoteDevice(macAddr);

    // Cancel any thread attempting to make a connection
    if (btState == STATE_CONNECTING) {
        if (btConnectThread != null) {
            btConnectThread.cancel();
            btConnectThread = null;
        }
    }

    // Cancel any thread currently running a connection
    if (btConnectedThread != null) {
        btConnectedThread.cancel();
        btConnectedThread = null;
    }

    // Start the thread to connect with the given device
    btConnectThread = new ConnectThread(device);
    btConnectThread.start();

    btState=STATE_CONNECTING;
}

/**
 * Start the ConnectedThread to begin managing a Bluetooth connection
 *
 * @param socket The BluetoothSocket on which the connection was made
 * @param device The BluetoothDevice that has been connected
 */
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
        device) {

    // Cancel the thread that completed the connection
    if (btConnectThread != null) {
        btConnectThread.cancel();
        btConnectThread = null;
    }

    // Cancel any thread currently running a connection
    if (btConnectedThread != null) {
        btConnectedThread.cancel();
        btConnectedThread = null;
    }

    // Start the thread to manage the connection and perform transmissions
    btConnectedThread = new ConnectedThread(socket);
    btConnectedThread.start();

    // Send the name of the connected device back to the UI Activity
    Message msg = handle.obtainMessage(DEVICE_NAME,device.getName());
    handle.sendMessage(msg);

    btState=STATE_CONNECTED;
}

/**
 * Stop all threads
 */
public synchronized void stop(){

    // Cancel the thread that completed the connection
    if (btConnectThread != null) {
        btConnectThread.cancel();
        btConnectThread = null;
    }

    // Cancel any thread currently running a connection
    if (btConnectedThread != null) {
        btConnectedThread.cancel();
        btConnectedThread = null;
    }
    btState=STATE_NONE;
}
}

And this is the receiver code:

//member variables
private BluetoothAdapter btAdapter=null;
private AcceptThread btAcceptThread;
private ConnectedThread btConnectedThread;
private int btState;

// Constants that indicate the current connection state
public static final int STATE_NONE = 0;       // we're doing nothing
public static final int STATE_LISTEN = 1;     // now listening for incoming connections
public static final int STATE_CONNECTED = 3;  // now connected to a remote device

//dev name to be returned to UI
private static final int DEVICE_NAME=0;
//received message returned to UI
private static final int RECEIVED_MESSAGE=1;

// Name for the SDP record when creating server socket
private static final String NAME = "BluetoothAnnouncement";
// Unique UUID for this application
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

//handler for UI thread
private final Handler handle=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);


        TextView dvNm=(TextView) findViewById(R.id.connectedTo);
        TextView rcvdMsg=(TextView) findViewById(R.id.receivedMessage);
        String temp;

        switch (msg.what)
        {
            case DEVICE_NAME:
            {
                temp=dvNm.getText().toString();
                dvNm.setText(temp+": "+msg.obj.toString());
                break;
            }

            case RECEIVED_MESSAGE:
            {
                temp=msg.obj.toString();
                rcvdMsg.setText("Received: "+temp);
                break;
            }
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Acquiring Bluetooth Adapter
    btAdapter = BluetoothAdapter.getDefaultAdapter();
    //setting initial state
}

@Override
protected void onStart() {
    super.onStart();

    if(!btAdapter.isEnabled())
    {
        Toast.makeText(this, "Please enable Bluetooth to receive announcements",
                Toast.LENGTH_SHORT).show();
    }
}

@Override
protected void onResume() {
    super.onResume();

    if(btAdapter.isEnabled())
    {
        if(btState==STATE_NONE)
        {
            start();
        }
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();

    if(btState!=STATE_NONE)
        stop();
}

//enabling Bluetooth
public void btEnable(View v)
{
    if (btAdapter.isEnabled())
    {
        Toast.makeText(this, "Bluetooth already enabled",
                Toast.LENGTH_SHORT).show();
    }
    else
    {
        Intent discoverableIntent = new
                Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
        startActivity(discoverableIntent);
    }
}

/**
 * Server component code
 */
private class AcceptThread extends Thread {
    private final BluetoothServerSocket btServerSocket;

    public AcceptThread() {
        // Use a temporary object that is later assigned to btServerSocket,
        // because btServerSocket is final
        BluetoothServerSocket tmp = null;
        try {
            // MY_UUID is the app's UUID string, also used by the client code
            tmp = btAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) { }
        btServerSocket = tmp;
    }

    public void run() {
        BluetoothSocket socket = null;
        BluetoothDevice device;
        // Keep listening until exception occurs or a socket is returned
        while (true) {
            try {
                socket = btServerSocket.accept();
            } catch (IOException e) {
                break;
            }
            // If a connection was accepted
            if (socket != null) {
                device=socket.getRemoteDevice();
                // Do work to manage the connection (in a separate thread)
                connected(socket, device);
                try {
                    btServerSocket.close();
                } catch (IOException e) { }
                break;
            }
        }
    }

    /** Will cancel the listening socket, and cause the thread to finish */
    public void cancel() {
        try {
            btServerSocket.close();
        } catch (IOException e) { }
    }
}

/**
 * Code to manage the connected socket
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket btSocket;
    private final InputStream inStream;

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

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

        inStream = tmpIn;
    }

    public void run() {
        byte[] buffer = new byte[1024];  // 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 = inStream.read(buffer);
                // Send the obtained bytes to the UI activity
                Message msg = handle.obtainMessage(RECEIVED_MESSAGE,bytes);
                handle.sendMessage(msg);

            } catch (IOException e) {
                break;
            }
        }
    }

    /* Call this from the main activity to shutdown the connection */
    public void cancel() {
        try {
            btSocket.close();
        } catch (IOException e) { }
    }
}

/**
 * Start the chat service. Specifically start AcceptThread to begin a
 * session in listening (server) mode. Called by the Activity onResume()
 */
public synchronized void start() {

    // Cancel any thread currently running a connection
    if (btConnectedThread != null) {
        btConnectedThread.cancel();
        btConnectedThread = null;
    }

    // Start the thread to listen on a BluetoothServerSocket
    if (btAcceptThread == null) {
        btAcceptThread = new AcceptThread();
        btAcceptThread.start();
    }

    //set state
    btState=STATE_LISTEN;
}

/**
 * Start the ConnectedThread to begin managing a Bluetooth connection
 *
 * @param socket The BluetoothSocket on which the connection was made
 * @param device The BluetoothDevice that has been connected
 */
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
        device) {

    // Cancel any thread currently running a connection
    if (btConnectedThread != null) {
        btConnectedThread.cancel();
        btConnectedThread = null;
    }

    // Cancel the accept thread because we only want to connect to one device
    if (btAcceptThread != null) {
        btAcceptThread.cancel();
        btAcceptThread = null;
    }

    // Start the thread to manage the connection and perform transmissions
    btConnectedThread = new ConnectedThread(socket);
    btConnectedThread.start();

    // Send the name of the connected device back to the UI Activity
    Message msg = handle.obtainMessage(DEVICE_NAME,device.getName());
    handle.sendMessage(msg);

    btState=STATE_CONNECTED;
}

/**
 * Stop all threads
 */
public synchronized void stop(){

    // Cancel any thread currently running a connection
    if (btConnectedThread != null) {
        btConnectedThread.cancel();
        btConnectedThread = null;
    }

    // Cancel the accept thread because we only want to connect to one device
    if (btAcceptThread != null) {
        btAcceptThread.cancel();
        btAcceptThread = null;
    }

    btState=STATE_NONE;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
  • 1
    possible duplicate of [Android Bluetooth Example](http://stackoverflow.com/questions/12562875/android-bluetooth-example) – Gyuri Apr 16 '15 at 21:48
  • Thanks for your suggestion Gyuri, but that is not my problem. I just want a one-way chat and debugging the code shows that outStream.write(bytes) is the method where code's stopping. But there is no error in logcat or syntax error whatsoever. – Sagnik Nandi Apr 18 '15 at 14:06

0 Answers0