计划按以下的内容更新
Sensor 使用
关于 Sensor
在 Android 中 sensor(传感器) 包含很多种类,目前已定义的有33种。sensor 就类似人的感官,把感受到的信息传回来,比如常用的亮度、距离、磁场、加速度、温度、湿度、记步、心率等等。而且随着科技和材料学的发展,更多的 sensor 将被发明或应用到手机上,也许将来会发明探测心动指数的 sensor,为程序猿们脱单指引正确方向。
其实每个 sensor 不一定会对应一个硬件,有可能是一个硬件同时实现了几种 sensor,或某个 sensor 是个纯软件实现的,比如我们常用的记步器,它就是一个软件实现的,只要手机中有加速度传感器或重力传感器,通过手机加速度的变化可推测出是否行走及步数,之所以用"推测"而不是”推算"是因为即使每家的算法有所不同,这个结果是靠算法"推测"出来的。因此都会有误差,这也就是不同手机出来的步数都不同的原因。
关于 sensor 详细的信息可以参考官方文档。
正因为有了各种 sensor,这就让在手机上能写出比电脑上更好玩的应用。
Sensor 使用
关于 sensor 的开发,代码比较简单,以下代码就得到了一个加速度传感器的对象。
// 得到 SensorManager
sensorManager := sensor.ManagerInstance()
// 得到默认的加速度传感器
accSensor := sensorManager.GetDefaultSensor(sensor.TYPE_ACCELEROMETER)
然后在需要处理加速度信息时调用 accSensor.Enable(),之后 app.Callbacks.Sensor 回调就会被不停的被调用并传回 []sensor.Event ,它里面就有加速度变化的信息。
在不需要接收 sensor 事件时,要及时 accSensor.Disable() ,注意如果没有 Disable,即使应用在后台,只要没被系统回收,应用还是会收到 sensor 事件,会影响系统性能并导致电量消耗增加。
sensor.Event 说明
之前提到过 app.Callbacks 回调中有个 Sensor(act *app.Activity, events []sensor.Event) 回调,它会传入一个sensor.Event 数组,之所以传数组是因为 sensor.Event 太多(很多 sensor 默认10ms一个),同时也要注意在此回调里代码需"简短"以避免出现性能问题。
对 sensor.Event 的处理,请参考示例,
它有两个函数要特别说一下
GetTimestamp() time.Duration 返回的是一个开机以来的时间,意思是这个 Event 是在这个时间采集到的。对时间敏感的应用需要用这个时间,而不能用处理 Event 时的当前时间。
GetData(interface{}) 之所以传入interface{},是因为不同类型的 sensor 要通过 GetData 得到它不同类型的值(在 C 中它是个 union ),这个值的结构和用法官方文档有详细说明。根据说明定义好数据结构,记得传入指针。比如对记步器要这样 var v int64; event.GetData(&v) 。
Sensor 进阶
Sensor 对象还有如下几个函数:
// Returns this sensor's name
func (sensor *Sensor) GetName() string
// Returns this sensor's vendor's name
func (sensor *Sensor) GetVendor() string
// Returns this sensors's resolution
func (sensor *Sensor) GetResolution() float32
// Returns the 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.
func (sensor *Sensor) GetMinDelay() time.Duration
// Sets the delivery rate of events in microseconds for the given sensor.
//
// This function has to be called after Enable.
// Note that this is a hint only, generally event will arrive at a higher
// rate. It is an error to set a rate inferior to the value returned by
// GetMinDelay().
func (s *Sensor) SetEventRate(act *Activity, t time.Duration)
特别说明一下 SetEventRate,它用于设置此 sensor 发送事件的频率,比如 SetEventRatet(act, time.Millisecond*100) 时就是希望它每100ms发一个 event(一秒10个),没错,刚才用的是"希望",这也是我们需要注意的地方,它只是一个你的意愿,实际结果不同的 sensor,不同的平台都不同,比如说计步器,不管你设置多快,你不走他也没必要发个 event 给你,在我的手机上也有些 sensor 不管你怎么设置,就是按它的节奏发。原则上,如果你不需要这么高频率的采样率,就尽量把时间设置长一点,至少有可能省电 ^_^ 。
几个要点:
及时 Disable ,如不需要在后台处理,在应用失去焦点时就要调用
尽量设置较长的采样时间
Sensor 事件较多,处理需要优化,比如自己维护一个事件队例,过滤(忽略)掉不重要的事件。
从 参考示例,可看到这些函数的用法,也可通过它(或修改它)来观察你的手机上 Sensor 的表现。
Sonsor 一些应用场景
现在知道怎样使用 sensor 了,象 《3D滚球》之类的游戏就可以自己写一个了,只要打开重力加速度(SENSOR_TYPE_ACCELEROMETER 或 SENSOR_TYPE_GRAVITY)根据X,Y,Z 轴不同的值,就知道手机的倾斜度了。
还有用 SENSOR_TYPE_ORIENTATION 可以来实现一个简单的指南针。或用 SENSOR_TYPE_MAGNETIC_FIELD 实现一个复杂的。
或通过 SENSOR_TYPE_LIGHT 来实现自动开灯(智能家居)。
也可开开脑洞,把手机挂在窗外探测风向/风速。
总之随着 sensor 的多元化,手机的"感官"越多,用手机应用能做的事就越多,开发的乐趣就越大。