书名:PhoneGap移动应用开发手册
ISBN:978-7-115-33740-5
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
• 著 [英] Matt Gifford
译 李海涛 郭光伟
责任编辑 傅道坤
• 人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
• 读者服务热线:(010)81055410
反盗版热线:(010)81055315
Copyright © Packt Publishing 2012. First published in the English language under the title PhoneGap Mobile Application Development Cookbook.
All Rights Reserved.
本书由英国Packt Publishing 公司授权人民邮电出版社出版。未经出版者书面许可,对本书的任何部分不得以任何方式或任何手段复制和传播。
版权所有,侵权必究。
这是一本介绍PhoneGap开发平台的入门图书,它以一种全新的方式,探讨了如何在PhoneGap平台上快速地掌握移动程序开发技巧,帮助读者轻松地学习在PhoneGap平台上的开发方法。
本书总共分为5部分。第1部分概述了PhoneGap平台进行开发时对设备接口的相关调用,包括对移动设备上移动与定位功能、文件系统、音频视频、通讯录以及本地事件。第2部分介绍了如何调用XUI JavaScript使用PhoneGap平台进行程序开发。第3部分讲述了如何使用jQuery Mobile进行用户界面的开发和美化。第4部分讲述了如何使用插件来扩展PhoneGap平台的API和方法。第5部分通过介绍一系列方法帮助用户简化开发流程,对开发环境的部署和测试都有所介绍。
本书适合想学习PhoneGap平台开发语言、提升编程技能的人员阅读。本书可以让初学者迅速入门,轻松掌握PhoneGap语言;可以让有经验的移动开发人员巩固个人知识,提升编码技能。
2007年夏天,Steve Jobs 通过发布iPhone改变了世界,并大胆宣称“基于Web的应用程序是未来的发展方向”。仅仅几年之后,事情有所变化,但是基本的方向仍然如此。当时我正以“执行CTO”的身份供职于一家名为Nitobi的小型Web咨询公司(我们为彼此起绰号,我的绰号是“SPACELORD!1!!”)。iPhone SDK(还不是现在的iOS SDK)刚刚发布,我的一些同事就参加了位于San Francisco的Adobe公司旗下的iPhone Dev Camp。他们对使用Web技术来开发app还心存疑虑。Rob Ellis、Brock Whitten和Eric Osterly成功地使用UIWebView实现了本地调用,PhoneGap的第一次实施由此诞生。不久之后,Joe Browser使用PhoneGap开发了一个Android应用。Dave Johnson——Nitobi的“真正CTO”——随后实施了BlackBerry运用。从此以后,PhoneGap瓜熟蒂落。距PhoneGap版本首次提交不到一年的时间,在2009年的春天,我在第一届JSConf会议上做了首次PhoneGap演讲,尽管当时我心存忐忑,但还是受到了观众的热烈欢迎。
也许开发人员只是喜欢我用来掩饰自己恐慌的演讲风格。但是,开发人员更希望自己被当作是一幅宏伟蓝图的拥护者,并受到技术人员的尊重,而不是被禁锢到一个未知的知识领域,无所适从。
我们曾经是,并且现在也是倾向于使用开源代码编写自己堆栈的Web开发人员。我们想要使用自己选择的技术来编写Web应用,而且无需支付版权费用。我们不希望看到PhoneGap这样一个项目的存在,而是希望它能够早日过时。该工作在Apache软件基金会的管理下,以Apache Cordova的名义继续推进。自PhoneGap项目成立以来,除了传播、咒骂和大量的演讲之外,定义愿景以及执行最终的执行计划成为我的首要任务。
今天的PhoneGap是一个健壮、成熟、稳定的软件项目,而且会定期发布新版本。如今在Apache有30名来自于赞助组织的全职核心技术专家负责PhoneGap的维护工作,而且每天都会收到数以百计的更新请求。PhoneGap支持所有主流的操作系统,具有齐全的开发文档,而且其CLI工具也使得常见的移动开发流程得以简化。另外,PhoneGap API涵盖了所有常见的设备功能,我们还有一个文档丰富的插件接口来扩展浏览器。
长期以来,Matt Gifford一直是PhoneGap的支持者和痴迷者,本书中包含了他来之不易的经验。读者在书中一定能找到想了解的内容,如访问设备传感器(如地理位置传感器)或者系统数据(如文件系统或者是手机通讯录)。读者也可以将本书作为处理富媒体数据(比如图像、音频和视频)的参考手册。
编写HTML、CSS及JavaScript是一项艰巨的任务,幸好Matt为读者提供两个伟大的选项,来帮助读者起步,它们是XUI和jQuery Mobile。最后,如果读者需要让开发的app独立于Phonegap运行,同时使用其原生的功能,则可以利用PhoneGap Plugin API来实现。
虽然为移动设备开发应用会相当困难,但是使用PhoneGap会降低此项工作的难度,而且PhoneGap也使得所开发的应用更容易地移植到未来的Web中。Matt编写的这本书可以帮助你做到这些。如果在阅读本书的过程中有任何问题,请与我或者Matt联系,千万别犹豫!现在,开始尽情阅读本书吧!
Brian Leroux
高级产品经理、PhoneGap负责人
Adobe公司
Matt Gifford是一名来自英国剑桥的RIA开发人员,以ColdFusion、Web应用和移动开发见长。他在这些领域具有10年以上的工作经验,当前是Monkeh Works公司(www.monkehworks.com)的所有者。
他经常在国内会议和国际会议上发表演讲,此外还为前沿的国际行业杂志撰写文章和教程。他还经常在其博客(www.mattgifford.co.uk)上撰写博文。
作为ColdFulsion方向的Adobe社区专家,Matt致力于倡导社区资源和行业知识的共享,并重点关注和鼓励下一代行业精英的成长。
Matt是Object-Oriented Programming in ColdFusion和许多开源应用程序(包括流行的monkehTweets twitter API包装器)的作者。
首先感谢所有才华横溢的PhoneGap开发人员。若没有他们充满创新和激动人心的项目,这本书将只能是一堆白纸。
Raymond Camden是Adobe的一名资深开发“传教士”。他的工作以Web标准、移动开发及ColdFusion为主。他是一位畅销书作家,而且经常会出席不同主题的会议和用户组。读者可通过他的博客(www.raymondcamden.com)、Twitter账户(@cfjedimaster)和电子邮箱(raymondcamden@gmail.com)与他联系。
Shaun Dunne是英国伦敦SapientNitro公司的一名开发人员,从2008年开始从事编程,而且对JavaScript和所有前端技术充满激情。在过去的几年里,Shaun一直供职于大型机构,因此能够有机会使用各种不同的Web技术来开发大规模的应用。此外,Shaun还通过自己的言传身教,让其他人员充分感受互联网所带来的激情。
多年以前,Shaun就着迷于移动Web,他测试了所有可以使用的工具,并与他人分享他的发现,从而让其他人知道在什么情况下应该使用什么工具。
工作之余,他除了陪伴子女外,就是在网上写博客,或者做一些开发工作。他当前正在忙于图书写作,这本书的名字是UberCSS,将在2012年冬天以自出版的形式问世。
Andrey Rebrov最初是Magenta Technology公司的一名软件开发人员。该公司是英国一家大型软件公司,专注于企业级Java解决方案,他在该公司工作了3年以上。Andrey 现在是俄罗斯ScrumTrek公司的一名敏捷工程教练(agile engineering coach)。
作为一名工程教练,他帮助团队学习并且适应XP实践,如TDD(测试驱动开发)。他的很大一部分职责是创建俄罗斯软件技术社区(Russian Software Craftsmanship Community)。
在工作中,他会使用创新和敏捷游戏。当前,他正在致力于俄罗斯与俄罗斯社区的创新游戏普及项目。
感谢Joel Goveya在审稿过程中提供的帮助与耐心。
感谢父母提供的机会,让我找到自己的价值。没有他们,就没有我今天的一切。在任何时候,他们都是我最强大的后方支持,我非常感激。
最后,我要感谢我的妻子Tatyana,是她在一直给我希望和力量。
谨将本书献给Arthur George Wood。感谢您给了我如此多的快乐回忆、美好的童年,并教会我如何做人。我爱你,爷爷!
当今的技术发展日新月异,传统意义上的Web服务从桌面系统到移动设备的移植,变得越来越重要。随着移动通信技术和设备性能的不断提高、用户使用率的提高,以及用户越来越习惯通过移动设备访问内容或与服务交互,无论是出于商业目的、开发新颖的应用程序占领市场攫取利润,还是作为软件或解决方案的实验,都有越来越多的组织和个人对这个领域垂涎不已,这一点并不令人惊奇。
采用什么平台?采用什么编程语言?这是开发移动应用程序不可避免的问题。为了在一个特定的平台上开发应用,开发者可能需要专门学习一门新的语言,如Objective-C、Java、C++。仅此一点就要付出高昂的成本:学习新语言的财务成本包括时间和学习材料,以及有效地管理开发流程的成本。如果再考虑把同一个应用推广到不同的平台和操作系统上,成本会急剧增加,并且每个代码库将难于维护和控制。
PhoneGap的应运而生解决了这些问题,它让开发人员使用HTML、CSS和JavaScript这些大家比较熟悉的Web技术创建跨平台的应用程序,而不必烦恼于使用不同OS指定的开发语言开发特定平台的应用程序。
对于所有Web开发人员和设计人员来说,PhoneGap大大降低了开发特定平台移动应用程序的门槛,他们能够使用现有的语言技术为移动平台开发特定的应用。
通过使用PhoneGap的JavaScript API,可以将一些功能加入设备的本地功能,如地理位置和GPS、加速计、摄像头、视频及音频的捕获,这样HTML应用程序就会瞬间变成功能强大的应用程序。
本书将通过不同的实例讲解来帮助读者学会使用PhoneGap API完善应用程序。对于初学者,这是一本不可多得的全面入门教材,读者可以参照本书的例子一步一步地学习使用PhoneGap库,亲身体验移动应用程序的开发过程。
通过阅读本书,读者会发现Cordova和PhoneGap可以相互切换使用。由于有两个完全一样的开放源码平台和库,所以用户可以使用HTML、JavaScript和CSS创建本地移动应用程序。
2011年,PhoneGap的代码库转移到Apache的开源项目Cordova。Adobe仍然在发行支持PhoneGap库。虽然这两种工程在本书中都将涉及,但是这只是设计决定,并不代表可以混用。从本质上讲,PhoneGap和Cordova项目相同,指的是同一个免费、开源库。
Brian Leroux还专门撰写了博文来解释PhoneGap名字的变更、PhoneGap与Lordova之间的区别,以及它们对开发人员、项目贡献者和PhoneGap社区的影响(如果存在的话)。
本书涵盖了PhoneGap库中大多数可用的各种方法和功能,但事物难以尽善尽美,读者在实际学习中可能需要了解到本书没有涉及到的知识。同时在本书的写作过程中,PhoneGap项目本身经历了多个版本发布(最新版本为2.0),因而必然会有本书未涉及到的在属性、小功能以及细节上的变化。
如果读者需要PhoneGap项目或代码相关的帮助,以下有一些额外的可用资源,可以确保读者获取最新信息。
第一个途径是官方的PhoneGap文档,网址为http://docs.phonegap.com/en/2.1.0/index.html,包括可用的API方法、功能和特性。本书介绍的内容和官方文档可能存在相同的内容,如果阅读本书时有困惑或者有不明白的地方,可以参考官方文档来相互印证,弄清原因。
第二个途径是谷歌的PhoneGap论坛,地址为groups.google.com/group/ PhoneGap,该论坛为PhoneGap的开发者、贡献者和用户提供了一个开放的讨论区,涵盖了各种各样的内容。在这里可以发布自己的问题,或查看其他社区成员遇到的问题。PhoneGap社区是充满活力、互助的论坛,一定有人能够帮到你,同时还可以帮助其他社区成员解决问题。分享会让知识和经验更加美好!
第1章,“移动与定位:使用加速计和位置传感器”,讲述了如何创建能确定用户地理位置的应用,以及使用设备加速计检测移动方向。
第2章,“文件系统、存储及本地数据库”,详细介绍了如何使用本地存储API向设备存储中读写文件、创建和管理SQLite数据库、从远程服务器上传和下载文件、保存应用程序的内容。
第3章,“处理音频、图像和视频”,讨论了如何使用设备功能创建丰富的多媒体应用程序,使用硬件捕捉音频、视频和图像,以及音频回放和流媒体。
第4章,“处理通讯录”,介绍了如何访问和使用设备上的通讯录数据库。
第5章,“本地事件”,介绍了如何使用和扩展设备上的本地事件,以实现应用程序的暂停和恢复,以及创建检测连接变化和设备电池量的自定义功能。
第6章,“使用XUI”,解释了轻量级XUI JavaScript库的可用功能和方法。
第7章,“使用jQuery Mobile进行用户界面开发”,引导用户通过使用jQuery Mobile框架创建一个简单的移动应用程序,包括页面跳转和“接近原生的”用户界面元素。
第8章,“PhoneGap插件扩展”,介绍了如何通过创建自定义插件来扩展PhoneGap的API和方法。
第9章,“开发工具及测试”,介绍了可以用来创建移动应用开发环境的大量选项,以及一些可用来简化工作流程的工具。
需要准备一台计算机、一个Web浏览器和喜欢的代码编辑器。有一些代码编辑器带有帮助用户进行PhoneGap移动应用程序开发的功能,在本书第9章中有所描述。例如Dreamweaver的CS5.5和CS6版本就支持PhoneGap及PhoneGap的编译服务。
最重要的是,可以免费使用Cordova或PhoneGap库开发移动应用程序。库可以免费下载,读者可以使用任何文本编辑器编写HTML、CSS和JavaScript。用于运行程序的设备模拟器也可以免费下载。
本书适合具有HTML、CSS和JavaScript开发经验的人员阅读,也适合打算从事移动应用开发的人员阅读。希望对其已有的HTML应用进行修改,使其具备移动特性的功能的人员,也可以从本书中获益。
本章将包含以下内容:
随着技术发展,移动设备早已不局限于收发短信和邮件这些简单的功能。它们还可以借助位置传感器、加速计传感器及其他传感器,帮助用户导航和定位。
本章将介绍如何使用PhoneGap API来访问这些传感器,并在应用程序中充分利用这些传感器的功能。
加速计可捕捉设备在x,y,z这3个空间轴上的移动。加速计是一种移动传感器,它能检测当前设备位置的相对移动变化。
使用PhoneGap API提供的加速计相关函数检测设备的反馈信息。
(1)首先,创建HTML初始化框架,并添加需求脚本文件cordova-2.0.0.js
的引用。
示例代码下载
通过http://www.packtpub.com.网站购买Packet相关书籍的用户,可以下载已购买书籍的示例代码。其他读者可以访问网站http://www.packtpub.com/support,通过注册后,可将相关文件直接发送到您的电子邮箱。
(2)在Cordova JavaScript
引用的下面,新建一个JavaScript标签块,进行下一步之前,定义一个确保设备准备就绪及本地代码加载完成的侦听事件。
(3)当本地代码加载全部完成后,在onDeviceReady
函数调用getCurrent Accelerration
方法。
(4)加入onSuccess
函数处理从加速计返回的信息。
(5)定义accelerometer div
元素对应变量,保存生成的加速计结果。
(6)接下来,将accerlation
对象的返回值赋给accelerometer via
元素中的HTML以显示给用户,将acceleration
对象访问的可用属性赋值给字符串变量。
(7)最后,添加onError函数处理可能遇到的情况。
(8)图1.1是程序在设备上的运行效果示意图。
图1.1
通过注册deviceready
事件的侦听事件,保证在JavaScript代码执行时本地的PhoneGap代码已经执行完毕。一旦准备就绪,程序将调用加速计API中的getCurrentAcceleration
函数,并加载两种方法,分别处理成功返回和错误信息。
onSuccess
函数返回的加速计信息,包含以下4种属性:
acceleration.x:Number
类型变量,单位是m/s^2,用于测量设备在x轴方向上的加速度。也就是当屏幕垂直放置时,设备从左向右的移动。从左向右移动时,加速度值为正,反之,为负。acceleration.y:Number
类型变量,单位是m/s^2,用于测量设备在y轴方向上的加速度。也就是当屏幕垂直放置时,设备从下向上方向的移动。当设备往上移动时,获取的加速度值为正值,从上往下移动时则为负值。acceleration.z:Number
类型变量,单位是m/s^2,用于测量设备在z轴方向上的运动。也就是设备垂直方向的变化。当设备朝向天空移动时,获取的加速度为正值,当设备向地面方面移动时,加速度为负值。acceleration.timestamp:DOMTimeStamp
对象,用于测量从程序初始化开始运行的时间(毫秒),可以用来存储、更新以及追踪从上次加速计更新开始时间内的变化。图1.2显示了x,y,z轴与设备的关系。
图1.2
之前提到的加速度对象返回的acceleration.x
、acceleration.y
和acceleration.z
值,都受到重力加速度的影响,其值精确到9.81 m/s^2。
从设备获取加速度数据在一些移动手机游戏的开发中必不可少,这些游戏往往需要平衡控制,以及对设备转向、视图控制、设备倾斜的移动检测。
读者可在下面地址了解getCurrentAcceleration方法,及获取加速计数据的官方Cordova文档:
getCurrentAcceleration
函数只是获取当它被调用的那个时间点的加速计数据,一次调用返回一个响应对象。本例中将设计一个程序可以设定时间间隔以从加速计持续获取其更新,以监视设备的持续运动。
通过对PhoneGap API中的一个可用方法提供另外的参数以设置更新时间间隔。
(1)首先,创建HTML初始化框架,并添加需要脚本文件cordova-2.0.0.js
的引用。
(2)在Cordova JavaScript引用后面,新加一个JavaScript标签块声明新的变量watchID
。
(3)接下来,定义侦听事件,以确保在进行下一步之前设备准备完毕、本地代码加载完成。
(4)添加onDeviceReady
函数,该函数在本地代码加载完成后调用startWatch
函数。
(5)创建startWatch
函数。首先,创建options
变量存放可选的frequency
参数,将其值设置为3000毫秒(3秒)。
(6)设置两个按钮来控制加速计监视的开始和停止,将其设置其初始属性disabled
。
(7)接下来,将watchAcceleration
赋给之前定义的watchID
变量,这样便可以查看其值以确认它是否仍被设置为null
。
(8)像定义成功调用以及错误处理函数名称一样,同样将包含frequency
值的options
变量传送到函数调用。
(9)startWatch
函数完成后,需要提供一个函数停止加速计的监测。该函数先检测watchID
的值,若非空,就调用clearWatch
函数停止对加速计的监测,提取watchID
的值并将该变量置为null。
(10)引用accelerometer div
元素并将其值设置为一个用户友好的消息。
(11)接下来,重新指定两个控制按钮的disabled
属性,使得用户能够再次开始监视。
(12)创建onSuccess
函数,它将在获取更新成功返回后运行。将accleration
对象的返回值赋给auelerometer
div 元素中的HTML,以向用户显示,将acclerstion
对象访问的可用属性转化为字符串形式。
(13)创建onError
函数,捕获请求过程中可能的情况。此处将输出一条用户友好的提示信息,将其设置为accelerometerData div
元素的值。
(14)最后添加两个按钮元素,并都具有onClick
属性,用于开始或停止对设备加速计的监视。
(15)运行的结果如图1.3所示。
图1.3
(16)停止监测加速计的类似显示界面如图1.4所示。
图1.4
通过注册deviceready
事件的侦听事件确保了本地PhoneGap代码未执行之前不运行JavaScript代码。PhoneGap一旦准备就绪,调用startWatch
函数,在该函数中设定加速计更新时间间隔。
PhoneGap API中的WatchAcceleration
函数在指定的时间间隔,获取设备当前的加速度数据。如果没有设置时间间隔,默认为10000毫秒(10秒)。每次获取到更新信息,onSuccess
方法将对获取的数据进行处理,并将之显示到屏幕上。
watchID
变量包含监视时间间隔,通过将其传递给PhoneGap API中的clearWatch
函数可以实现停止监视。
本例中,加速计更新时间间隔frequency
值被设置为3000毫秒(3秒)。请读者考虑如何为程序添加一个变量,允许用户通过滑动条或在输入对话框中手动设置时间间隔。
参考下面链接的Cordova官方文档,可以学习更多关于
watchAcceleration
方法的使用:http://docs.phonegap.com/en/2.0.0/cordova_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration。
开发者可以利用加速计传感器及其持续更新实现诸多功能,如运动监视游戏和更新屏幕上对象的位置。
下面将通过设备加速计传感器的持续更新,移动屏幕上的元素,作为设备移动的反应。该功能通过如下步骤实现。
(1)创建HTML初始化框架。在head
标签添加cordova JavaScript引用以导入需求的库。
(2)在body
标签中创建两个div
元素。将其中第一个的id
属性设置为点,作为在设备屏幕上移动的元素。
(3) 第二个div
元素的ID设置为acclerometerData
,作为返回的加速度数据输出容器。
(4)开始创建自定义脚本和PhoneGap实现,在head
标签内的末尾添加script
标签以存放代码。
(5)在着手核心代码之前,需要声明一些变量。给watchID
设定默认值和围绕屏幕移动的对象显示的圆形半径大小。
(6)现在为PhoneGap声明侦听事件函数,及在本地PhoneGap代码加载完成时运行的onDeviceReady
函数。
(7)onDeviceReady
函数中将会执行startWatch
方法,该函数设置加速计更新的frequency
值,并向设备发出获取加速度信息的请求。
(8)向设备发送请求后,现在需要请求成功和失败情况的处理函数。先是onSuccess
函数,该函数处理物体在屏幕上的移动。
(9)需要申明一些变量来表示移动对象在屏幕上的位置。
(10)返回的acceleration
对象包含了需要的屏幕上的x、y的坐标位置,现在可以将x、y坐标方向上的加速度值设置为变量,并计算出移动速度。
(11)为正确用像素解释加速度结果,可利用vmultiplier
变量将x,y坐标转化为像素变化:
(12)需要确保显示对象不能移出可视范围,始终保持在屏幕界限之内。
(13)有了正确的x,y坐标值,就可以将其用于dot
元素位置的风格,创建包含从acceleration
对象返回属性的字符串消息及已经创建的显示坐标。
(14)调用加速计时也需要用到错误处理,所以现在也需要编写。下面创建一个简单的字符串消息,并将其插入div
元素,以提醒用户遇到了问题。
(15)最后,添加一些CSS以创建点标记以用来在设备上显示位置。
(16)当运行程序时,可以通过倾斜设备使元素在屏幕上运动。显示效果如图1.5所示。
图1.5
通过对加速度持续监视,获取设备的移动结果,可以从加速计传感器获取位置变化。通过一些简单的JavaScript可对变化做出反应,基于返回的传感器信息更新一个元素在设备屏幕上的位置。
本例中,通过计算出dot元素在屏幕上的正确x、y坐标,可以很容易地更改其在屏幕上的位置。为确保元素运动时不超出屏幕范围,需要采取一些条件判断,检查当前位置、元素的半径,以及屏幕本身的范围。
位置和使用全球卫星定位系统(GPS)功能,可以使开发者创建动态的实时地图绘制、定位及跟踪应用程序。使用位置的一些方法可以获取位置感知应用程序所需要的信息和属性。只要用户连接到网络(通过移动数据业务或者WIFI),就可以从位置传感器获取其位置信息。
使用PhoneGap API的位置功能监视设备的反馈信息,获取相关的位置信息。
(1)创建HTML初始化框架,并添加需求脚本文件cordova-2.0.0.js
的引用。
(2)在Cordova JavaScript下面,添加新的JavaScript标签块,并在其中定义确保设备准备完毕的侦听事件。
(3)添加onDeviceReady
函数。一旦本地代码加载完毕,该函数将调用PhoneGap API中的gelocation.getCurrentPosition
函数。
(4)添加onSuccess
函数处理位置请求返回的position
对象。
(5)接下来创建对geolocationdata div
元素的引用,并将其赋给变量geoElment
,该变量保存生成的位置结果。
(6)下一步将返回值定义为格式化的字符串,设置为geolocationdata div
元素中的HTML内容。通过position
对象访问这些可用属性。
(7)最后,添加OnError
函数,处理任何可能出现的错误。
(8)错误一旦出现,根据错误代码返回值决定向用户显示哪类消息。这将被设定为geolocationData div
元素中的HTML内容。
(9)在设备上运行此程序时,可能的输出效果如图1.6所示。
图1.6
(10)出现错误时,可能的运行效果如图1.7所示。
图1.7
一旦设备准备就绪,并且本地PhoneGap代码初始化完毕,程序将执行geolocation API
中的getCurrentPosition
方法。定义onSuccess
方法处理输出以及成功响应,定义onError
方法捕获错误并进行相应的处理。
onSuccess以position
对象的形式返回位置信息,其中包含以下属性。
position.coords
:Coordinates
对象,存放请求的地理位置信息,包含以下属性。
latitude
:Number
类型值,取值范围为[−90.00,+90.00],以十进制表示估算的纬度数。
longitude
:Number
类型值,取值范围为[−180.00,+180.00],以十进制表示估算的经度数。
altitude
:Number
类型值,表示世界大地测量系统(WGS)84椭球中的海拔高度,单位为米。可选属性。
accuracy
:Number
类型值,表示纬度和经度的精确度,单位为米。可选属性。
altitudeAccuracy
:Number
类型值,表示海拔高度估算的准确度,单位为米。可选属性。heading
:Number
类型值,表示当前移动方向的度数,相对于正北的顺时针转动的度数。可选属性。speed
:Number
类型值,当前设备的移动速度,以米每秒为单位。可选属性。position.timestamp:DOMTimeStamp
对象,表示获取地理位置信息及创建Position
对象的时间。
position
对象可选属性相当丰富和详细。
对于“可选项”,如果设备没有返回相应的值,则设定为null
。
如果在请求过程中遇到错误,OnError
函数返回positionError
对象。该对象包含下面两个属性。
code
:Number
类型值,表示错误的数值代码。Message
:String
类型对象,表示用户可读的错误描述信息。错误可能产生的原因:未具备访问设备位置传感器的足够权限、未获取必要GPS信息致使定位失败、请求超时,或者其他未知错误。
PhoneGap中可用的定位API基于W3C Geolocation API Specification。当前多数浏览器和设备已使用该API。如果任何运行程序的设备上已经实现了该功能,那么它将使用内置的API,而非PhoneGap的API。
读者可以从下面的官方Cordova文档链接,获取更多关于定位和getCurrentPosition方法的信息:
http://docs.phonegap.com/en/2.0.0/cordova_geolocation_geolocation.md.html#geolocation.getCurrentPosition
。
使用getCurrentPosition
方法,可以获取以GPS坐标表示的设备位置。本例中,通过设定的间隔持续获取更新信息,以获取当前位置。
通过传递一个包含多个参数的可选项,设置时间间隔,提高精确度。
(1)创建HTML初始化框架,并添加需求的cordova- 2.0.0.js
文件。
(2)在Cordova JavaScript引用下面,添加新的JavaScript标签块。在该标签块中声明新的变量watchID
。
(3)下一步,创建在设备准备完毕时运行的侦听事件。
(4)现在添加onDeviceReady
函数执行startWatch
方法,代码如下。
(5)创建startWatch
函数。首先,创建options
变量保存传入该函数的可选参数。设置frequency
值为5000毫秒(5秒),并将enableHighAccuacy
设置为true。
(6)下一步,将watchPosition
方法赋给先前定义的变量watchID
,此变量用来检查当下位置是否正被监视。
(7)传递已设置的其他参数,将options
变量传递给watchPosition
方法。
(8)初始调用函数创建完成后,现在开始设计在成功回应后执行的onSuccess
函数。将返回的position
对象作为参数传入该函数。
(9)声明一些变量来保存从响应中获得的详细信息,它们以timestamp
、latitude
、longitude
和accuracy
变量的形式出现。同时需要创建一个元素变量,引用用于显示输出信息的geolocation div
元素。
(10)通过访问position
对象的属性,将返回值赋给相关的变量。
(11)最后,将这些变量设置连接为字符串,并将其设置为div
元素中的HTML。
(12)onSuccess
完成后,开始编写onError
函数来处理响应可能返回的错误。
(13)运行程序时,输出效果如图1.8所示。
图1.8
PhoneGap API中的watchPosition
方法以异步函数方式运行,持续检查设备当前位置的变化。一旦检测到设备位置发生变化,将以position
对象的形式返回当前地理位置信息。
在持续检测的循环过程中,onSuccess
负责处理成功的响应,并将返回值显示到屏幕上。
getcurrentPosition
和watchPosition
函数中有3个可选的参数。
enablehighaccuracy
:布尔值变量。决定用户选择的定位精度。默认(false)情况下,使用移动或网元网络获取位置信息。若设置为true,则会使用更加精确的定位方式,如卫星定位。Timeout
:Number
类型变量,单位为毫秒,定义获取成功响应的最大等待时间。MaximunAge
:Number
类型变量,单位为毫秒,如果缓存的数值小于指定的时间,则使用MaximumAge。
安卓设备中必须将
enableHighAccuracy
设置为true
,才能成功返回位置结果。
用户可以停止持续的位置请求,或通过程序调用PhongGap API中的clearWatch
方法清除更新间隔。清除更新时间间隔、停止检测的方法,与清除通过持续更新获取的加速计数据的方法,完全一样。
本节基于设备位置传感器返回的经纬度坐标,使用Google Maps API作为JaveScript,讲述如何在屏幕上绘制地图,及生成地图位置标签。
编码之前,先行搭建环境、获取Google Maps服务的访问权限。
(1)注册一个Google Maps API key:访问https://code.google.com/apis/console/
,并使用你的Google账户登录。
(2)从左边菜单中选择Services选项,并激活Google Maps API v3 service。
(3)一旦服务激活,在API access页面中就会生成用户的API key。在该页Simple API Access章节就会发现该key,效果如图1.9所示。
图1.9
(4)现在可以开始我们的例子了。
可从下面的链接获取Google Maps API的相关官方文档:
https://developers.google.com/maps/documentation/javascript/
。
使用设备的GPS功能获取位置坐标、创建并初始化地图、显示当前位置的标记。
(1)为页面创建基本的HTML框架。
(2)在head
标签中添加Google Maps API需要的JavaScript。将API key加入脚本中src
属性的查询字符串中。
(3)接下来,添加对cordova-2.0.o.js
的引用,并创建另一个JavaScript标签块,以存放自定义代码。
将Google Maps API JavaScript加入文件中时,设置传感器查询参数为true。若只允许人工输入而非设备自动检测,该参数设为false。但我们始终使用从设备传感器获取的数据自动更新当前位置。
(4)在JavaScript标签块中创建自定义代码。首先,创建侦听事件来确保设备准备完毕,并创建onDeviceReady
方法运行侦听事件。
(5)下一步,创建onSuccess
函数,访问position
对象返回的位置信息。
(6)根据从设备位置传感器获取到的latitude
和longitude
信息,创建latLng
对象,在组件初始化时将其传入Map对象。
(7)设置Map选项,将设置的latlLng
变量的值作为地图的中心。Google Map控件在转换到移动设备屏幕上时可能会出现异常,尤其在可用性方面。用户可以自定义需要使用的控件。本例中使用zoomControl
控件而不使用panControl
控件。
(8)为定义Map
对象,需引用一个div
元素,并传递给之前定义的mapOptions
变量。
(9)为关闭该方法,下面创建marker
变量显示latLng
对象表示的精确位置。
(10)为确保对返回的错误都能正确处理,下面创建onError
方法,它将根据div
元素内的错误码显示对应的字符串消息。
(11)在body
标签中导入显示地图的div
元素。
(12)最后,在head标签中添加style
块,提供必要的页面格式及map
元素。
(13)在设备上运行该程序,显示效果如图1.10所示。
图1.10
多亏开放的绘制服务,比如Google Maps,才能从设备获取位置更新,并利用返回的数据,创建丰富的、可交互的、可视化地图应用程序。
本例中,使用设备的坐标作为Map的中心位置,并且在地图上创建Marker置于标签之上,易于可视化。
这类地图服务的可用API相当丰富,其中的信息非常详细,并包括许多函数及方法可以帮助开发者实现基于位置的工具和应用程序。一些服务限制对API的需求数目,所以编写程序的时候一定要注意相关限制。
本例中使用Goole Maps API作为JavaScript。Google提供的API有许多不同的层次。也可以访问其他地图绘制系统,诸如MapQuest、MultiMap和Yahoo! Maps提供者。读者可以尝试使用这些不同的服务,并通过实验从中挑出最适合自己的解决方案。
本例所使用的是动态Google Map API。这样做是为了可以使用zoom控件,并且使得用户能在最终应用中拖拉地图。
读者同样可以选用Google Static Map服务,该服务生成地图的代码相对简单,将会返回位置的静态图片。
读者可以在该服务中选择使用API key。此后仍然可以和本例开始时启用API Access的方式一样来启用API。
思考下面的代码,其是对onSuccess
函数的一个修订,获取到位置信息后将会运行。
从中可以看到,通过运用Static Maps API,此处仅仅使用了一个图像资源,将坐标、图像大小及其他数据作为参数,比之前代码中创建坐标、地图及标签的操作要简单得多。
虽然使用Static Map API会使得程序失去用户对动态地图的交互性,然而整个服务会变得简单许多,要求的代码量也会大量减少。
更多关于Google Static Map API的官方文档,请参见下面的链接
https://developers.google.com/maps/documentation/staticmaps/
。
PhoneGap API向开发者提供了获取设备的坐标信息及前进方向信息。开发者可以利用这些信息自定义一个罗盘工具来显示设备的移动。
(1)创建HTML初始化框架,并添加需要脚本文件cordova-2.0.0.js
的引用。
(2)本例将以类名的方式调用DOM中的特定元素。为此我们使用XUI JavaScript库 (http://xuijs.com/)。在head
标签中添加script
的引用包含该库。
(3)创建script标签块存放自定义的JavaScript用来和PhoneGap API交互,代码如下。
(4)在body
标签下添加一个新的div
元素,并将container
的class
属性赋给该元素。用来存放显示的罗盘元素。
(5)罗盘本身由两个图像组成。每个图像都被分配了一个class
名,以方便在JavaScript中对其调用。将这两个元素添加到container
元素中。
(6)接下来,在图像下面添加一个新的div
元素,并将id
属性设置为heading
。该元素用来存放从罗盘回应的文本输出。
(7)初始化框架完成后开始创建自定义JavaScript代码。首先,定义deviceready
侦听事件。由于此处使用了XUI,这使得它和本章之前的例子有些区别。
(8)为将产生的结果输出,需要将heading id
属性插入到div
标签块。XUI使这项操作变得简单——用户可以通过更新headingDiv
全局变量保存该引用。
(9)添加对PhoneGap罗盘的请求方法。在这个函数中实际发送了两个请求,首先获取设备当前移动方向的瞬时数据,然后每1/10秒(通过frequency
参数)检测设备的当前移动方向。如此持续更新,可保证罗盘的正确性。
(10)这两种请求使用相同的onSuccess
和onError
方法进行输出处理和数据管理。onSuccess
方法将以heading
对象的方式返回数据。
(11)返回的数据将被用来设置HTML内容中的heading
元素,以消息字符串的方式保存在先前定义的headingDiv
变量中。
(12)可视化罗盘也需要对前进方向信息做出响应。利用XUI
中的CSS
方法,借助返回的magneticHeading
属性,可将rose图像中的transform
属性值转变为rotate
。这里通过调用类名.rose
引用该图像。
(13)onSuccess
完成后,编写onError
方法处理遇到问题时以友好的方式返回给用户,代码如下所示。
(14)在onSuccess
中创建消息字符串时,调用了一个新的函数converTOText
。该函数将从heading
对象中接收的magneticHeading
值转化为文本输出显示。在XUI deviceready
代码块之外添加该函数。
(15)采用一些CSS将两个图像显示在屏幕上,确保rose图像位于罗盘图像之上。新建compass_style.css
文件,并采用下面的风格添加内容。
(16)最后,在HTML文档中的head
标签块内添加compass_style.css
文件的引用。
(17)在设备上运行该程序,输出效果如图1.11所示。
图1.11
PhoneGap API罗盘功能中的watchHeading
方法按frequency
变量传递的时间间隔更新设备的移动方向数据。如果没有指定间隔时间,则采用默认的时间间隔100微秒(1/10秒)。
在整个持续周期中,每次成功请求,onSuccess
方法将被执行并将结果格式化后输出到屏幕,同时改变图像元素的transform
属性,使得图像对应移动方向转动方向。
onSuccess
方法以compassHeading
对象的方式返回设备的移动方向信息。该对象包含以下属性。
magneticheading
:Number
类型,取值范围为0~359.9,表示一次移动的转动度数。trueheading
:Number
类型,取值范围为0~359.9,表示当前运动方向相对于正北的偏转度数。headingaccuracy
:Number
类型,表示返回的移动方向和实际移动方向之间的偏差。timestamp
:以毫秒为单位,获取移动方向的时间。第6章,“使用XUI”。