App Inventor编程教程-第24课-传感器-少儿编程教育网

App Inventor编程教程-目录

想象一下,你像往常一样,正在一条熟悉的路上慢跑,突然被一个念头打动——一款全新的杀手级移动应用!一路上,你甚至忘记了回家…

将你的手机指向天空,谷歌星空地图{![谷歌星空是谷歌地球应用的组成部分,类似于谷歌地图应用,以观察者为中心,显示天空中的星图。该应用创建于2007年8月,运行在安卓系统中,可以利用智能手机中的位置传感器及方向传感器,动态地显示星空图。如,当用户改变手机的方向时,应用将显示手机顶端所指方向的星图。——译者注]}

会显示出你正在观看的星群;倾斜手机,可以控制游戏中的角色;带着你的手机去散步,一款“面包渣儿”应用将记录下你途经的路线。所有这些应用之所以能够实现,是因为你所携带的移动设备装备了高科技的传感器,可以探测到位置、方向以及加速度。

本章将讨论App Inventor的位置传感器、方向传感器以及加速度传感器等组件,学习的内容涉及GPS、方向测量(也称姿态测量,包括手机的倾斜角、翻转角及方位角等)以及对加速度传感器读数的数学处理。

App Inventor编程教程-第24课-传感器-少儿编程教育网

创建位置感知应用

在智能手机流行之前,计算仅限于桌面电脑。虽然便携式电脑也算是移动设备,但与我们今天随身携带的微型设备相比,不可同日而语。计算已经摆脱了实验室及办公室,冲破了围墙与屋顶的束缚,每时每刻都发生在世界的每一个角落。

对移动计算的普及产生深刻影响的是一项新的、非常有趣的数据:当前位置信息,所有应用都可以使用这些信息。当人们在世界各地游走时掌握他们的行踪,这件事影响深远,它既有可能对我们的生活产生极大的帮助,但同时也存在侵犯隐私及侵害人权的可能。

在位置感知类应用中,“安卓,我的车在哪”(第7章)就是一个对人们有帮助的例子,它可以记住我们之前的位置,以便我们稍后返回。这是一款个人应用,位置信息就保存在手机的数据库中。

位置感知类应用同样适用于由多人组成的小组。例如,一个徒步旅行团可能希望在荒野中查看每个组员的去向,一个商务小组可能希望在一个大型会议上寻找自己的伙伴,还有人每天都在使用签到{![许多社交类网站都具有签到功能,允许用户随时报告自己的位置或具体地点,并与朋友们分享这些信息,其中位置或地点信息可能来自于某项地图服务。——译者注]}类应用,等等。

另一类位置感知应用中引入了增强现实技术。这类应用利用位置信息及手机的方向,在真实信息的基础上,覆盖了一层额外的信息。例如,在一个地图应用中,当你用手机指向一栋建筑物时,除了基础的地图信息之外,你可能会看到这栋建筑在房地产市场上的价格;或者一个导游类的应用,当你在植物园中欣赏奇花异草时,这个应用会告诉你这株植物的品种。

GPS

创建一个位置感知应用,首先需要了解GPS的工作原理。GPS数据来自美国政府所保有的卫星系统,只要在视野开阔地带,并且至少能“看”到三颗卫星,你的手机就能获得GPS数据。一份GPS数据中包括所在位置的纬度、经度及海拔高度。纬度表示与赤道的距离,赤道以北为正值,以南为负值,范围从-90至90。在图23-1所示的谷歌地图中,显示了厄瓜多尔首都基多的位置,它的纬度为-0.01,表示在赤道偏南一点点。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-1 赤道上的厄瓜多尔首都基多
经度是距离本初子午线(零度经线)向东或向西偏离的距离,向东为正值,向西为负值。零度经线穿过的最知名的地点就是格林尼治,它是伦敦附近的一座小镇,是皇家天文台的所在地。图23-2中的地图标出了格林尼治的位置,它的经度为0.0。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-2 格林尼治的皇家天文台,沿0度经线射出一道光柱
经度值从-180到180。图23-3显示了俄罗斯境内的一点,距离阿拉斯加非常近,它的经度为180.0。这个点可以理解为以格林尼治(经度为0.0)为起点绕地球半圈所到达的位置。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-3 在俄罗斯与阿拉斯加边境附近的一点,经度为180

App Inventor与位置感知

App Inventor为访问GPS信息提供了位置传感器组件,该组件具有纬度、经度及海拔高度三个属性。此外,它还可以与谷歌地图通信,来获得当前位置的街道地址信息。

位置传感器组件中最重要的是位置信息改变事件,以及相应的事件处理程序,如图23-4所示。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-4 位置传感器的位置信息改变事件处理程序
两种情况可以触发位置信息改变事件:传感器第一次收到读数时,以及当位置发生变化而传感器收到新的读数时。其中第一次读数通常会延迟几秒钟,有时也会一直没有读数。例如,如果你在室内而且没有连接WiFi,设备将无法获得读数。无法获得读数的另一个原因,可能是你的手机出于省电的目的,关闭了GPS功能。如果你的位置传感器一直收不到数据,你需要逐一排查上述可能的原因。

有一种方法可以侦测到位置传感器的读数变化:创建一个变量“最新位置”,将其初始化为“未知”,并在位置信息改变事件中修改变量的值,如图23-5所示。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-5 变量最新位置的值会随位置的改变而改变
在图中所示的事件处理程序中,在位置传感器第一次获得位置信息之前,应用显示“未知”。一旦获得新的读数,变量“最新位置”将改为新的经纬度值。这些值可以直接显示在用户界面上,也可以保存到数据库中。这个方法在第4章“开车不发短信”应用中使用过,即,在自动回复的短信中加入位置信息:“未知”或最后一次获得的读数。

也可以使用“位置传感器的有经纬度值”块,直接询问传感器中是否有读数,如图23-6所示。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-6 用“有经纬度值”块测试传感器是否含有读数

边界检查

位置信息改变事件通常用于检查设备是否处在某个边界之内,或某个设定的区域内。如图23-7所示,这段代码的功能是判断某人到0度经线的距离是否超过了0.1度:每当位置传感器获得读数时,如果读数中的经度值大于0.1度,则让手机产生振动。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-7 如果读数远离了零度经线,则让手机振动
这种边界检查功能可以有很多用途。例如,对于假释犯,如果他们离开家的距离接近规定的合法距离时,应用会发出警告;或者对教师及家长来说,当孩子离开操场时,发出警告。如果你想看到更为复杂的例子,参见第18章中关于条件块的讨论。

位置信息的来源:GPS、WiFi以及基站标识

有几种方法可以确定安卓设备的位置,其中最精确的方法是通过GPS卫星定位,可精确到数米。但是如果设备在室内,或者周围有高楼或其他障碍物遮挡,则无法获得读数。在视野开阔地区,并且至少能“看到”三颗GPS卫星时,才能获得位置信息。

如果无法使用GPS,或者用户的设备禁用了这一功能,也可以通过无线网络获得位置信息。设备需要在WiFi路由器附近,当然,你获得的经纬度读数是这台WiFi设备的位置信息。

判断设备位置的第三种方式是通过移动网络的基站标识(Cell ID)。基站标识对手机位置的判断基于手机与附近基站之间通信信号的强弱,这种方式通常不够精确,除非你周围有很多个基站。不过这种方式与GPS或WiFi连接相比,是最省电的。

方向传感器

游戏中会用到方向传感器,用户通过倾斜设备来控制物体的运动。方向传感器也可以用作指南针,确定手机所指的方向。

方向传感器有五个与方向有关的属性,除了航空工程师外,很少有人熟悉这些数据的含义。

翻转角(左右转动)

当设备水平时,翻转角的值为0度;当设备向左倾斜时,增加到90度;而当设备向右倾斜时,减少到-90度。

倾斜角(前后转动)

当设备水平时,倾斜角的值为0度;当设备头朝下时,倾斜角的值增加到90度;当设备翻转至面朝下时,倾斜角回到0度。同样,当设备的下端朝下时,倾斜角的值减小到-90度;当继续翻转至面朝下时,倾斜角的值回到0度。

方位角(指南针)

当设备顶端指向正北时,方位角的值为0度;指向正东时,值为90度;指向正南时,值为180度;指向正西时,值为270度。

幅度(球的滚动速度)

取值范围在0~1之间,表示设备的倾斜程度。如果有一个球放置在设备表面,设备的倾斜会导致球的滚动,这个值间接地影响球的滚动速度(在游戏中,球组件在画布上移动的速度等于幅度值乘以100时,才能明显地体现出幅度对速度的影响。——译者注)。

角度(球的滚动方向)

表示设备倾斜的方向。如果有一个球放置在设备表面,当设备倾斜时,球将模拟受到重力的作用而朝位置低的方向滚动。

方向传感器提供了方向改变事件,每当方向发生变化时,会触发该事件。为了进一步研究这些属性的意义,我们写一个应用,来具体说明这些属性如何随设备的倾斜而改变。在用户界面中添加一个五行两列的表格布局,每个单元格中放置一个标签,左边标签用于提示数据的含义,右边标签用于显示相应的数据,然后编写代码,如图23-8所示。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-8 显示方向传感器数据的代码块

用翻转角移动物体

现在通过用户对设备的左右翻转,来实现图像在屏幕上的左右移动,就像在射击或赛车类游戏中那样。拖入一个画布组件,宽度设为“充满”,高度为200像素。然后向画布中添加一个精灵或球,并在画布下方添加一个标签,命名为翻转角标签,来显示翻转角的值。如图23-9所示。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-9 用翻转角控制图像移动的用户界面
方向传感器的翻转角属性表示手机左右倾斜的角度,即,在竖屏模式下,如果将手机稍向左倾斜,则翻转角读数为正值;反之,向右倾斜则为负值。因此,利用图23-10中的事件处理程序,用户可以控制物体的运动。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-10 在方向改变事件中响应翻转角属性值的变化
图中将翻转角属性值乘以-1,因为向左倾斜时,翻转角的值为正,但我们希望物体向左移动(因此x坐标的值变小)。要了解动画应用中的坐标系统的工作原理,参见第17章。

需要注意的是,这段程序是针对竖屏模式编写的,而非横屏。事实上,当你过度地倾斜手机时,屏幕会自动转成横屏模式,而图像则被卡在屏幕的左边(经测试,精灵卡在屏幕的左边,与屏幕的显示模式没有直接的关系。即便设置屏幕的方向不变,只要稍向左倾斜手机,精灵就会到达左侧边界。快速到达边界的原因无非两个。首先,方向传感器的方向改变事件被触发的频次很高。经测试,10秒钟内触发576次,平均每秒触发6次。

其次,翻转角的值在0~90°之间。当翻转角等于15°时,每秒钟精灵的移动距离是15×6=90像素。假设手机屏幕宽480像素,且精灵从屏幕中间开始移动,则不到3秒钟就会碰到边界,并停在那里。实际观察到的效果是,精灵不能平滑地移动到边界,而是突然到达边界,难道与手机的处理能力有关?——译者注)。这是因为当设备向一侧倾斜时,如向左倾斜时,获得的翻转角属性的读数一直是正值,因此图像的x坐标值也一直在变小,如图23-10所示。

注意到App Inventor特别为屏幕组件提供了“屏幕方向”属性,如果你不希望屏幕随着手机的转动而自动旋转,可以将其设为固定模式(竖屏或横屏)。

控制运动的方向及速度

前面的例子中图像可以左右移动,如果想实现任意方向的运动,可以使用方向传感器的角度及幅度属性,这正是第5章的游戏中让瓢虫移动的属性。

在图23-11中是一个测试程序,用户通过倾斜设备来控制角色向任意方向移动(需要两个标签及一个精灵组件)。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-11 用角度和幅度属性来移动角色
幅度属性的值介于0到1之间,代表设备的倾斜程度。试试看,在这段测试程序中,幅度的值越大,图像的移动就越快。

手机用作指南针

指南针应用,以及像谷歌星空这样的应用,需要知道手机所指的方向(东南西北)。谷歌星空就是根据手机的指向,将方向信息叠加在星座信息上。

方位角属性用于表示方向,取值范围介于0°至360°之间:正北为0,正东为90,正南为180,正西为270。因此当方位角的值为45°时,意味着手机指向东北;值为135时,指向东南;值为225时,指向西南;值为315时,指向西北。

图23-12中的代码块创建了一个简易的指南针,可以用文字显示手机所指的方向(如西北)。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-12 编程实现一个简易的指南针
你可能已经发现,程序的显示结果只能是这四个方向之一:东南、东北、西南、西北。你可以挑战一下自己,看能否修改程序,使手机的指向在某个范围内时,显示四个正方向:正北、正南、正东、正西。

加速度传感器

加速度是速度随时间的变化率。如果你踩下油门,汽车会加速——速度将以一定的比率增加。

在安卓手机中内置了加速度计,用于测量加速度,但测量的参照系不是静止的手机,而是自由下落中的手机:如果你让手机下落,它所记录的加速度读数为0。一句话,读数与重力有关。

如果你对相关的物理知识感兴趣,可以去查阅与牛顿经典力学{![原书为“与爱因斯坦相关的书籍”,当速度远远低于光速时,与加速度有关的运动学知识属于经典力学范畴,非爱因斯坦的相对论力学。——译者注]}有关的书籍,但本小节中,我们将以一个可以救命的应用为例,开始学习使用加速度传感器。

响应设备的摇晃

如果你学习过第1章(你好猫咪),那么你已经使用过加速度传感器了。在这个最简单的应用中,当手机摇晃时,利用加速度传感器的摇晃事件,让设备发出猫叫声,如图23-13所示的块。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-13 当手机摇晃时播放猫叫声

使用加速度传感器的读数

像其他传感器一样,加速度传感器也具备侦测读数变化的事件——加速度改变事件。这个事件中携带了三个参数,对应于加速度在三个方向上的分量。

x分量

当设备向右倾斜时,其值为负(设备的左侧边缘抬起);当设备向左倾斜时,其值为正(设备的右侧边缘上升)。

y分量

当设备的底部抬起时,其值为负;当设备顶部抬起时,其值为正。

z分量

设备的显示屏朝上时,其值为正;显示屏朝下时,其值为负。

检测自由落体

我们知道,如果加速度三个方向的分量都接近于0,那么设备一定在做自由落体运动。基于这一认识,我们可以在加速度改变事件中,通过检测各个分量的值,来判断设备是否发生了自由落体事件。这些代码经过反复测试,可以用于老年人的自动求救:一旦侦测到发生跌倒,就会自动向外发送短信。

图23-14中显示了这个应用使用的代码块,当发生自由落体运动时,在设备上显示一条简单的信息(用户可以点击重置按钮进行再次检测){![用右键点击某个代码块,并选择“内嵌输入项”或“外挂输入项”,可以改变代码块的外观。在这个例子中,已经设置“并且”块的显示方式为“外挂”式,以减小整个事件处理程序代码的宽度。——译者注]}。

App Inventor编程教程-第24课-传感器-少儿编程教育网
图23-14 当自由落体发生时进行报告
每当传感器获得读数时,程序将对三个方向(xyz)上的加速度分量进行判断,看这些值是否接近于0(即绝对值小于1)。如果三者都接近于0,应用将改变标签的属性,来提示设备正处于自由落体状态。当用户点击重置按钮时,标签又被重新设为初始状态(显示“设备没有自由下落”)。

小结

传感器是移动应用中最富魅力的部分,因为它们实现了用户与环境之间实实在在的交互。无论是用户体验,还是应用开发,移动计算为我们带来了无限的商机。不过依然要精心地构思一个应用,来决定何时、何地以及如何使用这些传感器。很多人会担心隐私问题,如果应用中涉及个人敏感信息,他们可能会放弃使用。尽管如此,在游戏、社交网络、旅行以及其他众多领域中,仍然有无限多种可能开发出有积极意义的应用来。