![](/img/trans.png)
[英]How to handle InputStream and OutputStream via Bluetooth in Android
[英]Android Bluetooth periodic calls to inputStream and outputStream: inconsistent timestamps
連接了兩個藍牙設備。 一個通過outputStream發送一個周期性時間戳(writeTime)到另一個,后者通過inputStream檢索writeTimes並附加自己的時間戳(readTime)進行比較。 我的目標是使每個循環的readTime等於writeTime。 下面的代碼使writeTimes以預定的延遲(3秒)遞增,但readTimes不會遞增。 當兩個設備相互連接時,讀取時間是固定的。 以下是outputStream.write和inputStream.read的片段以及示例結果。
對於發送設備:在計時器內循環,在兩次寫入outputStream之間有三秒的延遲:有一個CountDownTimer驅動onTick
public void onTick(long millisUntilFinished) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat mdformat = new SimpleDateFormat("HH:mm:ss");
String thisTime = mdformat.format(calendar.getTime());
tV.setText("Current Time: " + thisTime); // thisTime increments on the display in real time.
try {
thisTime=thisTime+ "^"; // "^" added as the end of a line
outputStream.write(thisTime.getBytes(Charset.forName("UTF-8")));
} catch (IOException e) {}
對於接收設備:一個讀取循環(iloop),它與發送方的寫入循環重復相同的次數:
for (iloop =1;iloop<6;iloop++) {
inputStream = socket.getInputStream();
byte[] inbyte = new byte[1];
int inbuffer;
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
writeTime = "";
eol = false;
do {
inbuffer = br.read();
if (inbuffer != 94) { // character "^" (byte 94) triggers an end-of-line for each read.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(inbuffer);
inbyte = bos.toByteArray();
next = new String(inbyte, "UTF-8");
writeTime = writeTime + next;
} else {eol = true;}
} while (!eol);
readTime = mdformat.format(calendar.getTime());
readarray[iloop] = "\r\n" + writeTime + " " + readTime ;
}
}
readarray寫入后的屏幕截圖:(五行循環,兩次寫入之間有3秒的延遲):
14:44:12 14:44:02
14:44:15 14:44:02
14:44:18 14:44:02
14:44:21 14:44:02
14:44:24 14:44:02
結論:正在使用與套接字連接的開始相等的時間戳讀取inputStream。 (在示例輸出中,我在連接后等待了十秒鍾,然后才開始寫入outputStream)。 如何獲取readTime以反映writeTime? 我的最終目標是以周期性的速率從inputStream讀取數據,而不是批量處理單個批處理中的大量小讀取。 我想實時訪問每個讀取,並知道讀取發生的時間。
這篇文章的更新:我從Ole VV獲得了見識,並將以下三行代碼從讀取循環(iloop)外部移到了readTime上方的INSIDE內部
Calendar calendar = Calendar.getInstance();
SimpleDateFormat mdformat = new SimpleDateFormat("HH:mm:ss");
String strDate;
這樣就解決了問題。 我應該知道,日歷是Calendar的一個實例,其特性calendar.getTime()不會隨着時鍾的滴答而改變。 盡管Ole VV建議更換它,但過時的SimpeDateFormat並沒有錯,在其他應用程序中可能很有用。
將當前時間(例如,從流中讀取的時間)放入字符串中:
DateTimeFormatter timeFormatter
= DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
String readTime = LocalTime.now(ZoneId.of("America/Dawson"))
.format(timeFormatter);
可以在循環外部創建DateTimeFormatter
,但是必須在循環內部調用LocalTime.now
才能獲取當前迭代的時間。
在我的語言環境中,示例結果是字符串11.57.13
。 請替換您要放置美國/道森的所需時區。
我使用的是現代Java日期和時間API java.time,因為您使用的日期和時間類Calendar
和SimpleDateFormat
始終存在設計問題,並且現在已經過時了。 考慮不再使用它們。
您尚未提供完整的示例,因此問題中的代碼片段無法按現狀進行編譯和運行,而我也無法做到。 但是, 似乎您已經在循環外創建了Calendar
對象,並且以后沒有修改該Calendar
對象的時間。 因此,它保持其時間,而時間就是您每次循環所獲得的時間。 (相比之下,在書寫方面,每次onTick
調用都在創建一個新的Calendar
對象,這就是每次獲取當前時間的原因。)
是的, java.time
在較新和較舊的Android設備上java.time
正常運行。 它至少需要Java 6 。
org.threeten.bp
和子包中導入日期和時間類。 java.time
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.