Android send ArrayList commands with delay to OBD - java

I need to send a list of commands to OBD port with some delay because the ELM327 can't manage all commands together...
I'm trying with this code but not work
public void repeatCommand(){
for (final String command : commandArray){
Log.d(TAG, "Giro for");
final Handler handlerTimed = new Handler();
handlerTimed.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 100ms
sendMessage(command);
}
}, 1000);
}
/*String message = "010C\r";
sendMessage(message);*/
}
It's only send the first command after 1 sec but the other commands nope.
How can i send all comands delayed for let the write to manage all commands sended to the OBD?
Ok i use the suggested method that send the first command and wait for response.... when get response, send the next message.
private synchronized void manage(BluetoothSocket socket, BluetoothDevice
device) {
Log.d(TAG, "connected, Socket Type:");
// Cancel the thread that completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Cancel any thread currently managing connections
if (mManageThread != null) {
mManageThread.cancel();
mManageThread = null;
}
// Start the thread to manage the connection and perform transmissions
mManageThread = new ManageDataThread(socket);
mManageThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Constants.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
// Update UI title
updateUserInterfaceTitle();
}
Here the Thread that manage connection..
public class ManageDataThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private boolean wait_response = false;
public ManageDataThread(BluetoothSocket socket) {
Log.d(TAG, "create ManageDataThread: ");
mmSocket = 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(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
mState = STATE_CONNECTED;
}
public void run() {
while(true) {
for (final String command : commandArray) {
byte[] send = command.getBytes();
write(send);
//mState = STATE_WAIT_RESPONSE;
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (wait_response) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
//TODO devo gestire l'arrivo di bytes
ObdCommand obc = new ObdCommand();
obc.readResult(mmInStream);
formattedMessage = obc.getResult();
//buffer = (byte) obc.getBuffer();
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, formattedMessage)
.sendToTarget();
wait_response = false;
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
}
}
It's little bit imperfect but now it's work....
I will open a new post for stop it and update the array list of commands because if i change the list of commands, the loop keep the old array list, so i need to notify the thread that the arraylist has change
EDIT
Don't use while(true) inside thread, better to use a variable set to True e when need to stop thread set the variable to false, or problem occurs when stop thread....

The proper way to work with OBD2 – which is a serial protocol – is to implement something like a command queue with command-specific callbacks that deliver the response to the command you have requested to it. The command queue should work in a background thread, operating the queue and listening to the serial port. Don't even start w/ delays or similar approaches.

One thing to consider is that when you create a handler and don't provide it with a looper it will use the looper of it's current thread.
So my best guess, since we don't have your code, is that you do in fact run it in a thread which is not the main one. make sure your thread doesn't get killed somewhere along the way and it should work.
Also, a few coding tips:
First, I must say that it would be more efficient to set the handler outside of the loop.
That way you don't waste memory creating a handler in each iteration.
So it should look something like that:
public void repeatCommand()
{
final Handler handlerTimed = new Handler();
for (final String command : commandArray){
Log.d(TAG, "Giro for");
handlerTimed.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 100ms
sendMessage(command);
}
}, 1000);
}
}
Second, I strongly recommend that you will set the consts of your class, like that 1000 value.

Related

Input Stream Issue

stuck in One Issue ,
I am using BluetoothSocket class, I am sending and receiving data with the help of input and output streams.
when App receives large amount of data from input stream, I am killing my app forcefully and after it I am again restarting my app, but InputStream returns me previous data, which is not needed anymore.how to discard that old data?
has Anyone Some Solution for this Issue?
Following is my source code:
public class MyBluetoothService {
private static final String TAG = "MY_APP_DEBUG_TAG";
private Handler mHandler; // handler that gets info from Bluetooth service
// Defines several constants used when transmitting messages between the
// service and the UI.
private interface MessageConstants {
public static final int MESSAGE_READ = 0;
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_TOAST = 2;
// ... (Add other message types here as needed.)
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private byte[] mmBuffer; // mmBuffer store for the stream
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();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating input stream", e);
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating output stream", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
mmBuffer = new byte[1024];
int numBytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs.
while (true) {
try {
// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
// Send the obtained bytes to the UI activity.
Message readMsg = mHandler.obtainMessage(
MessageConstants.MESSAGE_READ, numBytes, -1,
mmBuffer);
readMsg.sendToTarget();
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
break;
}
}
}
// Call this from the main activity to send data to the remote device.
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
// Share the sent message with the UI activity.
Message writtenMsg = mHandler.obtainMessage(
MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
writtenMsg.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Error occurred when sending data", e);
// Send a failure message back to the activity.
Message writeErrorMsg =
mHandler.obtainMessage(MessageConstants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString("toast",
"Couldn't send data to the other device");
writeErrorMsg.setData(bundle);
mHandler.sendMessage(writeErrorMsg);
}
}
// Call this method from the main activity to shut down the connection.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the connect socket", e);
}
}
}
}
// Keep listening to the InputStream until an exception occurs
The problem is here. You should keep reading from the stream until end of stream or an exception occurs. You need to break out of the read loop if read() returns -1.
At present you are reading beyond end of stream, and ignoring the condition altogether, so of course the data that was in the buffer on the last successful read is still there.
For your application to keep seeing that data, you must also be ignoring the read count and assuming the buffer was filled, which also is invalid.
I think you should close the socket to manage the bug.
I recommend you to do this in finalizer like the code below.
private class ConnectedThread extends Thread
{
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private byte[] mmBuffer; // mmBuffer store for the stream
#override
protected void finalize() throws Throwable
{
try
{
cancel();
}
finally
{
super.finalize();
}
}
...
Also as I mentioned in comment, it is safer to close every streams before closing the socket.
So, try this cancel() method.
// Call this method from the main activity to shut down the connection.
public void cancel()
{
try {
mmInStream.close();
} catch( NullPointerException | IOException e) {}
try {
mmOutStream.close();
} catch( NullPointerException | IOException e) {}
try
{
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the connect socket", e);
}
}
And more information about finalize method.
EDIT: bold ones are important than other suggestions.
Reading comments of EJP I understood why your app stops when you get large data : you maybe have to clear buffers before calling read(). And he says that finalizer can happen not to be called by system (I don't know why).
How about breaking the loop when the read() returned -1?
And just now I found a helpful link about proper method to read a stream. I hope it helped.
Code cited from the link
private String extract(InputStream inputStream) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int read = 0;
while ((read = inputStream.read(buffer, 0, buffer.length)) != -1) {
baos.write(buffer, 0, read);
}
baos.flush();
return new String(baos.toByteArray(), "UTF-8");
}
Also
Though the finalizer may be able not to be called by system closing streams before closing sockets is safer (I read some SO threads before).

Android interrupt threads on button click - avoiding race condition

I have an android app designed to pair with other phones and send/receive data over bluetooth. Specifically, when a user clicks a button, it will start discovery, connect to a phone, open a socket etc. In general this works, however, I also want to set it up so that during this whole process, if the user clicks the button again, it will correctly close/stop this process. The problem I'm having is that when the user clicks to stop, sometimes it will close a socket prematurely while the app is still trying to check for incoming data because this is all happening across multiple threads. I'm trying to find the correct way to handle this
So when the user clicks to start the process, discovery will happen and then it will try to connect to the paired device over a socket:
private class ConnectThread extends Thread {
private BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
mmDevice = device;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
while(!this.isInterrupted()){
BluetoothSocket tmp = null;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// SERVICE_UUID is the app's UUID string, also used by the server code
tmp = mmDevice.createRfcommSocketToServiceRecord(SERVICE_UUID);
} catch (IOException e) {
e.printStackTrace();
}
mmSocket = tmp;
if(mmSocket != null){
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.d(TAG, "Socket connected");
// Do work to manage the connection (in a separate thread)
connectedThread = new ConnectedThread(mmSocket);
connectedThread.start();
break;
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
Log.d(TAG, "Unable to connect socket: " + connectException.getMessage());
}
}
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
Log.d(TAG, "Closing socket");
mmSocket.close();
this.interrupt();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Once the socket has connected, I start a different thread to set up the datastreams:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
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;
}
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 (!this.isInterrupted()) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
this.interrupt();
} catch (IOException e) {
e.printStackTrace();
}
}
}
So this all works as far as sending/receiving data goes. But when the user clicks the button a second time to stop the entire process (or kill the connection if it already exists) I get an error. On pressing Stop the following code gets executed:
if(btHelper.discoveryStarted){
this.discoveryStarted = false;
mBluetoothAdapter.cancelDiscovery();
}
//Stop socket connection
if(connectThread != null & connectedThread != null){
connectedThread.cancel();
connectThread.cancel();
}
The error I get is an ioexception: bt socket closed, read return: -1 and its pointing to the line where I'm trying to read from the datastream:
bytes = mmInStream.read(buffer)
So the problem is that its trying to read from the stream, but on button click I have already told the socket to close, therefore theres no socket to read from. Whats the correct way to interrupt these threads to avoid a race condition like this?
Furthermore, how do I set this up so that regardless of where the user is in this process the appropriate threads/sockets/connections will be closed correctly? (for example, sometimes the socket will be opened, but data streams have not been set up yet, vs both/neither have been created)

Trouble receiving data from Android Bluetooth connection

I have an android application connected to a Bluetooth mate silver chip. I'm in the process of testing the send/receive function of it. Mostly I have been following the bluetooth examples on the android dev site.
I can tell sending data works because when I write("$$$") to the chip, it enters command mode and flashes it's status LED very quickly. When the chip enters command mode, it sends a reply: "CMD". I am having trouble receiving this reply.
When I press a button, the following code is executed. mct is the global ConnectedThread that I am using to read and write. As poor form as it is, all functions are inside MainActivity.java
if(connected){
if (cmdMode == false){
mct.write("$$$".getBytes()); //enter command mode
mct.listen();
TextView lbl_history = (TextView) findViewById(R.id.lbl_history);
lbl_history.setText(message);
cmdMode = true;
}
else{
mct.write("k,\n".getBytes()); //kill the connection
cmdMode = false;
}
}
My communication thread:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void listen() {
handled = false;
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
reply=null;
while (reply==null) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
reply = buffer.toString();
//message is a global String to store the latest message received
message = reply;
} catch (IOException e) {
break;
}
}
reply = null;
}
//write and cancel functions removed for simplicity
}
When I run this code, the result is a textview that says "[B#415f8910", which I assume is junk. Multiple runs of the same code will produce similar results, with the last few digits varying. The expected result would be "CMD". Any ideas on what the problem is here? I am new to android development, so any help is appreciated.
Further inspection reveals that multiple runs strictly increase "[B#415f8910", leading me to believe that it is a memory address. Still, I don't know What to do with it though.
I found the problem. Rather than straight up calling "toString()" on the array of bytes, I needed to call the String constructor to properly convert the data:
String message = new String(buffer, "UTF-8");
specifying UTF-8 is what made the difference.

Bluetooth data transfer between two Android devices

I have been following this Android guide for Bluetooth communication
To explain exactly what I want to do, when the two devices are paired, two different activities open up on each device (server and client) where on the server activity I have different buttons, and on the client activity there is just a textview.
I want to be able to press a button on the server device and display it on the client.
I have managed to establish a connection between the two devices, but now I want to send data which I have not been able to do.
They give this code for data transfer:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
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) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
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 = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
But this line generates an error
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
And is not explained in the guide. I don't know what the mHandler is or does.
Apart from the error, I don't even really understand where to put this code. Should it be in the second activities (server and client) that I open or in the main? If in the Server activity, should it be in the onClick method for all the buttons with a different byte code to send for each button? And in this code, how do we distinguish who is sending and who is receiving?
Check out the BluetoothChat example that Google provides in the SDK. It'll show you how to implement basic sending of text over bluetooth.
You can also try the tutorial example here
Can you please describe the error as seen by you?
As informed by Ankit and Addy, BlueToothChat is the best code for you to refer. Conduct an experiment by loading it on 2 android devices - use one as server other as client to exchange the messages between them. Such experiment will help you to understand it's code and decide your coding logic.
mHandler is used for passing message from your BluetoothHandle.java to your Activity. This will help you to update messages on your screen which are returned by BluetoothHandler.
you have to create mHandler from your activity and call your handler like this -
mBluetoothHandler = new BluetoothHandler(this, mHandler);
and your BluetoothHandler.java has constructor like this -
public class BluetoothHandler {
public BluetoothHandler(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
mcontext = context;
}
}
For more details, please refer Android sample project of Bluetooth Chat .
You can also use this link :
http://myandroidappdevelop.blogspot.in/2013/05/bluetooth-chat-example.html
// Enter code here
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
byte[] writeBuf = (byte[]) msg.obj;
int begin = (int)msg.arg1;
int end = (int)msg.arg2;
switch(msg.what) {
case 1:
String writeMessage = new String(writeBuf);
writeMessage = writeMessage.substring(begin, end);
break;
}
}
};

Can't read socket InputStream on Jelly Bean

I have a TCP socket connection which works well on Android 2.3 but now facing some problems on Android 4.1.
The problem is that InputStream.read() method always returns -1 (without blocking), like the connection is closed.
Creating socket:
SocketFactory socketFactory = SocketFactory.getDefault();
Socket socket = socketFactory.createSocket("c.whatsapp.net", 5222);
socket.setSoTimeout(3*60*1000);
socket.setTcpNoDelay(true);
Retrieving input and output streams and writing some initial data:
InputStream inputStream = new BufferedInputStream(socket.getInputStream());
OutputStream outputStream = new BufferedOutputStream(socket.getOutputStream());
outputStream.write(87);
outputStream.write(65);
outputStream.write(1);
outputStream.write(2);
outputStream.flush();
Then, this condition always passes without blocking:
int c = inputStream.read();
if (c < 0) {
Log.d(TAG, "End of stream");
}
This code is running in a background thread. And it was working on Gingerbread.
Tried to use InputStreamReader and OutputStreamWriter instead of direct streams - no effect.
I have seen that very same error before, although this answer might look offtopic give it a chance and let me know if it worked, for some reason sockets are having strange behavior on jellybean even when they were working completely fine in lower android versions, the way I fixed this issue was to move the targetSdkVersion to jelly bean as well as the Project Build Target under Android properties of the project, didn't modify one single line of code, just that, and for some reason it does the trick...
Hope this helps.
Regards!
I had some similar issue where the inputStream.read() returned -1 and I did not get any Exception. In fact the server was down and the connection broken. I didn't test it with different versions, only with 4.0.
Here's the Google Bug Report about this behavior.
Unfortunately status of the bug seems to be 'closed' as not reproduceable.
My work around was to interpret the -1 as a close of the socket and an unreachable server. When you try to reconnect, you get the right errors.
I have had a similar problem and fixed it with a workaround like this
private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
private static class WatchDog implements Runnable{
private Thread thread = Thread.currentThread();
public void run() {
Log.d(LOG_TAG, "Interrupting read due to timeout");
thread.interrupt();
}
}
private void read(InputStream in, ByteBuffer bb, long waitTime) throws IOException {
int startingPos = bb.position();
long timeout = System.currentTimeMillis() + RESPONSE_TIMEOUT;
ScheduledFuture<?> watchdogFuture = executor.schedule(new WatchDog(), RESPONSE_TIMEOUT, TimeUnit.MILLISECONDS);
try {
while(System.currentTimeMillis() < timeout && bb.hasRemaining()){ //workaround fixing timeout after 1ms
try{
int read = in.read(bb.array(), bb.position(), bb.remaining());
if(read > 0){
bb.position(bb.position()+read);
}
} catch(SocketTimeoutException e){}
if(bb.hasRemaining()){
Thread.sleep(5);
}
}
watchdogFuture.cancel(true);
} catch (InterruptedException e) {}
if(bb.hasRemaining()){
throw new SocketTimeoutException("Unable to read requested bytes: "
+ (bb.position()-startingPos) + "/" + (bb.limit()-startingPos)
+ " after " + (System.currentTimeMillis() - timeout + RESPONSE_TIMEOUT) + "ms");
}
}
Using BufferedReader and PrintWriter works on all versions for me and is extremely convenient for sending and receiving anything you want (even JSON strings) via any communication protocol. Try saving them as member variables when starting your background thread like this:
mInput = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
mOutput = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
For asynchronous communication your background thread might then look like this:
#Override
public final void run() {
while (!Thread.currentThread().isInterrupted()) {
if (mInput == null) {
break;
}
String message = null;
try {
message = mInput.readLine();
} catch (IOException e) {
// handle the exception as you like
break;
}
if (Thread.currentThread().isInterrupted()) {
// thread was interrupted while reading
break;
} else if (message != null) {
// handle the message as you like
}
}
}
Use another background thread to send messages:
#Override
public void run() {
if (mOutput != null) {
mOutput.println(<message to be );
if (mOutput == null) {
// the above thread was interrupted while writing
} else if (!mOutput.checkError()) {
// everything went fine
} else {
// handle the exception
}
}
}
Also, you will have to close the streams from outside to make sure readLine doesn't block forever:
try {
mOutput.close();
mInput.close();
mOutput = null;
mInput = null;
} catch (IOException e) {
// log the exception
}
Now, since you're using TCP sockets it may happen that the socket is actually dead and readLine is still blocking. You have to detect that and close the streams just like above. For that, you will have to add another thread (oh well) that periodically sends keep-alive-messages. If no message was received from the remote device for X seconds, it has to close the streams.
This whole approach makes sure the socket is closed and all threads finish at all circumstances. Of course you can make the communication synchronous, if that is what you need, by removing the sender-thread and including println() inside the reader-thread instead. I hope that helps you (even though the answer comes 8 months late).
Friend,
try inputStream.readLine(); (i.e) DataInputStream.readLine(); (Deprecated method)
this worked for me...
Try this code -
Runnable runnable = new Runnable() {
#Override
public void run() {
synchronized (this) {
Socket s = null;
String inMsg = null, msg2 = null;
try {
try {
s = new Socket(server, port);
} catch (Exception e) {
return;
}
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
try {
inMsg = in.readLine()
+ System.getProperty("line.separator");
} catch (Exception e) {
return;
}
out.write(message + "\n\r");
out.flush();
try {
msg2 = in.readLine();
if (msg2 == null) {
return;
}
} catch (Exception e) {
return;
}
out.close();
s.close();
} catch (Exception e) {
return;
}
}
}
};
It works for me.
You should use Apache Commons IO: http://commons.apache.org/proper/commons-io/
See IOUtils.copy() http://commons.apache.org/proper/commons-io/javadocs/api-release/index.html?org/apache/commons/io/package-summary.html

Categories

Resources