繁体   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