我有一个自制的蓝牙设备,以500Hz的频率测量ECG:每2毫秒该设备发送9字节的数据(标头,ECG测量,页脚)。因此,这大约是9 * 500 =4.5kbytes / s的数据流。
我有一个C ++ Windows程序,能够连接设备并检索数据流(使用Qt/qwt显示)。在这种情况下,我使用Windows控制面板绑定设备,并使用boost
serial_port接口通过虚拟COM端口将其连接。这非常有效,并且我实时接收数据流:每2毫秒左右获得一个测量点。
我通过QtCreator 3.0.1(Qt5.2.1)在Android上移植了整个程序。似乎虚拟COM端口不能通过boost访问(可能是SDK权限不允许这样做),所以我写了一段Java代码来打开和管理蓝牙连接。因此,我的应用程序仍然是C++ /Qt,但是只有在Java中对连接和从设备读取数据的层进行了重新处理(使用createInsecureRfcommSocketToServiceRecord打开连接):
Java代码读取数据:
public int readData( byte[] buffer )
{
if( mInputStream == null )
{
traceErrorString("No connection, can't receive data");
}
else
{
try
{
final boolean verbose = false;
int available = mInputStream.available();
if ( verbose )
{
Calendar c = Calendar.getInstance();
Date date = new Date();
c.setTime(date);
c.get(Calendar.MILLISECOND);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentTime = sdf.format(date);
traceDebugString( currentTime + ":" + c.get(Calendar.MILLISECOND) + " - " + available + " bytes available, requested " + buffer.length );
}
if ( available >= buffer.length )
return mInputStream.read( buffer ); // only call read if we know it's not blocking
else
return 0;
}
catch (IOException e)
{
traceDebugString( "Failed to read data...disconnected?" );
}
}
return -1;
}
像这样从C ++调用:
bool ReceiveData( JNIEnv* env,
char* data,
size_t length,
bool& haserror )
{
bool result = false;
jbyteArray array = env->NewByteArray(length);
jint res = env->CallIntMethod(j_object, s_patchIfReceiveDataID, array );
if ( static_cast<size_t>(res) == length )
{
env->GetByteArrayRegion(array, 0, length, reinterpret_cast<jbyte*>(data));
result = true;
}
else if ( res == -1 )
{
haserror = true;
}
else
{
// not enough data in the stream buffer
haserror = false;
}
return result;
}
bool readThread( size_t blockSize )
{
BTGETANDCHECKENV // retrieving environment
char* buf = new char[blockSize];
bool haserror = false;
while ( !haserror )
{
if ( !ReceiveData( env, buf, blockSize, haserror ) )
{
// could not read data
if ( haserror )
{
// will stop this thread soon
}
else
{
boost::this_thread::sleep( boost::posix_time::milliseconds( 10 ) );
}
}
}
delete [] buf;
return true;
}
这很好用… 在头五个秒中, 我实时获取了值,然后:
将verbose设置为true时,日志如下所示:
14:59:30:756 - 0 bytes available, requested 3
14:59:30:767 - 0 bytes available, requested 3
14:59:30:778 - 0 bytes available, requested 3
14:59:30:789 - 1728 bytes available, requested 3
14:59:30:790 - 1725 bytes available, requested 6
14:59:30:792 - 1719 bytes available, requested 3
我的ECG设备绝对没有在11毫秒内发送1728字节!
我知道我的设备每2ms发送9个字节(否则,它将无法在我的PC应用程序上运行)。看起来Java进行了一些意外的缓冲,并且不会每2ms提供9个字节…。同样奇怪的是,在开始时仅5秒就可以正常工作。
请注意,我尝试使用read()而不检查available()(阻止版本),但是体验完全相同。
所以我想知道我做错了什么…
任何帮助或想法都将受到欢迎!
编辑:我在Nexus 5手机,Android 4.4.2上遇到了这种情况,我刚刚在不同设备上测试了相同的APK包:
编辑:因为我没有答案:-(我试图使用纯Java程序(没有C++,没有Qt)做同样的事情。
这个问题显然类似于这里报告的问题。
5秒后,我要么失去了连接,要么实时流变得非常慢。
如此处所述Android>4.3显然不喜欢超过5秒的单向通信。因此,我现在每隔1秒向设备发送一个虚拟命令(有点“ keep-
alive”命令),现在Android很高兴,因为它不再是单向通信了……所以数据流在之后第五秒比以前!
问题内容: 是否有使用Java直播视频的良好库?理想情况下,管道的两端都应使用Java编写,但我最关心的是视频播放器。您会推荐什么软件? 更新 :似乎VLC引入了1-2秒的延迟。我需要真正的实时视频流。记录到播放的延迟必须小于300ms。 问题答案: 我见过的最好的视频播放/编码库是ffmpeg。它播放您扔给它的所有内容。(它是MPlayer使用的。)它是用C编写的,但是我发现了一些Java包装器
问题内容: 我正在使用具有以下功能的simplehtmldom: 我这样使用它: 有时,URL可能只是无效的,我想对此进行处理。我以为我可以使用try and catch,但是这没有用,因为它不会抛出异常,它只是给出了这样的php警告: 第39行在上面的代码中。 我如何正确处理此错误,我可以只使用普通条件,它看起来不像返回布尔值。 谢谢大家的帮助 更新资料 这是一个好的解决方案吗? 问题答案: 这
问题内容: 关于如何在Hibernate实体和Web服务要返回的数据传输对象之间进行转换,我也有类似的问题和疑虑,如以下问题所述: 此处提到的因素之一是,如果域模型发生更改,则在Web服务的情况下,一组DTO将保护使用者。 即使看起来它将为我的项目添加大量代码,这种推理也似乎是合理的。 是否可以使用一种好的设计模式将一个Hibernate实体(实现一个接口)转换为一个实现相同接口的DTO? 因此,
问题内容: 关于如何在Hibernate实体和Web服务要返回的数据传输对象之间进行转换,我也有类似的问题和疑虑,如以下问题所述: 在ejb3中使用数据传输对象被认为是最佳实践 此处提到的因素之一是,如果域模型发生更改,则在Web服务的情况下,一组DTO将保护使用者。 即使看起来它将为我的项目添加大量代码,这种推理也似乎是合理的。 是否可以使用一种好的设计模式将Hibernate实体(实现一个接口
我正在构建一个有以下要求的应用程序,我刚刚开始使用Flink。 null null 谢谢并感激你的帮助。
问题内容: 当实现具有多个属性的类时(例如下面的玩具示例),处理哈希的最佳方法是什么? 我认为和应该是一致的,但是如何实现能够处理所有属性的适当的哈希函数呢? 问题答案: 对于相等的对象应返回相同的值。它也不应在对象的整个生命周期内发生变化。通常,您只为不可变的对象实现它。 一个简单的实现就是公正。这始终是正确的,但效果很差。 您的解决方案,返回一个属性元组的哈希,是很好的。但是请注意,您无需列出