为没有回调的传感器创建活套?

时间:2014-09-03 05:52:37

标签: android android-ndk android-looper

我正在开展一个想要简单采样Android传感器的项目。在这里,简单地说是大约200到400毫秒(关于眨眼间的字面意思)。

我想避免使用Android的异步,并使用ALooper_pollOnceALooper_pollAll。避免它简化了编程和审计,因为我可以使用梯形图而不是状态机来建模系统。时间非常短暂,在实践中不应成为问题。

以下代码:

#include "android_native_app_glue.h"
...

// Should be defined in app_glue
#ifndef LOOPER_ID_USER
# define LOOPER_ID_USER 3
#endif
...

static const int LOOPER_ID_PRNG = LOOPER_ID_USER + 1;
...

ALooper* looper = ALooper_forThread();
if (looper == NULL)
    looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
...

ASensorEventQueue* queue = ASensorManager_createEventQueue(sensorManager,
    looper, LOOPER_ID_PRNG, NULL /*SensorEvent*/,
    reinterpret_cast<void*>(&context));

在logcat中导致以下错误:

09-03 01:30:00.100: E/Looper(4026): Invalid attempt to set NULL callback but not 
                                    allowed for this looper.

如何创建允许轮询的looper?或者,如果存在looper,如何修改它以允许轮询?


struct Sensor {
    Sensor() :
        m_type(-1), m_sensor(NULL) {
    }

    explicit Sensor(int type, string name, const ASensor* sensor) :
        m_type(type), m_name(name), m_sensor(sensor) {
    }

    int m_type;
    string m_name;
    const ASensor* m_sensor;
};

typedef vector<Sensor> SensorList;

static SensorList s_list;
// Double checked initialization omitted

ASensorList sensorList;
ASensorManager* sensorManager = ASensorManager_getInstance();

int n = ASensorManager_getSensorList(sensorManager, &sensorList);

if( n < 0)
{
    LOG_ERROR("SensorList: failed to retrieve list");
}
else if (n == 0)
{
    LOG_DEBUG("SensorList: no sensors available");
}
else
{
    s_list.reserve(static_cast<size_t>(n));

    for (int i = 0; i < n; i++)
    {
        const ASensor* sensor = sensorList[i];
        if (sensor == NULL)
            continue;

        const char* name = ASensor_getName(sensor);
        const char* vendor = ASensor_getVendor(sensor);
        int type = ASensor_getType(sensor);
        int min_delay = ASensor_getMinDelay(sensor);
        float resolution = ASensor_getResolution(sensor);

        LOG_DEBUG("SensorList: %s (%s) %d %d %f", name, vendor, type, min_delay, resolution);

        // These sensors require callbacks. Avoid them for simplicity.
        if (type == ASENSOR_TYPE_LIGHT || min_delay == 0)
            continue;

        s_list.push_back(Sensor(type, name, sensor));
    }
}

下面,光传感器需要回调,因为它的min_delay为0.它没有添加到SensorList。其他传感器已添加到SensorList

输出是由这一行创建的:

LOG_DEBUG("SensorList: %s (%s) %d %d %f", name, vendor, type, min_delay, resolution);
D/PRNG ( 3950): SensorList: MPL rotation vector (Invensense) 11 20000 1.000000
D/PRNG ( 3950): SensorList: MPL linear accel (Invensense) 10 20000 1.000000
D/PRNG ( 3950): SensorList: MPL gravity (Invensense) 9 20000 1.000000
D/PRNG ( 3950): SensorList: MPL Gyro (Invensense) 4 20000 1.000000
D/PRNG ( 3950): SensorList: MPL accel (Invensense) 1 20000 1.000000
D/PRNG ( 3950): SensorList: MPL magnetic field (Invensense) 2 20000 1.000000
D/PRNG ( 3950): SensorList: MPL Orientation (Invensense) 3 20000 1.000000
D/PRNG ( 3950): SensorList: Lite-On al3000a Ambient Light Sensor (Lite-On) 5 0 1.000000
D/PRNG ( 3950): SensorList: added 7 sensors

1 个答案:

答案 0 :(得分:1)

这部分

ALooper* looper = ALooper_forThread();
if (looper == NULL)
    looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);

可以简化为

ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);

ALooper_prepare返回与该帖子相关联的looper(如果存在),根据looper.h中的文档,这甚至可以解决您的问题b / c它可能会更改looper所以它允许非回调,但我不确定。

虽然你应该知道你应该自己完全控制弯针,即如果一个弯针已经在其他地方进行了调查,我认为你不能在没有干扰的情况下自己轮询同一个弯针。因此,要么在android_native_app_glue中修改looper,要么在新主题中编写新的looper。这是我的理解。