android - 在辅助线程中接收传感器事件(Android native )

标签 android multithreading android-ndk sensors

我尝试在Android native 层中获取传感器数据,并且它起作用了。现在,

我想在辅助线程中接收传感器数据。这是我的代码,首先,

调用 native 函数 HelloThread ,它将创建一个线程来

注册并接收传感器数据,但是失败,回调get_sensor_events

尚未被调用。

提前致谢。

void* threadFunction(void* irrelevant)
{
    int tid = syscall(__NR_gettid);
    LOGI("thread id(thread function) = %d", tid);

    looper = ALooper_forThread();

    while(looper == NULL)
    {
        looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);

        if(looper == NULL)
            continue;
        else
            break;
    }

    LOGI("Finished prepare");

    sensorManager = NULL;
    accSensor = NULL;
    gyroSensor = NULL;
    magSensor = NULL;

    sensor_data = (void*)malloc(1000);

    if(looper == NULL)
        LOGI("Looper is null");

    sensorManager = ASensorManager_getInstance();

    if(sensorManager == NULL)
        LOGI("sensorManager == NULL");

    accSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
    gyroSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_GYROSCOPE);
    magSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_MAGNETIC_FIELD);

    if(accSensor == NULL)
        LOGI("accSensor == NULL");
    if(gyroSensor == NULL)
        LOGI("gyroSensor == NULL");
    if(magSensor == NULL)
        LOGI("magSensor == NULL");

    sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper, 3, get_sensor_events, sensor_data);

    LOGI("Finished ASensorManager_createEventQueue()");

    if(accSensor)
    {   
        ASensorEventQueue_enableSensor(sensorEventQueue, accSensor);
        ASensorEventQueue_setEventRate(sensorEventQueue, accSensor, 20000);
    }
    if(gyroSensor)
    {
        ASensorEventQueue_enableSensor(sensorEventQueue, gyroSensor);
        ASensorEventQueue_setEventRate(sensorEventQueue, gyroSensor, 20000);
    }
    if(magSensor)
    {
        ASensorEventQueue_enableSensor(sensorEventQueue, magSensor);
        ASensorEventQueue_setEventRate(sensorEventQueue, magSensor, 20000);
    }

    LOGI("Finish enable sensor");

    HasAllocateLooper = true;
}

static int get_sensor_events(int fd, int events, void* data) {
  ASensorEvent event;

  int tid = syscall(__NR_gettid);
  LOGI("thread id(get sensor data) = %d", tid);

  while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0) {
        if(event.type == ASENSOR_TYPE_ACCELEROMETER) {
            LOGI("Acc:%f,%f,%f, time = %f", event.acceleration.x, event.acceleration.y, event.acceleration.z, ((double)(event.timestamp-lastAccTime))/1000000000.0);
            lastAccTime = event.timestamp;
        }
        else if(event.type == ASENSOR_TYPE_GYROSCOPE) {
            LOGI("Gyro:%f,%f,%f, time = %f", event.acceleration.x, event.acceleration.y, event.acceleration.z, ((double)(event.timestamp-lastGyroTime))/1000000000.0);
            lastGyroTime = event.timestamp;
        }
        else if(event.type == ASENSOR_TYPE_MAGNETIC_FIELD) {
            LOGI("Mag:%f,%f,%f, time = %f", event.acceleration.x, event.acceleration.y, event.acceleration.z, ((double)(event.timestamp-lastMagTime))/1000000000.0);
            lastMagTime = event.timestamp;
        }
  }
  //should return 1 to continue receiving callbacks, or 0 to unregister
  return 1;
}

JNIEXPORT jint JNICALL Java_asus_ndksample_MainActivity_HelloThread
(JNIEnv * env, jobject obj)
{
    int tid = syscall(__NR_gettid);
    LOGI("thread id(Java thread) = %d", tid);

    int ret = 0;

    pthread_t hThread;
    pthread_create(&hThread, NULL, &threadFunction, (void *)1);

    while(true)
    {
        if(HasAllocateLooper)
        {
            break;
        }
    }
    return ret;
}

最佳答案

您必须将ALOOPER_POLL_CALLBACK作为参数ident传递给ASensorManager_createEventQueue()

关于android - 在辅助线程中接收传感器事件(Android native ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30770904/

相关文章:

android - 隐藏安卓 fragment

android - 为什么即使在android :targetSdkVersion = "25"?中Uri.fromFile也没有问题

java - 同步方法是否会阻止对象字段被更新?

android - 错误 : undefined reference to 'av_free_packet(AVPacket*)' when use NDK to compile ffmpeg

Android cmake 不同的abi

android - AppCompatActivity 在工具栏中设置 Logo

android - 所有 firebase 依赖项的版本都是相同的,应用程序仍然会在启动后立即崩溃

c# - 如何使用 foreach 循环制作多线程应用程序

java - Android FileChannel 在不同的 AsyncTask 中读写失败

android NDK,在另一个android NDK项目中使用已编译的.so库中的函数