01.07.2014, 17:28. Просмотров 1865. Ответов 1
Создан блютузный сокет, приконнекчен к девайсу, запущен следующий поток:
Java |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
| private class ReceiveDataThread extends Thread {
public boolean stopThread = false;
private InputStream inStream;
//private BufferedReader bufferedReader; // not working
private StringBuilder receivedString;
public ReceiveDataThread(BluetoothSocket socket) {
Log.d(TAG, "ReceiveDataThread :: ReceiveDataThread()");
try {
if (socket != null) {
inStream = socket.getInputStream();
//bufferedReader = new BufferedReader(new InputStreamReader(inStream));
}
} catch (IOException e) {
Log.e(TAG, "input stream get failed: " + e.getMessage());
if (listener != null) {
listener.onBluetoothError(ERROR_INPUTSTREAM_GET_FAILED);
}
}
}
@Override
public void run() {
Log.d(TAG, "ReceiveDataThread :: run()");
//while (!stopThread) {
// Read from the InputStream
if (inStream != null) {
byte[] buffer; //= new byte[bufferSize]; // buffer store for the stream
int bytesAvailableCount = 0;
int bytesReadCount = 0; // bytes returned from read()
receivedString = new StringBuilder();
String line = "";
while (bytesReadCount >= 0 && !stopThread) {
try {
bytesAvailableCount = inStream.available();
Log.d(TAG, "bytesAvailableCount=" + bytesAvailableCount);
if (bytesAvailableCount == 0) {
if (receivedString.length() > 0) {
Log.d(TAG, "---------received string is ready: " + receivedString.toString() + "-----------");
final String tmpReceivedString = receivedString.toString();
receivedString.setLength(0);
//h.obtainMessage(RECEIVE_MESSAGE, bytes, -1, buffer).sendToTarget(); // Send to message queue Handler
uiHandler.post(new Runnable() {
@Override
public void run() {
if (listener != null) {
listener.onReceiveBluetoothData(tmpReceivedString);
}
}
});
}
continue;
}
} catch (IOException e1) {
Log.e(TAG, "an exception occured during available(): " + e1.getMessage());
if (listener != null) {
listener.onBluetoothError(ERROR_INPUTSTREAM_READ_FAILED);
}
break;
}
try {
//skipCount = 0;
Log.d(TAG, "bytesAvailableCount=" + bytesAvailableCount);
buffer = new byte[bytesAvailableCount];
// read is blocking and never returns "-1" : no end of input stream of bt socket
bytesReadCount = inStream.read(buffer, 0, buffer.length); // Get number of bytes and message in "buffer"
Log.d(TAG, "...read " + bytesReadCount + " bytes from InputStream");
if (bytesReadCount > 0) {
line = new String(buffer, 0, buffer.length, Charset.forName("UTF-8"));
//line = new String(buffer, Charset.forName("UTF-8"));
Log.d(TAG, "received line: " + line + ", appending to receivedString...");
receivedString.append(line);
}
} catch (IOException e2) {
Log.e(TAG, "an exception occurred during read: " + e2.getMessage());
if (listener != null) {
listener.onBluetoothError(ERROR_INPUTSTREAM_READ_FAILED);
}
break;
}
}
} else {
Log.e(TAG, "inputstream is null");
if (listener != null) {
listener.onBluetoothError(ERROR_INPUTSTREAM_GET_FAILED);
}
return;
}
//}
Log.d(TAG, "closing inputStream");
try {
//bufferedReader.close();
inStream.close();
} catch (IOException e) {
Log.d(TAG, "an exception occured during close()");
}
}
} |
|
Дело в том, что поток всегда застревает на вызове "read", в том случае, если в данный момент туда ничего не пришло, и никогда не возвращает "-1". Поэтому перед вычитыванием вызовом "read" порциями входную строку я поставил available(), чтобы делать это только тогда, когда фактическое количество доступных для чтения байт > 0 и также отводить ровно такой размер для байтового буфера, в который эти байты будут складываться. Так вот проблема в том, что на одном девайсе представленный выше алгоритм работает на ура (т.е. когда количество доступных байт на каждой итерации возвращается либо 0 либо >0), а на другом девайсе, когда в InputStream сокета ничего не приходит, на вызове available() поток с какого-то х.я ЗАВИСАЕТ, так же как на read, хотя вызов available не должен быть блокирующим. Соот-но я также не могу определить момент "готовности" текущей строки для оповещения об этом "слушателя".
Касаемо InputStreamReader, его read напрочь отказывается читать оттуда, т.е. даже если что-то пришло, он всё равно будет висеть.
Какие есть предложения?