Android系统内置对传感器有很多,它们分别是:加速度传感器gsensor(accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等。

Android实现传感器系统代码位置在

  framework层: frameworks\base\core\java\android\hardware\目录下

    Sensor.java

    SensorEventListener.java 

    SensorListener.java

    SensorManager.java

jni :frameworks\base\core\jni

                         android_hardware_SensorManager.cpp

hal层,这个每个平台的代码位置可能不一样,我现在分析4.4MTK的

       mediatek\hardware\sensor

Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,Android中Sensor的HAL接口定义在:hardware/libhardware/include/hardware/sensors.h

对传感器类型的定义:


传感器模块的定义结构体如下:


该接口的定义实际上是对标准的硬件模块hw_module_t的一个扩展,增加了一个get_sensors_list函数,用于获取传感器的列表。


对任意一个sensor设备 都会有一个 sensor_t 结构体,其定义如下:


struct sensor_t {
    /* name of this sensors */
    const char*     name;
    /* vendor of the hardware part */
    const char*     vendor;
    /* version of the hardware part + driver. The value of this field
     * must increase when the driver is updated in a way that changes the
     * output of this sensor. This is important for fused sensors when the
     * fusion algorithm is updated.
     */    
    int             version;
    /* handle that identifies this sensors. This handle is used to activate
     * and deactivate this sensor. The value of the handle must be 8 bits
     * in this version of the API. 
     */
    int             handle;
    /* this sensor's type. */
    int             type;
    /* maximaum range of this sensor's value in SI units */
    float           maxRange;
    /* smallest difference between two values reported by this sensor */
    float           resolution;
    /* rough estimate of this sensor's power consumption in mA */
    float           power;
    /* minimum delay allowed between events in microseconds. A value of zero
     * means that this sensor doesn't report events at a constant rate, but
     * rather only when a new data is available */
    int32_t         minDelay;

    /* reserved fields, must be zero */
    void*           reserved[8];
};

下面来分析hal流程:

 加载JNI时根据模块会找到sensor.c

 

由上面可以看出来open_sensors是整个加载流程入口


函数操作集合赋值,看到new了一个sensors_poll_context_t类,看看到底这里都做了什么

struct sensors_poll_context_t {
    struct sensors_poll_device_t device; // must be first
        sensors_poll_context_t();
        ~sensors_poll_context_t();
    int activate(int handle, int enabled);
    int setDelay(int handle, int64_t ns);
    int pollEvents(sensors_event_t* data, int count);
private:
    enum {
        hwmsen        = 0, 
        accel,
        magnetic,
        //gyro,
        //light,
        //proximity,
        //pressure,
        numSensorDrivers,
        numFds,
    };
int handleToDriver(int handle) const {
        switch (handle) {
            case ID_ACCELEROMETER:
return accel;
            case ID_MAGNETIC:
            case ID_ORIENTATION:
return magnetic;
            case ID_PROXIMITY:
//return proximity;
            case ID_LIGHT:
//return light;
            case ID_GYROSCOPE:
//return gyro;
case ID_PRESSURE:
break;
//return pressure;
        }
        return -EINVAL;
    }


    static const size_t wake = numFds - 1;
    static const char WAKE_MESSAGE = 'W';
    struct pollfd mPollFds[numFds];
    int mWritePipeFd;
    SensorBase* mSensors[numSensorDrivers];
};

构造函数


重点来看pollEvents函数


poll是真正实现查询事件

int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
{
    int nbEvents = 0;
    int n = 0;
//ALOGE("pollEvents count =%d",count );


    do {
        // see if we have some leftover from the last poll()
        for (int i=0 ; count && i             SensorBase* const sensor(mSensors[i]);
            if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) {
                int nb = sensor->readEvents(data, count);
                if (nb < count) {
                    // no more data for this sensor
                    mPollFds[i].revents = 0;
                }
                //if(nb < 0||nb > count)
                // ALOGE("pollEvents count error nb:%d, count:%d, nbEvents:%d", nb, count, nbEvents);//for sensor NE debug
                count -= nb;
                nbEvents += nb;
                data += nb;
                //if(nb < 0||nb > count)
                // ALOGE("pollEvents count error nb:%d, count:%d, nbEvents:%d", nb, count, nbEvents);//for sensor NE debug
            }
        }
        if (count) {
            // we still have some room, so try to see if we can get
            // some events immediately or just wait if we don't have
            // anything to return
            
            n = poll(mPollFds, numFds, nbEvents ? 0 : -1);
            if (n<0) {
                ALOGE("poll() failed (%s)", strerror(errno));
                return -errno;
            }
            if (mPollFds[wake].revents & POLLIN) {
                char msg;
                int result = read(mPollFds[wake].fd, &msg, 1);
                ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
                ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
                mPollFds[wake].revents = 0;
            }
        }
        // if we have events and space, go read them
    } while (n && count);
    return nbEvents;
}





更多相关文章

  1. android 自定义checkbox (转)
  2. TabHost 相关解决
  3. Android的ProgressBar自定义入门
  4. android的style控制Theme
  5. telephony
  6. android5.0以上对于APP_SWITCH和HOME键的处理
  7. Android(安卓)开机启动过程
  8. android 自定义时间控件
  9. 箭头函数的基础使用

随机推荐

  1. android fragment新手简单应用(实现界面之
  2. Android(安卓)数据表的更新的 解决方案?
  3. Android实现拍照或从相册中获取图片并且
  4. 关于Unity发布苹果并真机测试的设置与连接
  5. Android中实现native服务利用binder与应
  6. Android的签名文件生成两种方法
  7. 避免Drawable保持引用的内存泄露
  8. android textview 排版混乱问题
  9. Android怎么解决不同版本SDK的兼容性问题
  10. php运行过程和数据类型