(我在上一篇博客中写的很多东西我会直接拿过来用,所以在这里会复用很多代码)
手机和电脑一个很大的区别就是手机有各种各样的传感器,可以获取各种各样的环境信息,从而为用户提供更加方便和宽广的支持。
嗯,所以Virgo库也必须支持传感器,下面让我们看看Virgo的传感器用法
【壹】大致流程:
1.调用get_sensor_manager() 返回 VSensorManager对象
2.设置Listener
-用VSensorEventListener()创建一个监听器
-设置监听器的setSensorChanged(函数体)来设置回调函数
例如:
sensor_listener = VSensorEventListener() 2.1设置【当传感器数值发生改变时】对应的回调函数 sensor_listener.setSensorChanged(self.sensor_changed)
3.注册传感器
[!] 这一步通常在Activity的onResume(页面获得焦点时)中实现,请尽量遵守这一规则
调用VSensorManager对象的.registerListener(arg1, arg2, arg3)
- arg1:监听器对象
- arg2:传感器对象,可用方法sensor_manager.get_default_sensor(传感器对应编号) 获取
- arg3:传感器更新速度
其中,arg2中的传感器编号可选值如下:(通过SensorType.TYPE_**获取)
【下面这一小部分是基本上所有手机都有的,所以比较稳妥,用起来应该不会报一些奇奇怪怪的BUG,请尽量使用下面的传感器】 TYPE_PRESSURE = 压力传感器 TYPE_ACCELEROMETER = 加速度传感器 TYPE_GRAVITY = 重力传感器 TYPE_LINEAR_ACCELERATION = 线性加速度传感器 TYPE_GYROSCOPE = 陀螺仪传感器 TYPE_LIGHT = 光纤传感器 TYPE_MAGNETIC_FIELD = 磁场传感器 TYPE_ORIENTATION = 方向传感器 TYPE_PROXIMITY = 距离传感器 TYPE_AMBIENT_TEMPERATURE = 温度传感器 TYPE_RELATIVE_HUMIDITY = 相对湿度传感器 TYPE_ROTATION_VECTOR = 旋转矢量传感器| ----------------------------------------------------------- TYPE_TEMPERATURE = 被弃用的温度传感器,请使用TYPE_AMBIENT_TEMPERATURE! ___________________________________________________________ 【下列这些可能不常用,但还是列出来吧,可能有些手机上并没有相应的传感器,所以使用的时候请谨慎,例如下面的【TYPE_HEART_RATE = 心率监测器】,安卓手机上大概率是没有的】 TYPE_MAGNETIC_FIELD_UNCALIBRATED = 未校准磁场传感器 TYPE_GAME_ROTATION_VECTOR = 未校准旋转矢量传感器 TYPE_GYROSCOPE_UNCALIBRATED = 未校准陀螺仪传感器 TYPE_SIGNIFICANT_MOTION = 重要运动触发传感器 TYPE_STEP_DETECTOR = 步进检测器传感器 TYPE_STEP_COUNTER = 步进计数器传感器 TYPE_GEOMAGNETIC_ROTATION_VECTOR = 地磁旋转矢量 TYPE_HEART_RATE = 心率监测器 TYPE_TILT_DETECTOR = 唤醒倾斜探测器传感器 TYPE_WAKE_GESTURE = 唤醒手势传感器 TYPE_GLANCE_GESTURE = 唤醒手势传感器
arg3中的传感器更新速度,可由VSensorManager.SENSOR_DELAY_**获取,下面列举可选值
SENSOR_DELAY_FASTEST 最快,延迟最小(风驰电挚,更新数值快到看不清) SENSOR_DELAY_GAME 适合游戏中获取的频率(健步如飞,速度很快) SENSOR_DELAY_NORMAL 正常频率(可以说不快也不慢?或者也挺快的?) SENSOR_DELAY_UI 适用普通用户界面频率(还行,够用了)(更新速度由上至下越来越慢,根据个人需求选择)
例如:
sensor_manger.registerListener(self.sensor_listener, sensor_manger.get_default_sensor(SensorType.TYPE_GRAVITY), VSensorManager.SENSOR_DELAY_NORMAL)
4.编写注销传感器的逻辑
[!] 这一步通常在onStop(页面停止),onPause(页面暂停)中实现,请尽量遵守这一规则
SensorManager对象.unregisterListener(监听器对象)
监听器对象可与前文共用同一个
例如:
self.get_sensor_manager().unregisterListener(self.sensor_listener)
5.编写传感器数值处理逻辑
这一步通常在前文VSensorEventListener()处通过调用setSensorChanged(函数体)来设置回调函数
下面看一看回调函数的编写规范和用法
编写规范:
你定义的回调函数大抵需要是这样的吧
# 必须含有参数event,在系统发现任何一个你注册的传感器数值改变,便会调用你注册的Listener中的SensorChanged函数(没错,就是下面你传进去的这个),函数名随你定
def your_func(self, event): # event会带来新改变的传感器数值,不同传感器values也不一样,例如,重力传感器的 values是[x,y,z]的float列表,可用values[0]、values[1]、values[2]获取,光线传感器是单独一个浮点数,但也要用values[0]的方式获取,切记。其他类型传感器的返回值懒得打表了,自己去试(猜)。 values = event.values # 一次一个event对应的只有一个传感器的改变事件,所以先判断是什么传感器 sensor_type = event.sensor.getType() # 获取此次事件的传感器类型 # 如果是重力传感器 if sensor_type == SensorType.TYPE_GRAVITY: ... # 如果是光线传感器 elif sensor_type == SensorType.TYPE_LIGHT: ...
用法:
不多BB,直接上例子
def sensor_changed(self, event):
gravities = str(list(event.values[::]))
light = str(event.values[0])
sensor_type = event.sensor.getType()
if sensor_type == SensorType.TYPE_GRAVITY:
self.gravity_text.setText(gravities)
elif sensor_type == SensorType.TYPE_LIGHT:
self.light_text.setText(light)
大意就是获取传感器数值列表,变成字符串后直接给对应文字控件显示
【贰】实际案例代码与完整逻辑与结果动图
1.新编写一个Activity,命名为SensorActivity,继承CA,不多解释
class SensorActivity(ControlActivity):
# 新编写一个Activity,命名为SensorActivity,继承CA,不多解释
def __init__(self, APP):
# 调用父类构造方法,传入Activity名与APP
super(SensorActivity, self).__init__("trysensor", APP)
# 定义几个变量用于存储获取到的控件
self.position_providers_text = None
self.gravity_text = None
self.light_text = None
self.call_btn = None
#定义存储SensorListener的变量
self.sensor_listener = None
2. 重写此Activity的onCreate方法,为按钮添加一个取消注册传感器的方法
def onCreate(self, savedInstanceState):
self.setContentView("trysensorlay")
# 获取对应的文字,赋值实例变量
self.gravity_text = self.findViewById("sensorgravity")
self.light_text = self.findViewById("sensorlight")
self.position_providers_text = self.findViewById("position_providers")
# 获取按钮,对按钮进行赋值回调函数,用的lambda匿名函数的方式
self.call_btn = self.findViewById("button_try")
self.call_btn.setOnClickListener(VOnClickListener().register_onClick(
# 这个self.sensor_listener是什么先别急,后文有
# self.get_sensor_manager()获取该Activity的SensorManager对象,所有的传感器相关事务都与它有关
lambda view: self.get_sensor_manager().unregisterListener(self.sensor_listener)
))
3. 重写onResume方法,写注册传感器的逻辑
def onResume(self):
# 获取传感器管理器
sensor_manger = self.get_sensor_manager()
# 设置传感器事件监听器
self.sensor_listener = VSensorEventListener().setSensorChanged(self.sensor_changed)
# 注册传感器1:重力传感器
sensor_manger.registerListener(self.sensor_listener,
sensor_manger.get_default_sensor(SensorType.TYPE_GRAVITY),
VSensorManager.SENSOR_DELAY_NORMAL
)
# 注册传感器2:光线传感器
sensor_manger.registerListener(self.sensor_listener,
sensor_manger.get_default_sensor(SensorType.TYPE_LIGHT),
VSensorManager.SENSOR_DELAY_NORMAL
)
4.重写、注销监听器的逻辑
因为一直开着监听器会造成程序的不稳定与系统占用,所以一定记得编写传感器注销逻辑
def onStop(self):
self.get_sensor_manager().unregisterListener(self.sensor_listener)
def onPause(self):
self.get_sensor_manager().unregisterListener(self.sensor_listener)
5.编写传感器值改变时的回调函数
这个例子前文有,不写注释了
def sensor_changed(self, event):
gravities = str(list(event.values[::]))
light = str(event.values[0])
sensor_type = event.sensor.getType()
if sensor_type == SensorType.TYPE_GRAVITY:
self.gravity_text.setText(gravities)
elif sensor_type == SensorType.TYPE_LIGHT:
self.light_text.setText(light)
6.结果动图,效果展示
点击(测试按钮)后注销监听器,效果与onStop与onPause一样
【叁】附录-完整代码
class SensorActivity(ControlActivity):
# 新编写一个Activity,命名为SensorActivity,继承CA,不多解释
def __init__(self, APP):
# 调用父类构造方法,传入Activity名与APP
super(SensorActivity, self).__init__("trysensor", APP)
# 定义几个变量用于存储获取到的控件
self.gravity_text = None
self.light_text = None
self.call_btn = None
#定义存储SensorListener的变量
self.sensor_listener = None
def sensor_changed(self, event):
gravities = str(list(event.values[::]))
light = str(event.values[0])
sensor_type = event.sensor.getType()
if sensor_type == SensorType.TYPE_GRAVITY:
self.gravity_text.setText(gravities)
elif sensor_type == SensorType.TYPE_LIGHT:
self.light_text.setText(light)
def onCreate(self, savedInstanceState):
self.setContentView("trysensorlay")
# 获取对应的文字,赋值实例变量
self.gravity_text = self.findViewById("sensorgravity")
self.light_text = self.findViewById("sensorlight")
# 获取按钮,对按钮进行赋值回调函数,用的lambda匿名函数的方式
self.call_btn = self.findViewById("button_try")
self.call_btn.setOnClickListener(VOnClickListener().register_onClick(
# 这个self.sensor_listener是什么先别急,后文有
# self.get_sensor_manager()获取该Activity的SensorManager对象,所有的传感器相关事务都与它有关
lambda view: self.get_sensor_manager().unregisterListener(self.sensor_listener)
))
def onResume(self):
# 获取传感器管理器
sensor_manger = self.get_sensor_manager()
# 设置传感器事件监听器
self.sensor_listener = VSensorEventListener().setSensorChanged(self.sensor_changed)
# 注册传感器1:重力传感器
sensor_manger.registerListener(self.sensor_listener,
sensor_manger.get_default_sensor(SensorType.TYPE_GRAVITY),
VSensorManager.SENSOR_DELAY_NORMAL
)
# 注册传感器2:光线传感器
sensor_manger.registerListener(self.sensor_listener,
sensor_manger.get_default_sensor(SensorType.TYPE_LIGHT),
VSensorManager.SENSOR_DELAY_NORMAL
)
def onStop(self):
self.get_sensor_manager().unregisterListener(self.sensor_listener)
def onPause(self):
self.get_sensor_manager().unregisterListener(self.sensor_listener)