I have been using InputStream.read( byte[] b, int off, int len )
method to read in data, but now have run into a timeout problem. I am sometimes expecting timeouts from reading, and should have the program adjust itself accordingly after a timeout. I have tried to implement a Thread but I really know nothing about Threads and cannot get it to work. I also want to add that this thread is being initialized within another thread. I'm not sure what the implications of this are but it may cause a problem.
My initial code had worked for the majority of times I need to read, but whenever I'm expecting a timeout, my program freezes at the read()
call and never times out. When I implemented this new code, the times when my initial code worked now time out. I use Thread.wait(500)
which I assume is 500 milliseconds, but I cannot find any Javadocs including the wait()
function. Here and Here.
Other posts relating to this: 1, 2, 3.
I have also looked into declaring a timeout for the BluetoothSocket
, but I cannot find it anywhere in the documentation.
Here is what my initial code looks like:
public void run(int length) throws IOException {
buffer = new byte[1024];
try {
bytes = mmInStream.read(buffer, 0, length);
mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Message msg = mHandler.obtainMessage(MainMenu.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString( TOAST, "Device has disconnected from the Bluetooth Module." );
msg.setData(bundle);
mHandler.sendMessage(msg);
connectionLost();
BluetoothService.this.start();
}
This is what I have tried to implement:
public void run(int length) throws IOException {
buffer = new byte[1024];
length1 = length;
Thread myThread = new Thread(new Runnable() {
public void run() {
try {
bytes = mmInStream.read( buffer, 0, length1 );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
synchronized (myThread) {
myThread.start();
try {
myThread.wait(500);
if(myThread.isAlive()) {
mmInStream.close();
Log.i( "InStream", "Timeout exceeded!");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
myThread.run();
mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Message msg = mHandler.obtainMessage(MainMenu.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString( TOAST, "Device has disconnected from the Bluetooth Module." );
msg.setData(bundle);
mHandler.sendMessage(msg);
connectionLost();
BluetoothService.this.start();
}
EDIT:
So I'm trying to recreate
buffer = new byte[1024];
bytes = mmInStream.read(buffer, 0, length);
I have done the following:
Scanner scan = new Scanner(new InputStreamReader(mmInStream));
String readIn;
try {
readIn = scan.next();
bytes = 5; // I tried with or without this, since I do not think it matters...
buffer = readIn.getBytes( Charset.forName( "US-ASCII" ) );
}
Later in my code I make this call....Sorry edit again, the buf=read( 5 )
call goes to what is shown above.
byte[] buf = buffer;
write( a );
buf = read( 5 );
Log.i(TAG, "Before buf[5]" );
try {
buf[5] = '\0';
} catch( NullPointerException e ) {
return false;
}
When I use the original method, It passes this buf[5]
call fine. But when I use the new method, it gives me an IndexOutOfBoundsException
at that spot. Am I missing something? The expected input should be CMD\r\n