Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to send text data between two bluetooth devices in android?

I have downloaded the android sample of Bluetooth chat app to send text between two android devices using Bluetooth.

I have installed and run this app in two android devices.

I faced many problems in that code

  1. Service discovery failed exception - Fixed
  2. java.io.IOException: Software caused connection abort - Fixed
  3. java.io.IOException: Connection reset by Peer - Struck on this

1. Cleared the Service discovery failed exception:

For service discovery failed exception, In Bluetooth Chat Service, I have checked sdk version and for the sdk version which is greater than Ginger Bread,

I have used Method class to invoke RfCOMM socket connection and my first exception is solved in this approach.

Exception Code

 tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

Fixed Exception code

try {
if (Build.VERSION.SDK_INT < 9) { 
try {
     tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
       } catch (IOException e1) {
            e1.printStackTrace();
       }
       } else {
   Method m = null;
  try {
  m = device.getClass().getMethod("createRfcommSocket",
        new Class[] { int.class });
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
                }
                try {
                    tmp = (BluetoothSocket) m.invoke(device, 1);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                }
            } catch (Exception e) {
                Log.e(TAG, "create() failed", e);
            }

2. Cleared java.io.IOException: Software caused connection abort

I have made check whether the InputStream is available

Exception Code

bytes = mmInStream.read(buffer);

Fixed Exception code

 if (mmInStream.available() > 0) {
                            // Read from the InputStream
                            bytes = mmInStream.read(buffer);

Now my problem is when I try to send data between connected devices, it throws the following error message "Connection Reset By Peer" while writing to output stream

Exception code:

public void write(byte[] buffer, int start, int end) {
mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
    if (mmOutStream !=null) {
        try {
             mmOutStream.write(buffer);
        } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
        }
    }
    else{
        Log.e("OutputStream Null","");
    }
}

== Update ==

Even though it shows that both devices are connected, the accept method returns fail

**06-19 10:30:23.625: D/BluetoothChatService(2630): connected
06-19 10:30:23.625: D/BluetoothChatService(2630): cancel Thread[AcceptThread,5,main]
06-19 10:30:23.625: V/BluetoothSocket.cpp(2630): abortNative
06-19 10:30:23.625: V/BluetoothSocket.cpp(2630): ...asocket_abort(50) complete
06-19 10:30:23.625: V/BluetoothSocket.cpp(2630): ...accept(50, RFCOMM) = -1 (errno 125)
06-19 10:30:23.632: E/BluetoothChatService(2630): accept() failed
06-19 10:30:23.632: E/BluetoothChatService(2630): java.io.IOException: Operation Canceled
06-19 10:30:23.632: E/BluetoothChatService(2630):   at android.bluetooth.BluetoothSocket.acceptNative(Native Method)
like image 762
Sankar Ganesh PMP Avatar asked Nov 12 '22 03:11

Sankar Ganesh PMP


1 Answers

I had alot of problems with the chat example myself, so i tried another approach.

First you have to make one device host and the other the client, this works with the example pretty well. if you dont have this running, i can provide you with that code aswell.

Using the classes above, you get the socket for the connection. Use that to pass it to this class and then you can send using the write method. and the incoming messages are automatically parsed in the run-method (i added a message id and length to the front, thats why there is so much things going on in there)

private class ConnectedThread extends Thread {

/** the connection socket */
private final BluetoothSocket mmSocket;

/** input stream for incoming messages */
private final InputStream mmInStream;

/** output stream for outgoing messages */
private final OutputStream mmOutStream;

/**
 * save the socket and get the streams
 * 
 * @param socket
 */
public ConnectedThread(BluetoothSocket socket) {
    mmSocket = 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) {
        e.printStackTrace();
    }

    mmInStream = tmpIn;
    mmOutStream = tmpOut;
}

/**
 * reads incoming data and splits it into single messages
 */
public void run() {
    /** buffer for a single byte message */
    byte[] buffer = new byte[1024];

    /** number of bytes returned from read() */
    int bytes;

    // Keep listening to the InputStream until an exception occurs
    while (true) {
        try {
            // read overhead from the InputStream
            bytes = mmInStream.read(buffer, 0, LEN_SIZE + LEN_TYPE);

            // if no bytes are read, wait for a new message
            if (bytes == 0)
                continue;

            // get the size bytes and convert them to int
            byte[] size_arr = new byte[LEN_SIZE];
            for (int i = 0; i < LEN_SIZE; i++)
                size_arr[i] = buffer[i];
            int size = convertByteArrayToInt(size_arr, LEN_SIZE);

            // the type is 1 byte after the size
            byte type = buffer[LEN_SIZE];

            // array for the output data
            byte[] output = new byte[size + LEN_TYPE];
            output[0] = type;

            // current position, read until cPos == size
            int cPos = 0;
            while (cPos < size) {
                // either read the buffer lenght or the remaining bytes
                int read_len = Math.min(buffer.length, size - cPos);
                bytes = mmInStream.read(buffer, 0, read_len);

                // write the bytes to the output
                for (int i = 0; i < bytes; i++)
                    output[cPos + i + LEN_TYPE] = buffer[i];

                // increase the current position
                cPos += bytes;
            }

            // add the message to the queue
            mMessageData.add(output);

            // tell the service about the new message
            mHandler.obtainMessage(BluetoothService.CONNECTION_RECV_MSG, mConnectionAddress).sendToTarget();

        } catch (IOException e) {
            // tell the service about the disconnect
            mHandler.obtainMessage(BluetoothService.CONNECTION_LOST, mConnectionAddress).sendToTarget();
            e.printStackTrace();
            break;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/**
 * writes a byte stream to the connection
 * 
 * @param bytes
 *            the byte stream
 */
public void write(byte[] bytes) {
    try {
        mmOutStream.write(bytes, 0, bytes.length);
        mmOutStream.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * close the socket
 */
public void cancel() {
    try {
        mmSocket.close();
    } catch (IOException e) {
    }
}

}

This worked for me, i hope it also does for you. If you have any question, feel free to ask :-)

like image 199
gtRfnkN Avatar answered Nov 15 '22 00:11

gtRfnkN