已连接两个启用了蓝牙的设备。一个通过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并没有错,
答案 0 :(得分:1)
要将当前时间(例如,从流中读取的时间)放入字符串中:
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
对象的时间。因此,它保持其时间,而时间就是您每次循环所获得的时间。 (相反,在您的书写方面,您每次调用Calendar
时都会创建一个新的onTick
对象,这就是为什么您每次都获得当前时间。)
是的,java.time
在较新的Android设备上都能很好地工作。它只需要至少 Java 6 。
org.threeten.bp
和子包中导入日期和时间类。java.time
。