Sensors API 文档
文章信息
文章
Contents |
Sensors
本文包括高层感应器,例如屏幕定向(横屏,竖屏)和 底层的实时感应器,例如加速度数据。
命名空间
QtMobility API 放在 QtMobility 的命名空间. 这是为以后Mobility APIs 集成到 Qt做准备. 参考Quickstart guide中的例子体会这个命名空间如何影响使用QtMobility的开发
感应器类型
设备上有很多种感应器,有些设备的感应器 Sensor API不支持,也可能Sensor API支持的感应器在某型设备上面没有。你可以使用 QSensor::sensorTypes() 方法来查看Sensor API可以调用的当前设备的感应器类型。
内建的感应器类型列表参见下面的 感应器类 章节。
约定习惯
如没有特别说明,感应器要使用右手直角坐标系。

为了能测量6个方向,引入了负数。

使用了关于坐标轴的旋转的地方,旋转要表示成右手系的选择。

总的来说,感应器的数据要以设备的上方的定向来取值。 如果数据要显示在屏幕上,那么数据需要变换,以符合用户界面的定向。某个感应器可能定义它的数据依赖于UI的定向,这会在感应器的文档中被注明。

使用感应器
感应器的运行周期通常是这样:
- 创建一个QSensor或其子类的实例,在堆或栈上。
- 根据应用的需要setup
- 开始接收数据
- 应用程序使用感应器数据
下面的例子在堆上和栈上创建感应器
// On the heap (deleted when this object is deleted)
QAccelerometer *sensor = new QAccelerometer(this);
// On the stack (deleted when the current scope ends)
QOrientationSensor orient_sensor;
获取感应器数据的通常模式
推荐使用读取类来处理感应器数据。尽管有些时候这样行不通,例如,你的目标设备有一种新的感应器,但是没有可用的读取类的C++头文件。
还好有Qt的 属性(property)系统,我们还是能获得感应器数据。这需要以下3条信息:
- 感应器类型
- 属性的名字或指标(index)
- 属性的类型(type)或兼容类型
来看一个如何获得加速度属性的例子。这段代码不需要在编译期链接到QAccelerometer 或QAccelerometerReading。
// start the sensor
QSensor sensor("QAccelerometer");
sensor.start();
// later
QSensorReading *reading = sensor.reading();
qreal x = reading->property("x").value<qreal>();
qreal y = reading->value(1).value<qreal>();
你可以在运行期获取所有这些信息。sensor_explorer 例子显示了关于可用感应器的信息。
前端,后端
感应器API有一个供应用开发者使用的前端,和一个供设备制造者写代码访问硬件的后端。做为应用开发者你不需要访问后端,但是通过后端理解工作原理很有帮助。
应用程序的命令通过QSensor传递给设备插件。数据通过QSensorReading类传回。

更多关于后端的信息参见感应器后端。 自定义感应器插件参看例子:Grue Plugin
主要的类
感应器API的主要有以下主要的类构成。
| QSensor | Represents a single hardware sensor |
| QSensorFilter | Efficient callback facility for asynchronous notifications of sensor changes |
| QSensorReading | Holds the readings from the sensor |
读取类
访问感应器数据的最佳方法是通过以下的类
| QAccelerometerReading | Reports on linear acceleration along the X, Y and Z axes |
| QAmbientLightReading | Represents one reading from the ambient light sensor |
| QCompassReading | Represents one reading from a compass |
| QMagnetometerReading | Represents one reading from the magnetometer |
| QOrientationReading | Represents one reading from the orientation sensor |
| QProximityReading | Represents one reading from the proximity sensor |
| QRotationReading | Represents one reading from the rotation sensor |
| QTapReading | Represents one reading from the tap sensor |
感应器类
这些类提供良好的包装以减少类型转换的需求。每个感应器类代表一个感应器API知道的感应器类型。注意运行时可以增加类型,详情请参看感应器类型。
| QAccelerometer | Convenience wrapper around QSensor |
| QAmbientLightSensor | Convenience wrapper around QSensor |
| QCompass | Convenience wrapper around QSensor |
| QMagnetometer | Convenience wrapper around QSensor |
| QOrientationSensor | Convenience wrapper around QSensor |
| QProximitySensor | Convenience wrapper around QSensor |
| QRotationSensor | Convenience wrapper around QSensor |
| QTapSensor | Convenience wrapper around QSensor |
过滤器类
类似于感应器类,这些类提供良好的包装以减少类型转换的需要。
| QAccelerometerFilter | Convenience wrapper around QSensorFilter |
| QAmbientLightFilter | Convenience wrapper around QSensorFilter |
| QCompassFilter | Convenience wrapper around QSensorFilter |
| QMagnetometerFilter | Convenience wrapper around QSensorFilter |
| QOrientationFilter | Convenience wrapper around QSensorFilter |
| QProximityFilter | Convenience wrapper around QSensorFilter |
| QRotationFilter | Convenience wrapper around QSensorFilter |
| QTapFilter | Convenience wrapper around QSensorFilter |
例子
这个最简单的例子参看\examples\sensors\accel。演示了如何使用filter来高效的获得sensor的读数进一步可以参考\examples\sensors\中的其他例子,关于QSensor::dataRate的设置。
accel.pro
TEMPLATE=app
TARGET=accel
QT=core
CONFIG+=mobility
MOBILITY+=sensors
SOURCES=main.cpp
main.cpp
#include <QtCore>
#include <qaccelerometer.h>
QTM_USE_NAMESPACE
class AccelerometerFilter : public QAccelerometerFilter
{
public:
bool filter(QAccelerometerReading *reading)
{
qDebug() << "acceleration: "
<< QString().sprintf("%0.2f %0.2f %0.2f",
reading->x(),
reading->y(),
reading->z());
return false; // don't store the reading in the sensor
}
};
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QAccelerometer sensor;
AccelerometerFilter filter;
sensor.addFilter(&filter);
sensor.start();
if (!sensor.isActive()) {
qWarning("Accelerometer didn't start!");
return 1;
}
return app.exec();
}

