我尝试从NDK访问加速度计。到目前为止,它可以正常工作。但是将事件写入事件队列的方式似乎有点奇怪。
请参阅以下代码:
请参阅以下代码:
ASensorManager* AcquireASensorManagerInstance(void) {
typedef ASensorManager *(*PF_GETINSTANCEFORPACKAGE)(const char *name);
void* androidHandle = dlopen("libandroid.so", RTLD_NOW);
PF_GETINSTANCEFORPACKAGE getInstanceForPackageFunc = (PF_GETINSTANCEFORPACKAGE) dlsym(androidHandle, "ASensorManager_getInstanceForPackage");
if (getInstanceForPackageFunc) {
return getInstanceForPackageFunc(kPackageName);
}
typedef ASensorManager *(*PF_GETINSTANCE)();
PF_GETINSTANCE getInstanceFunc = (PF_GETINSTANCE) dlsym(androidHandle, "ASensorManager_getInstance");
return getInstanceFunc();
}
void init() {
sensorManager = AcquireASensorManagerInstance();
accelerometer = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
accelerometerEventQueue = ASensorManager_createEventQueue(sensorManager, looper, LOOPER_ID_USER, NULL, NULL);
auto status = ASensorEventQueue_enableSensor(accelerometerEventQueue,
accelerometer);
status = ASensorEventQueue_setEventRate(accelerometerEventQueue,
accelerometer,
SENSOR_REFRESH_PERIOD_US);
}
这是我初始化所有内容的方式。我的SENSOR_REFRESH_PERIOD_US为100,000,因此每秒刷新10次。现在我有以下方法来接收事件队列中的事件。
vector<sensorEvent> update() {
ALooper_pollAll(0, NULL, NULL, NULL);
vector<sensorEvent> listEvents;
ASensorEvent event;
while (ASensorEventQueue_getEvents(accelerometerEventQueue, &event, 1) > 0) {
listEvents.push_back(sensorEvent{event.acceleration.x, event.acceleration.y, event.acceleration.z, (long long) event.timestamp});
}
return listEvents;
}
sensorEvent
这里是我使用的一个自定义结构体。这个 update
方法会通过 JNI 从 Android 调用,在每个来自 IntentService
的 10 秒钟中运行一次(即使应用程序已经被杀死)。现在,我希望能够收到 100 个数值(每秒 10 次 * 10 秒)。在不同的测试中,我收到了大约 130 个数值,即使有点偏差也完全可以接受。然后,我在 ASensorEventQueue_setEventRate
的文档中读到,它并不强制遵循给定的刷新周期。因此,如果我得到的数值比我想要的更多,那么完全没问题。
但现在问题来了:有时我在 10 秒内只收到了 13 个值,当我在 10 秒后继续调用 update
时,我会得到 130 个值 + 上一次丢失的 117 个值。这种情况完全是随机出现的,有时候不是下一次运行就是第四次之后才出现这种情况。
如果我获得了更多的值而与刷新周期有所偏差,那我完全可以接受。但是否有人能解释一下为什么会有这么多的值丢失,而它们会在下一次运行时出现?或者是否有方法可以确保我在期望的运行中收到这些值?