官网:https://developer.android.google.cn/guide/topics/sensors这里面就包含了很详细的使用说明,包含示例代码等。
传感器的坐标系定义,可查看SensorEvent类的文档说明,此类表示一个Sensor事件,并包含诸如传感器的类型,时间戳,准确性以及传感器的信息等信息。
相对于手机屏幕的默认方向定义了坐标系。设备的屏幕方向更改时,轴不交换。
X轴为水平并指向右侧,Y轴为垂直并指向上方,Z轴指向屏幕正面的外部。在此系统中,屏幕后面的坐标具有负Z值。如下图:
注意:此坐标系与Android 2D API中使用的坐标系不同,后者的原点位于左上角。
看上图的坐标系统,注意看箭头的方向,还有坐标原点是在屏幕中央,所以,对于重力传感器,手机向左倾斜是负数,向右倾斜是正数,向上倾斜是正数,向下倾斜是负数,对于z轴不太清楚具体怎么操作的,但是把手机水平放桌面上,翻转手机时z轴的值会变。
SensorEvent中的values属性(一个数组)就保存了x、y、z的值,分别对应values[0]、values[1]、values[2]。也不是所有的传感器都会有x、y、z三个值的,具体要看是什么样类型的传感器,不同类型传感器中的values值的含义也不相同,这些含义可以查看values属性的文档说明,其中重力传感器和加速度传感器的是一样的。
通常重力传感器用于确定设备在空间中相对屏幕的方向,比如是向左倾斜了还是向右倾斜了。
重力传感器使用示例(其他传感器使用方式类似):
class GravitySensor: SensorEventListener {
private val sensorManager = MyApplication.sInstance.getSystemService(Context.SENSOR_SERVICE) as SensorManager
private var gravitySensor: Sensor? = null
private lateinit var callback: (x: Float, y: Float, z: Float) -> Unit?
/** 启动重力传感器数据捕捉 */
fun start(callback: (x: Float, y: Float, z: Float) -> Unit?) {
this.callback = callback
if (gravitySensor == null) {
gravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
sensorManager.registerListener(this, gravitySensor, SensorManager.SENSOR_DELAY_NORMAL)
}
}
/** 停止重力传感器数据捕捉 */
fun stop() {
if (gravitySensor != null) {
sensorManager.unregisterListener(this, gravitySensor)
gravitySensor = null
}
}
/** 当所登记的传感器的精确度已经改变时调用。*/
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
}
/** 当有新的传感器的事件时调用 */
override fun onSensorChanged(event: SensorEvent) {
// values[0]为x轴的值,values[1]为y轴的值,values[2]为z轴的值
callback(event.values[0], event.values[1], event.values[2])
}
}
这里对传感器进行了封装,这样使用的时候就非常简单了,直接调用start方法传入一个回调即可接收重力传感器的数据了,不使用时调用stop方法即可,如下:
// 开启重力传感器
val gravitySensor = GravitySensor()
gravitySensor.start { x, y, z ->
// TODO 使用重力数据x、y、z
}
// 停用重力传感器
gravitySensor.stop()
我们公司有个设备摄像头可以上下转动,怎么知道转到前面还是后面了,就是使用的重力感应,很奇怪的,即使手机不动,只是转动这个摄像头,重力感应的值就会变化,因为只有前后的转动,属于Y轴,所以处理起来也很简单,转动的时候看Y值的变化做相应的处理即可,具体表现为,y为0时转到一个中间的位置,再往正面(人脸的方向)转时为负数,往背面(手机背面的方向)转时为正数。