Я пытаюсь получить доступ к акселерометру из 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 каждые 10 секунд из IntentService
(чтобы убедиться, что он работает, даже если само приложение убито). Теперь я ожидаю получить 100 значений (10 в секунду * 10 секунд). В разных тестах я получил около 130, что также вполне нормально для меня, даже если немного. Затем я прочитал в документации ASensorEventQueue_setEventRate
, что он не обязан следовать заданному периоду обновления. Так что, если бы я получил больше, чем хотел, все было бы прекрасно.
Но теперь проблема: иногда я получаю 13 значений за 10 секунд, а когда я продолжаю вызывать update
10 секунд спустя, я получаю 130 значений + пропущенные 117 прогонов до этого. Это происходит совершенно случайно, и иногда это не следующий прогон, а четвертый после или что-то в этом роде.
Я полностью согласен с выходом из периода обновления, имея больше значений. Но кто-нибудь может объяснить, почему так много значений пропущено, и они появятся через 10 секунд при следующем запуске? Или, может быть, есть способ убедиться, что я получу их в нужном порядке?