![](/img/trans.png)
[英]Implement a timeout in BluetoothSocket inputstream.read() in Android
[英]Thread to catch a BluetoothSocket InputStream.read() timeout
我一直在使用InputStream.read( byte[] b, int off, int len )
方法讀入數據,但現在已經遇到了超時問題。 我有時會期待閱讀超時,並且應該讓程序在超時后相應地調整自己。 我試圖實現一個Thread,但我對Threads一無所知,也無法讓它工作。 我還想補充一點,這個線程正在另一個線程中初始化。 我不確定這是什么意思,但它可能會導致問題。
我的初始代碼在我需要閱讀的大部分時間都有效,但每當我預計超時時,我的程序會在read()
調用時凍結,並且永遠不會超時。 當我實現這個新代碼時,我的初始代碼工作的時間現在超時了。 我使用Thread.wait(500)
,我假設是500毫秒,但我找不到任何Javadocs,包括wait()
函數。 這里和這里 。
我還考慮過聲明BluetoothSocket
的超時,但我在文檔中的任何地方都找不到它。
這是我的初始代碼:
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();
}
這是我試圖實現的:
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();
}
編輯:
所以我正在嘗試重新創建
buffer = new byte[1024];
bytes = mmInStream.read(buffer, 0, length);
我做了以下事情:
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" ) );
}
稍后在我的代碼中我打了這個電話....抱歉再次編輯, buf=read( 5 )
調用轉到上面顯示的內容。
byte[] buf = buffer;
write( a );
buf = read( 5 );
Log.i(TAG, "Before buf[5]" );
try {
buf[5] = '\0';
} catch( NullPointerException e ) {
return false;
}
當我使用原始方法時,它會將此buf[5]
調用通過。 但是當我使用new方法時,它會在那個位置給我一個IndexOutOfBoundsException
。 我錯過了什么嗎? 預期輸入應為CMD\\r\\n
藍牙聊天示例在這方面確實很差,你應該使用輸入掃描器而不是mmInStream.read。 這是我使用的,它運作得相當好......
對於您的用例,您可以跳過整個緩沖區和字節並進行寫入和讀取(當您使用掃描儀和輸入流程讀取器時,不需要使用任何這些,因為那些處理那些東西)...換句話說,下面的代碼需要注意這一切都適合你。 我把你的分隔符更改為CRLF。 下面的代碼是你發送一個字符串然后寫入然后讀取。 如果您不需要向遠程設備發送任何內容,只需從scan = new Scanner開始。 每次讀取一行並以\\ r \\ n結束時,它會將其存儲在字符串instring中。
所以如果你想發送“a”,你會寫
String readIn = beginListenForData("a");
a將在mmOutStream下發送,然后掃描器將讀取mmInStream並收集所有字符,然后一旦看到CRLF,它將返回它讀取的字符並將它們返回到readIn字符串中。 合理?
private String beginListenForData(String msg0) {
msg0 += "\r"; //this adds a return character to the string, you can omit this if you just send an a and the remote device understands what that means.
String instring = "";
try {
mmOutStream.write(msg0.getBytes());
} catch (IOException ex) {
stop();
}
scan = new Scanner(new InputStreamReader(mmInStream));
scan.useDelimiter(Pattern.compile("[\\r\\n]+"));
instring = scan.next();
scan = null;
return instring;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.