簡體   English   中英

Android Bluetooth定期調用inputStream和outputStream:時間戳不一致

[英]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並沒有錯,在其他應用程序中可能很有用。

java.time

將當前時間(例如,從流中讀取的時間)放入字符串中:

    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,因為您使用的日期和時間類CalendarSimpleDateFormat始終存在設計問題,並且現在已經過時了。 考慮不再使用它們。

您的代碼出了什么問題?

您尚未提供完整的示例,因此問題中的代碼片段無法按現狀進行編譯和運行,而我也無法做到。 但是, 似乎您已經在循環外創建了Calendar對象,並且以后沒有修改該Calendar對象的時間。 因此,它保持其時間,而時間就是您每次循環所獲得的時間。 (相比之下,在書寫方面,每次onTick調用都在創建一個新的Calendar對象,這就是每次獲取當前時間的原因。)

問題:我可以在Android上使用java.time嗎?

是的, java.time在較新和較舊的Android設備上java.time正常運行。 它至少需要Java 6

  • 在Java 8和更高版本以及新的Android設備(API級別26)中,內置了新API。
  • 在Java 6和7中,獲取ThreeTen Backport,即新類的backport(用於JSR 310的ThreeTen,首次描述了現代API)。
  • 在(較舊的)Android上,使用Android版本的ThreeTen Backport。 它稱為ThreeTenABP。 確保從包org.threeten.bp和子包中導入日期和時間類。

鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM