Python开发安卓-Virgo库开发日记(2)--增加传感器支持

(我在上一篇博客中写的很多东西我会直接拿过来用,所以在这里会复用很多代码)

手机和电脑一个很大的区别就是手机有各种各样的传感器,可以获取各种各样的环境信息,从而为用户提供更加方便和宽广的支持。

嗯,所以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)
)1
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值