PhoneGap-入门指南-全-
PhoneGap 入门指南(全)
零、简介
这本书是给谁的
这本书是为任何想要开始跨多个移动平台开发移动应用的人准备的。该书提供了关于 PhoneGap 的介绍和详细教程,并在以下方面为读者提供了帮助:
- 确定哪种 JavaScript UI 框架最适合他们
- 介绍 JavaScript UI 框架及其与 PhoneGap 的集成
- 解释插件的概念以及如何使用它来进行 OAuth 身份验证和云推送
- 解释如何编写自定义插件
这本书的结构
这本书首先解释了移动操作系统世界的碎片化以及它如何影响我们。它进一步讨论了如何弥合由于这种碎片化造成的差距,以及如何编写一次代码并跨移动平台部署它。
在 PhoneGap 背后的概念被弄清楚之后,这本书继续解释 PhoneGap 在 Android 上的用法,然后给出了如何在其他剩余的移动平台上做同样事情的说明。
接下来介绍了如何在 PhoneGap 上使用 JavaScript UI 框架,还讨论了在什么场景中使用哪个 JavaScript UI 框架。
最后,这本书将重点转移到插件上。它展示了几个如何用社区插件扩展 PhoneGap 框架的例子。然后解释了如何在 iOS、Android 和 BlackBerry 上构建这些插件。
下载代码
本书中提到的所有源代码都可以在[bitbucket.org/rohitghatol/apress-phonegap](https://bitbucket.org/rohitghatol/apress-phonegap)获得。这些章节本身就说明了这一点。也可在 Apress 网站[Apress.com](http://apress.com)上获得。
联系作者
可以通过作者的 LinkedIn 个人资料联系到他们:
Rohit Ghatol—[in.linkedin.com/in/rohitghatol](http://in.linkedin.com/in/rohitghatol)
Yogesh Patel—[www.linkedin.com/profile/view?id=19911394](http://www.linkedin.com/profile/view?id=19911394)
一、了解跨平台移动应用开发
这本书是关于移动应用开发的;更确切地说,是关于减轻移动应用开发的痛苦。市场上有许多智能手机平台:安卓、iPhone、黑莓、诺基亚、Windows 7 手机和 WebOS。更新的平台也在增加,比如三星的 Bada 和 Meego。
移动应用开发平台的数量之多似乎令人应接不暇。在处理移动应用开发时,这是你必须记住的第一点。
在 2000 年,我们在台式机领域看到了类似的情况。我们有微软的 Windows,苹果的 Mac,以及各种版本的 Linux 和 UNIX。那时,很难构建能在所有这些平台上运行的产品。由此产生的碎片通常通过内部解决方案来解决,方法是用 C++构建框架,抽象出特定于操作系统(OS)的模块。幸运的是,Sun 的 Java 拯救了我们,为我们提供了一个通用的构建平台。有了 Java 的“一次构建,随处运行”策略,构建桌面产品变得轻而易举。
在 2004 年到 2008 年之间,开发者社区看到了一种不同的分裂;这一次,它发生在浏览器世界。这是一场涉及非常流行的 Internet Explorer 6 与 Firefox 和 Safari 的分裂——然后,Chrome 和其他浏览器突然出现,导致了进一步的分裂。
然而,这种碎片化的本质是不同的,更温和一些:这主要是由于浏览器没有遵循万维网联盟(W3C)概述的规范。通常,这种分裂是通过写“如果浏览器是 IE,那么做这个做那个”或者“如果特性存在,那么做这个做那个”来解决的。
许多 JavaScript 库来帮忙编写跨浏览器的 web 应用。事情已经改善到这样的程度,所有的浏览器都在努力工作,越来越符合 W3C 规范。浏览器作为一个平台,现在是一个强有力的竞争者。
这本书是关于移动世界的碎片化。移动操作系统碎片化非常严重,因为在这个开发领域没有规范或标准。
2007 年,苹果和谷歌推出了他们的移动平台。2008 年,两家公司都推出了移动应用商店,允许智能手机用户下载移动应用。移动应用的时代已经开始;从此,再也没有回头。智能手机用户数量呈指数级增长。
公司开始专注于在新的智能手机平台上提供服务和内容。企业意识到他们需要将注意力转移到智能手机用户身上。不仅用户数量增加,智能手机的使用频率也增加了。
想象一下,您的开发人员日以继夜地在 iPhone、Android、BlackBerry、WebOS 和 Symbia 上发布相同的产品——现在,让我们将 Samsung Bada 添加到这个列表中!你可以看到这里的挑战。操作系统平台,从它们的开发环境开始,是如此的分散。对于 iPhone,你将需要 Mac 机,对于黑莓,你将需要 Windows。本章将更详细地讨论这些事情。
现在,对于那些刚接触移动应用开发的人来说,我们将从关注创建一个移动应用是什么样子开始。我们将回答诸如“移动应用与传统的基于网络或基于桌面的应用有何不同?”我们将研究为各种平台开发移动应用的挑战。
移动应用的类型
了解不同类型的移动应用非常重要。我将根据他们的工作把他们分为两类。
- 独立移动应用
- 移动应用(基于 web 服务)
独立移动应用是诸如闹钟、电话拨号器和离线游戏之类的应用。支持 Web 服务的移动应用包括电子邮件、日历、Twitter 客户端、在线游戏以及与 web 服务交互的应用。
这种移动应用之间的区别是本书上下文中所独有的。虽然 PhoneGap 可以用来实现独立的移动应用,但是基于 PhoneGap 的移动应用的本质通常属于“服务支持的移动应用”的范畴
了解 Web 服务
作为一名开发人员,当你看互联网上的 web 应用时,你需要考虑两种 web 开发。
- 可通过浏览器访问的 Web 应用(用于人机交互)
- 可以通过 RESTful Web 服务之类的协议访问的 web 服务(用于编程接口)
所有流行的网络应用,如谷歌、脸书、Twitter、LinkedIn、MySpace、Flickr 和 Picasa,都为它们的服务提供了 RESTful 界面。这类网站有很多在线词典。如果你访问[www.programmableweb.com](http://www.programmableweb.com),你会看到一个相当大的列表,列出了所有为编程接口提供此类服务的网络应用(见图 1–1)。

图 1–1。 可编程 Web API 目录
许多想要为多个平台开发移动应用的公司要么拥有自己的 web 服务,要么依赖于其他 web 服务。虽然 PhoneGap 可以用于独立的移动应用,但它非常适合使用 web 服务的移动应用。原因是 PhoneGap 应用主要是增加了设备功能的 web 应用。想象一下,一个 Flickr web 应用可以访问设备的摄像头或 Google Maps 应用,而后者又可以访问 GPS。另一个例子是 Foursquare,它可以访问你的 GPS,以及你手机的通讯录。
这或多或少意味着大多数基于 PhoneGap 的应用将使用 JavaScript 访问 web 服务。这使得使用 PhoneGap 的开发人员掌握使用 web 服务变得非常重要。
对于读过这本书后想要编写 PhoneGap 应用的开发人员,我建议在 ProgrammableWeb.com 上找到一些 web 服务,并为这些服务编写一个 PhoneGap 客户端作为练习。
这本书将提供一个这样的服务的例子;也就是 AlternativeTo.Net。
移动应用概述
虽然你们中的许多人至少有一些使用移动应用的经验,但你们中的许多人更熟悉非移动平台(例如,web 平台)。因此,这本书明确论述了移动应用的本质以及与之相关的挑战。如果您来自非移动背景,这将有助于您理解开发移动应用意味着什么。
移动应用功能

图 1–2。 移动应用不是 web 应用。
首先要注意的是,移动应用不是 web 应用。区别在于特性的性质和所提供的特性数量(参见图 1–3)。
- 移动应用的功能可能会更少。
- 您可以期待您的移动应用看起来与您的 web 应用非常不同。首先,智能手机的屏幕大小与桌面不同。在 web 应用中,屏幕越大,你就有越多的空间来放置菜单、工具栏和小部件。
- 考虑到智能手机的屏幕尺寸限制,你会看到更多仪表板类型的主屏幕。
- 智能手机用户需要通过不同级别的导航来找到他或她想要使用的功能。
- 智能手机用户和网络用户有不同的意图。智能手机用户希望在旅途中使用应用,以最少的努力获得最大的生产力,而网络用户可能会花更多的时间使用网络应用。
由于上述差异,您将看到智能手机上最具生产力(或最常用)的功能被突出显示。无论移动应用提供所有的功能,还是其中的一个子集,这些小的生产(和最频繁使用的)功能集将在移动应用上以最容易访问的方式进行组织。

图 1–3。 移动功能与网络应用功能不同。
用户互动
相对于传统的 web 应用,用户与移动应用交互的方式非常不同(参见 Figure 1–4)。
随着智能手机的触摸屏功能和更加生动的用户交互,基于加速度计和指南针,移动应用必须以不同的方式构建。
想象一个汽车游戏应用,通过向左或向右倾斜手机来操纵汽车。这是基于加速度计。想象一个地图应用,当用户改变他或她的方向时,它总是指向北方。这是基于一个指南针。
虽然与应用交互的新方式增强了用户体验,但新的移动平台上缺少物理键盘给 power keyboard 用户增加了一些额外的限制。在详细阐述移动应用需求时,需要考虑到这一点。
除此之外,智能手机有两种显示模式:布局和纵向;这些在早期的浏览器中是闻所未闻的。记录需求规格的一个重要部分是定义当设备处于纵向或横向模式时应用的外观、感觉和行为。

图 1–4。 智能手机和网络应用有不同的用户输入界面。
位置感知
位置感知是智能手机与生俱来的功能。谷歌地图、本地搜索、Foursquare 和许多其他移动应用都利用了智能手机的精密 GPS。Web 应用也使用位置感知;然而,这些应用使用相对更粗粒度的 GPS 系统(例如,国家级)(见图 1–5)。

图 1–5。 与网络应用相比,智能手机应用的位置感知能力
推送通知
应用用户喜欢收到有用事件的通知,比如收到的电子邮件和消息。智能手机是最好的通知平台,因为它几乎无时无刻不在用户身边。
除了收到电子邮件或信息等通知,任何服务都可以向智能手机用户发送通知(见图 1–6)。考虑一个组织的工作流程。用户不必总是登录 web 应用来完成涉及他或她的工作流,应用通知用户他或她需要执行某个操作来完成工作流会更有效率。这样,无论用户是否靠近笔记本电脑或台式机,他/她都可以始终高效地工作。

图 1–6。 智能手机的推送通知功能(移动通知)
跨平台移动应用开发的挑战
虽然移动应用的开发令人兴奋,但考虑到移动操作系统(OS)数量的不断增长,开发移动应用会面临许多挑战。
让我们来看看这些挑战。
OS 碎片化
碎片化增加的趋势与移动平台数量的增长相一致(参见图 1–7)。首先是黑莓和塞班智能手机,然后是强大的 iPhone 和 Android 平台。可以肯定的是,移动平台并没有就此止步。惠普随 WebOS 而来;微软推出了 Windows 7 手机;而现在,三星要出 Bada 了。
这意味着公司必须不断推出新产品,让所有移动平台都能感受到它们的存在。

图 1–7。 由于移动操作系统数量的增长而导致的碎片化
假设你想开发一个移动应用,目标是 iPhone,Android,BlackBerry 等。由于每个移动平台的操作系统不同,请考虑以下因素:
- 首先,你必须为每个平台设置不同的环境。
- 第二,你需要对每个操作系统有一点专业知识。对于移动开发者来说,学习曲线可能会很长。
- 不同的移动平台需要不同的编程语言。
- 你需要熟悉每个移动平台支持的特性;参见图 1–10。
表 1-1 描述了移动应用开发所需的设置(针对各种移动平台)。
过去,我们已经看到过类似的操作系统碎片化,从 Windows、Linux 和 Mac 的跨桌面碎片化开始,随着 Sun 推出 Java,这一问题得到了解决。在更近的过去,我们面临浏览器碎片,这是通过跨浏览器 JavaScript 框架如 jquery、YUI 和 Google Web Toolkit 解决的。
移动操作系统碎片是所有碎片中最糟糕和最多样化的。这为在所有移动平台上启动移动应用增加了相当大的技术挑战。
多个团队/产品
如果我们选择使用多个团队为每个平台构建一个移动应用,我们会面临许多问题;增加团队会增加项目交付的风险;增加产品意味着产品管理团队承担更多责任(参见图 1–8)。由于所有移动平台上的功能也是分散的,产品管理人员必须对每个平台上的产品提出具体要求。
最终,增加更多的团队,增加多个团队之间的协调,以及增加多个产品将导致管理和开发团队的额外开销。

图 1–8。为不同的移动操作系统增加多个团队带来了新的问题。
一致的用户体验
鉴于您希望您的应用在多个移动平台上保持一致,您的应用需要在所有平台上提供相似且一致的用户体验(参见 Figure 1–9)。这也与您的最终用户可能从一个平台迁移到另一个平台有关,或者他们可能存在于多个平台上。考虑一个拥有 Android 智能手机和 iPhone iPad 的用户。用户可以在家或在办公室使用 iPad,也可以在外出时使用 Android 智能手机。
这是你的应用必须提供跨移动平台的相似用户体验的众多原因之一;当然,由于设备特性和功能的分散,用户体验会因移动平台而有所不同。

图 1–9。 为跨平台的应用最终用户提供统一的用户体验
特征碎片化
设备特性和功能因平台而异(参见图 1–10)。这意味着,虽然一些机器人和 iPhones 有嵌入式指南针来显示方向,但其他智能手机没有。这可能意味着其他智能手机上的导航应用可能无法像 Android 或 iPhone 应用那样旋转地图。
总的来说,同一个应用在一些移动平台上会关闭一些功能,这是事实;应用的逻辑需要以这种方式编写。

图 1–10。 针对不同移动操作系统的特性碎片化
开发环境碎片化
开发环境是一个特别重要的片段。如果您想开发一个面向以下平台的移动应用,您至少需要两个操作系统:Windows(最好是 Windows 7)和 Mac(最好是 Leopard ):
- ios
- 机器人
- 黑莓
- WebOS
- 智能移动终端操作系统
- Windows 7
此外,您将不得不使用各种 ide 和编程语言,如 Java、C++和 Objective C。此外,您将使用许多 ide,如 Xcode 和 Eclipse。
表 1-1 显示了开发环境的要求(针对各种移动平台)。

PhoneGap 的跨平台移动应用战略
PhoneGap 之所以成为可能,是因为所有移动平台之间的共性。如果没有这个通用组件,PhoneGap 就不可能存在。
浏览器组件作为通用平台
直到几年前,浏览器世界还很分散。当时,不同的浏览器在不同程度上遵循 W3C 标准。Firefox 和 Safari 浏览器在遵守标准方面走在了前列,而其他浏览器则落在了后面。
从那以后,很多事情都变了。现在,浏览器在遵守标准方面看起来更好了(在移动平台上更是如此)。这也是事实,因为大多数现代移动平台都有相同的基于 webkit 的浏览器。
此外,桌面和智能手机上的新浏览器已经开始遵循 HTML5/CSS3 等新标准。这为浏览器世界增加了更多功能,减少了移动平台之间的碎片化(参见图 1–11)。

图 1–11。 手机浏览器
我们来看表 1-2 ,表中列出了移动平台及其对应的浏览器平台。如你所见,除了 Windows 7 手机,所有的移动平台都使用基于 webkit 的浏览器。虽然 Windows 7 手机有自己的浏览器,但好消息是,这里列出的所有浏览器都已经遵守 HTML5/CSS3 标准,随着时间的推移,它们的遵守程度将继续提高。
PhoneGap 使用这些现代浏览器作为构建基于 HTML5/CSS3 的应用的平台。把所有 PhoneGap 应用想象成具有嵌入式浏览器并运行这些基于 HTML5/CSS3 的应用。
移动应用网页浏览量
所有这些移动平台都支持在应用中嵌入浏览器。这意味着移动应用的一个屏幕实际上可以是一个显示 HTML 页面的浏览器。
这些嵌入式浏览器通常被称为网络视图。这意味着您可以将应用的一个屏幕定义为 webview。
假设您的应用有一个名为“关于我们”的屏幕“关于我们”屏幕显示贵公司的信息。现在,让我们假设,例如,关于贵公司的“关于我们”的信息经常改变。您的移动应用的要求之一是显示最新的“关于我们”的信息。因此,您可以显示一个指向贵公司“关于我们”页面的 webview,而不是显示一个硬编码的“关于我们”屏幕(最好是网页的移动版本)。它将从网上加载“关于我们”页面。此外,webview 可用于加载和显示本地存储在移动设备上的 HTML 页面。我们可以进一步发展这个概念:我们可以显示与 web 服务交互的基于 Ajax 的 web 页面,而不是静态 web 页面。
本机挂钩暴露设备能力
既然我们知道浏览器可以嵌入到 web 应用中,让我们把注意力转移到通过这些嵌入式浏览器来公开设备功能上。
假设您正在开发一个基于 Flickr API 的 Flickr 应用。在这些 API 的帮助下,你可以登录 Flickr,列出图库,下载和展示你的图片。
虽然这对于 web 应用来说是一个好主意,但是当我们在手机上显示相同的应用时,请记住手机通常有一个摄像头。允许 Flickr 应用从相机中拍摄一张照片并上传到 Flickr 是非常合理的。
为了做到这一点,我们可以让嵌入式浏览器(或 webview)公开 JavaScript API,当调用该 API 时,它会让相机拍摄一张照片,并将该照片的二进制数据返回给我们(参见图 1–12)。

图 1–12。 JavaScript 到本地通信,反之亦然
从技术上讲,所有这些平台都支持在 webview 中将本机模块暴露给 JavaScript。这意味着,从程序上讲,所有这些平台都允许 JavaScript 代码调用本地 Java/C++/Objective C 代码,反之亦然。
让我们看一个例子。我们的 webview 有一个 HTML 页面,显示的是谷歌地图。我们希望根据手机的 GPS 位置将地图居中。为了做到这一点,我们需要编写一个本地组件,向设备查询 GPS 位置。
然后,我们编写代码,从 webview 中公开这个本机模块。webview 中的 JavaScript 代码调用此代码来访问 GPS 坐标。一旦代码获得了 GPS 坐标,它就相应地将地图居中。这是 PhoneGap 框架背后的主要原则。
HTML5 和 CSS3:编写应用的标准
HTML5 和 CSS3 是新兴的 web 技术。他们使网络应用更具交互性,功能更丰富。
HTML5 不仅为更强大的多媒体支持增加了新的标记;它还增加了一些特性,比如用于后台处理的 web worker、离线支持、数据库支持等等。
CSS3 是无缝、丰富的用户界面(UI)的新标准。设计师被要求在按钮或边框上制作简单的圆角或渐变的日子已经一去不复返了。有了 CSS3,事情变得更容易、更快、更好。
有了对动画的支持,CSS3 站点现在可以与基于 flash 的站点竞争了。不仅如此,只需更改 CSS 文件,门户网站就可以轻松地转换为移动网站。此外,打印预览现在可以实现不同的 CSS 文件。
众所周知,移动浏览器是 W3C 标准的早期采用者。这意味着手机是 HTML5/CSS3 应用的合适平台。
单一原产地政策不适用
对于那些使用过基于 Ajax 的应用的人来说,你知道托管在“abc.com”上的 web 应用不能对托管在“xyz.com”上的 web 服务进行 Ajax 调用。这意味着如果有人正在开发一个基于 Ajax 的应用,比如托管在 myphotobook.com 上,他或她将不能对 flickr.com 进行 Ajax 调用。
这被称为单一原产地政策——你可以在[en.wikipedia.org/wiki/Same_origin_policy](http://en.wikipedia.org/wiki/Same_origin_policy)进一步了解单一原产地政策。
对于 PhoneGap 应用来说,情况并非如此。PhoneGap 应用捆绑了所需的 HTML、JavaScript 和 CSS 文件,PhoneGap 应用没有像“abc.com”这样的域。这使得 PhoneGap 成为一个易于开发混搭的平台,可以自由地对各种其他站点进行 Ajax 调用。
想象一下,您的 PhoneGap 应用将脸书、Twitter 和 Flickr 集成到一个 mashup 中,只需要几行 JavaScript 代码。
这使得 PhoneGap 成为为在 programmableweb.com 上市的网络服务创建移动应用的理想平台。
这些限制在图 1–13 中说明:

图 1–13。 单一原产地政策
结论
PhoneGap 使用 HTML5、JavaScript 和 CSS3 来开发移动应用。这些是网络世界的标准技术。通过使用 PhoneGap,很少或没有母语背景的开发人员可以开始为所有流行的移动平台开发移动应用。
尽管 PhoneGap 提供了对移动应用标准原生功能的访问,但它的插件框架足够灵活,可以根据需要扩展和添加新功能。
PhoneGap 是一项正在发展的技术,用于开发跨移动平台应用。
二、PhoneGap 入门
PhoneGap 是一个 HTML5 应用框架,用于通过 web 技术开发本地应用。这意味着开发人员可以利用他们现有的 HTML、CSS 和 JavaScript 知识开发智能手机和平板电脑应用。有了 PhoneGap,开发人员就不必为 iPhone 学习像 Objective-C 这样的语言了。
使用 PhoneGap 开发的应用是混合应用。这些应用不完全基于 HTML/JavaScript,也不是本地的。应用的各个部分,主要是 UI、应用逻辑和与服务器的通信,都是基于 HTML/JavaScript 的。与设备(手机或平板电脑)进行通信和控制的应用的另一部分基于该平台的本地语言。PhoneGap 提供了从 JavaScript 世界到平台本地世界的桥梁,允许 JavaScript API 访问和控制设备(手机或平板电脑)。
PhoneGap 本质上为 JavaScript API 提供了对设备(手机或平板电脑)功能的访问,如摄像头、GPS、设备信息等。这些 API 将在第四章中详细介绍。
本章首先为您提供理解 PhoneGap 整体架构的适当信息。然后,我们将在 PhoneGap 示例中应用这些信息。在本章的最后,我们将使用 PhoneGap 编写一个小的 Hello World 应用。
注: PhoneGap 是一个框架;它没有为编码提供任何 ide 或特殊的开发环境。您将需要使用 Eclipse 和 Android SDK 来为 Android 开发 PhoneGap 应用;您需要使用 Xcode 为 IPhone 开发 PhoneGap 应用。
PhoneGap 架构

图 2–1。 PhoneGap 应用架构
PhoneGap 框架主要是一个 JavaScript 库,允许 HTML/JavaScript 应用访问设备功能。PhoneGap 框架也有一个本地组件,它在幕后工作,并在设备(手机或平板电脑)上完成实际工作。
请参考图 2–1 了解 PhoneGap 的整体架构。使用 PhoneGap 构建的应用主要由两部分组成:
- JavaScript 业务逻辑部分,驱动 UI 及其功能。
- JavaScript 部分,用于访问和控制设备(手机或平板电脑)。
考虑一个脸书应用。该应用的主要部分将是登录页面,并下载照片库。现在你想添加一个你可以拍照并上传到脸书的模块。为了做到这一点,您可以调用 PhoneGap 的相机 API 来访问手机的相机,拍摄照片,并获取图片文件。下一步是对脸书服务器的 AJAX 调用,以便上传图片。另一个可以应用的例子是使用 PhoneGap 在数据库中存储朋友列表,这样我们就可以搜索当地的朋友。
前面的描述给人的印象是,在 PhoneGap 中开发移动应用需要编写更多的业务逻辑和 UI,而很少访问设备的功能,这是正确的。这本书不仅解释了 PhoneGap APIs,也是创建基于 HTML5/CSS3 的移动应用的指南。
在 Android 上设置环境
创建 PhoneGap 应用的第一步是设置一个移动开发环境。我们将从 Android 开始,因为 Android 应用是用 Java 开发的,Java 基于 Eclipse,支持 PhoneGap 的几乎所有功能。
您需要下载并安装 Android 的以下必备软件:
- JDK 1.6 以上
- Eclipse 3.4 到 3.6
- 采用 Android 2.2 平台的 Android SDK
- Eclipse 的 Android ADT 插件
- Android 2.2 版的 Android AVD
- Android 版 PhoneGap SDK 1.1.0
由于 Android 是用 Java 编程的,所以我们需要 JDK 1.6+和 Eclipse 3.4+。然后我们将安装 Android SDK。Android SDK 是一个通用的 SDK,不支持任何平台。一个平台就是一个操作系统版本,例如 2.2 版的 Froyo、2.3 版的津嘉·布雷德和 3.0 版的蜂巢。为了创建、构建和运行 Android 项目,需要下载这些平台。这个插件叫做 Android ADT 插件。
一旦 Eclipse、Android SDK 和 Android ADT (Eclipse 插件)都设置好了,我们就需要为 Android 创建一个模拟器环境。这被称为准备 Android AVD (Android 虚拟设备)。如果我们正在为 Android 开发一个针对 2.2 Froyo 的 PhoneGap 应用,我们需要一个相同 Android 平台的 AVD。
以下步骤将解释如何创建一个 Android 项目并将 PhoneGap 库注入到 Android 中。
PhoneGap Android 项目的必需安装
- 安装 Eclipse 的 3.4 版本。
- 安装 Android SDK。
- 为 Eclipse 安装 Android ADT 插件。
- 为模拟器创建 AVD。
- 安装 PhoneGap 库。
第一步:安装 Eclipse
这一步假设您已经安装了 Java SDK 1.6。安装完成后,从[www.eclipse.org/downloads/](http://www.eclipse.org/downloads/)下载 Eclipse。参见图 2–2 查看 eclipse 下载页面。我们需要一个支持 JDT (Java 开发环境)的 Eclipse IDE 版本 3.4+。您应该为 Java 开发人员安装 Eclipse IDE。

图 2–2。 月食下载页面
第二步:安装 Android SDK
设置 Android 开发环境的一些步骤是依赖于平台的。为了避免任何混淆,我们将解释如何以特定于平台的方式执行每个步骤。
从[developer.android.com/sdk/index.html](http://developer.android.com/sdk/index.html)开始下载 Android SDK(参见图 2–3)。

图 2–3。 Android SDK 下载页面
针对 Windows 的说明
使用 Android 安装程序,安装程序 r11-windows.exe 安装 Android SDK。这是推荐的 Windows 安装技术。另一种方法是下载 android-sdk r11-windows.zip 文件,并将其解压缩到一个文件夹中。我们假设 Android SDK 被提取到 c:\android_sdk。
【Linux 操作说明
下载 Archie Android-dk _ r11-Linux _ x86 . tgz 归档文件并解压到一个文件夹中。
Mac OSX 英特尔指令
下载存档 android-sdk_r11-mac_x86.zip 文件,并将其解压缩到文件夹中。
这个 Android SDK 可以支持目前已经发布的所有 Android 平台。这些平台包括 Android 1.1 平台到最近的 Android 3.0(蜂巢)平台。由于没有人需要所有的平台,Android SDK 没有预装任何平台。
对于本书,我们将只关注 SDK 平台:Android 2.2、API 8 和 revision 3。
由于没有预装平台,下一步是安装您感兴趣的平台。转到 Android SDK 位置(在我们的例子中是 c:\android_sdk),在 tools 文件夹中打开一个名为 Android 的可执行文件。如果您有带宽限制,不要下载所有平台,只下载 Android 2.2 平台(SDK 平台 Android 2.2、API 8 和修订版 3)。
这将打开在图 2–4 中看到的以下屏幕。选择可用的包选项,检查 Android 存储库,然后单击 Install。

图 2–4。 可以安装的可用平台包
既然您已经下载了平台,那么您就拥有了为目前已经发布的所有 Android 版本创建应用的必要工具。
建议您安装所有可用的包,这样您就可以有工具为已经发布的任何 Android 平台创建 Android 项目。
如果你想开发一个适用于 Froyo (Android 2.2)的移动应用,你需要有 Froyo (Android 2.2。)列在已安装的软件包中。
步骤 3:为 Eclipse 安装 Android ADT 插件
- 启动 Eclipse 并点击 Help->Install New Software 打开可用软件对话框。
- 在“使用”文本框中,输入 URL
[dl-ssl.google.com/android/eclipse](https://dl-ssl.google.com/android/eclipse),如图 2–5 所示。 - 当您看到安装开发人员工具的选项时,单击它,选中开发人员工具复选框中的所有复选框,然后单击下一步。

图 2–5。 为 Eclipse 安装 Android ADT 插件
-
用之前安装的 Android SDK 的位置配置 Android ADT 插件。通过单击 Windows-> Windows 的首选项和 Eclipse-> Mac 的首选项打开 Eclipse 的首选项。如果您收到未签名内容警告对话框,您可以安全地忽略它。
-
In the Preferences pane, click and expand the Android option. You will see Android Preferences pane as shown in Figure 2–6. In the Android Preferences pane, put in the location of the Android SDK in the SDK Location text box, and hit Apply.
如果 Android SDK 的位置是正确的,您应该在 Target Name 下看到许多选项,包括 Android 2.2。

图 2–6。 在 Android 首选项屏幕中设置 Android SDK 的位置。
步骤 3:为 Android 2.2 平台创建 Android AVD
-
Open Eclipse and create a workspace for the Android PhoneGap. The next step is to create an emulator for Android. Since Android comes with many platform versions, we have to create an Android Virtual Device (AVD) for each platform that is targeted. In Figure 2–7, you will see your eclipse as depicted in the screen.
请注意,Android 模拟器运行的是 Android 虚拟设备(AVD)。
![images]()
图 2–7。 带 ADT 插件的 Eclipse。
-
Click on the
button on the toolbar to open the Android SDK and the AVD Manager. Choose the Virtual Devices option as depicted in Figure 2–8. ![images]()
图 2–8。Android SDK 和 AVD 管理器
-
点击新建按钮创建一个新的 AVD。选择 Android 2.2 平台,也就是 Froyo。选择 128 MB 的 SD 卡大小,并选择皮肤内置为 HVGA。填写完所有内容后,单击 Create AVD。参见图 2–9 查看“AVD 屏幕”的样子。

图 2–9。 创建一个新的 Android 虚拟设备(AVD)在 Android 模拟器中运行
您将看到创建的 AVD,如图 2–10 所示。

图 2–10。 安卓 2.2 平台的 AVD(Froyo)
步骤 4:安装 PhoneGap SDK
-
Download the PhoneGap SDK 1.1.0 from the following link,
[phonegap.googlecode.com/files/phonegap-1.1.0.zip](http://phonegap.googlecode.com/files/phonegap-1.1.0.zip). After this zip is extracted you should see a directory structure, as seen in Figure 2–11.![images]()
图 2–11。 PhoneGap SDK 1.1.0 目录结构
-
选择 Android 目录,你会看到 phonegap-1.1.0.jar 和 phonegap-1.1.0.js 文件(见图 2–12)。

图 2–12。PhoneGap SDK 内的 Android 文件夹。
这就完成了 Android PhoneGap 的设置。
创建新项目
本书中的第一个应用是 Hello World 应用。加载 PhoneGap 框架后,Hello World PhoneGap 移动应用会在屏幕上显示 Hello World。
第一步:创建一个 Android 项目
打开 Eclipse,点击文件->新建项目->Android 项目。这将打开一个 Android 项目对话框,如图 2–13 和图 2–14 所示。这显示在以下步骤中:
- 将 PhoneGap-helloworld 作为项目名称。
- 确保您已经选择了 Android 2.2 作为构建目标。
- 输入 Helloworld 作为应用名称。这是应用的可读名称。
- 输入
org.examples.phonegap.sample作为包名。Android market 中的一个应用是由包名唯一标识的。Android market 上不能有两个具有相同包名的 Android 应用。 - 选中“创建活动”复选框,并输入 helloworld 作为活动名称。Android 中的活动是一个屏幕。并且活动名也是活动的类名。
- 在 min SDK 版本中放 7。这意味着您将允许所有 Android 2.1 设备平台(也称为 clair Android 手机)搜索和安装该应用。

图 2–13。 安卓项目创建

图 2–14。 Android 项目创建。
步骤 2:将 PhoneGap 库添加到项目中
一旦创建了 Android 项目,就该将 PhoneGap 框架注入到 Android 项目中了。正如我们之前提到的,PhoneGap 有三个主要组件:原生组件、XML 插件和 JavaScript 文件。
-
要在 Android 中安装原生组件,在项目中创建一个名为 lib 的目录,并将 PhoneGap jar 复制到其中。您可以将
phonegap-1.1.0.jar拖放到 lib 文件夹中,也可以将其复制并粘贴到 Eclipse IDE 的 lib 文件夹中。接下来,通过右键单击 Build Path - > Add to Build Path,将 PhoneGap jar 添加到类路径中。这在图 2–15 中突出显示。 -
Copy the XML directory from the PhoneGap’s Android Directory into the res folder.
![images]()
图 2–15。 突出显示 Android 项目中 PhoneGap jar 的位置
-
一旦 PhoneGap Jar 被添加到 Android 项目中,就该将 PhoneGap 的 JavaScript 文件注入到项目中了。我们将在 Android 项目的 Assets 文件夹下创建一个 www 文件夹。Assets 文件夹类似于 Android 应用的 media 文件夹。在我们的例子中,我们将把基于浏览器的应用的所有文件放在 www 文件夹中。首先,将 PhoneGap JavaScript 文件添加到 www 文件夹中,该文件夹位于 Assets 文件夹中。这在图 2–16 中突出显示。

图 2–16。 突出显示 PhoneGap JavaScript 文件在 Android 项目中的位置
第三步:修改 Android 权限
在 Android 应用中,主文件是 Android 清单文件。在这个文件中有许多特定的东西,比如包名,它们唯一地标识了市场上的应用。主文件包含一个名为 permissions 的部分。Android 使用这一部分来通知用户应用将使用手机的某些功能。假设一个应用打算使用互联网获取数据;需要获得许可才能安装应用。当用户安装应用时,Android market 会向他显示该应用将被允许使用互联网。
对于 PhoneGap,需要添加以下权限:
- 向 Android 清单 XML 添加以下权限:
<uses-permission android:name=*"android.permission.CAMERA"* /> <uses-permission android:name=*"android.permission.VIBRATE"* /> <uses-permission android:name=*"android.permission.ACCESS_COARSE_LOCATION"* /> <uses-permission android:name=*"android.permission.ACCESS_FINE_LOCATION"* /> <uses-permission android:name=*"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"* /> <uses-permission android:name=*"android.permission.READ_PHONE_STATE"* /> <uses-permission android:name=*"android.permission.INTERNET"* /> <uses-permission android:name=*"android.permission.RECEIVE_SMS"* /> <uses-permission android:name=*"android.permission.RECORD_AUDIO"* /> <uses-permission android:name=*"android.permission.MODIFY_AUDIO_SETTINGS"* /> <uses-permission android:name=*"android.permission.READ_CONTACTS"* /><uses-permission android:name=*"android.permission.WRITE_CONTACTS"* /> <uses-permission android:name=*"android.permission.WRITE_EXTERNAL_STORAGE"* /> <uses-permission android:name=*"android.permission.ACCESS_NETWORK_STATE"* /> - 我们还需要在清单文件中添加 supports-screen 选项,如下所示:
<supports-screens android:largeScreens=*"true"* android:normalScreens=*"true"* android:smallScreens=*"true"* android:resizeable=*"true"* android:anyDensity=*"true"* /> - 将
android:configChanges=orignetation|keyboardHidden添加到 Android 清单中的活动。这告诉 Android 当用户翻转手机,屏幕从纵向切换到横向时,不要取消和重新创建活动,反之亦然。 - 通过应用以下 XML 片段,在前一个活动之后添加第二个活动:
<activity android:name="com.phonegap.DroidGap" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden"> <intent-filter> </intent-filter> </activity>
一旦您按照前面的说明修改了 Android Manifest,就会出现一个 Android Manifest XML。将会看到如下内容:
`
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.examples.phonegap.helloworld" android:versionCode="1"
android:versionName="1.0">
<supports-screens android:largeScreens="true"
android:normalScreens="true" android:smallScreens="true"
android:resizeable="true" android:anyDensity="true" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk android:minSdkVersion="7" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="HelloWorld" android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<activity android:name="com.phonegap.DroidGap" android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
`
第 4 步:修改主活动
在 Android 中,一个名为 activity 的类代表一个屏幕。为了让我们在 Android 中使用 PhoneGap,我们将把屏幕从活动更改为 DroidGap。DroidGap 是一个特殊的活动,它允许我们显示 HTML 页面。该类如 HelloWorld 类的图 2–17 所示。
注意:我们告诉 DroidGap 在 Android 资产中加载 index.html 文件。
`package org.examples.phonegap.helloworld;
import android.os.Bundle;
import com.phonegap.DroidGap;
public class HelloWorld extends DroidGap {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl("file:///android_asset/www/index.html");
}
}` 
图 2–17。 扩展 DroidGap 类的活动
编写 HelloWorld 应用
PhoneGap 应用是一个 HTML/JavaScript 应用。参见图 2–18。下面是 index.html。
- 在 HTML 页面中包含 PhoneGap JavaScript 库版本 1.1.0。
- 用主体的 onload 事件注册
init()方法。 - 在
init()函数中,用 DeviceReady 事件注册 JavaScript 回调函数 onDeviceReady。 - 在 onDeviceReady 回调函数中,将 ID 为“helloworld”的
h1元素的内容更改为文本“hello World!已加载 PhoneGap 框架!”
这里列出了完整的源代码:
`
<script type="text/javascript" src="phonegap-1.1.0.js">
...
` 图 2–18。PhoneGap 项目的 Index.html??
你可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Helloworld](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Helloworld)下载本章的完整源代码
部署到模拟器
为了运行 Android 应用,右键单击 PhoneGap-helloworld 项目,选择 Run As,然后选择 Android 应用。
这将启动带有我们之前创建的 AVD 的模拟器。当应用加载时,您将看到以下屏幕。随着应用的启动,您将在屏幕上看到…,如图图 2–19 所示。

图 2–19。PhoneGap 应用加载了…几秒钟。
加载 PhoneGap 框架后,您会看到应用显示一条消息,如图 Figure 2–20 所示。

图 2–20。PhoneGap 框架加载部署到设备应用后,PhoneGap 应用显示一条消息。
到目前为止,我们已经看到了如何在模拟器上测试应用。但是,有些功能不能在模拟器上测试。为了测试 GPS、相机、加速度计、罗盘和实际用户感知,需要测试实际设备。
部署到设备
将 Android 应用部署到设备需要两个步骤:
第一步:准备好设备。
-
Unlock your device and press the Menu key. This will give you a view that looks like Figure 2–21.
![images]()
图 2–21。 进入安卓手机的设置
-
Click on the Settings and the screen in Figure 2–22 will appear. Choose the Applications option.
![images]()
图 2–22。 进入应用设置
-
Now we must ensure that we can deploy non-Market applications on our device. This is done by clicking the Unknown sources, seen in Figure 2–23.
![images]()
图 2–23。 点击未知来源,我们可以添加非市场应用
-
下一步是进入开发选项(见图 2–24)并启用 USB 调试(见图 2–25)。这允许你将 USB 线的一端插入你的 Android 设备,另一端插入你的 PC 或 Mac。使用 Eclipse 调试设备上运行的应用。

图 2–24。 进入开发选项

图 2–25。启用 USB 调试
现在,您的设备已经准备好部署应用。
Android ADT 插件为 Android 提供了一个 Dalvik 调试监控服务器(DDMS)。DDMS 有许多功能,例如列出当前可用于部署和调试 Android 应用的设备/仿真器,允许用户查看部署在设备/仿真器上的应用的日志消息,以及浏览设备/仿真器的文件系统。
步骤 2:在应用启动类型中,提供我们打算部署到设备的信息。
-
Plug the USB cable into your device, and plug the USB end into your development machines. Now open Eclipse and go into the DDMS perspective (Go to Eclipse->Windows->Open Perspective->DDMS). You will see a screen like Figure 2–26. This screen depicts that we have an Android emulator running, and that we also have an Android device plugged into the machine’s USB input.
![images]()
图 2–26。DDMS 显示我们有一个仿真器在运行,一个设备插入了 USB。
-
当您点击您的 Android 项目的任何 Android 应用的 Run As 时,您将看到图 2–27 中的屏幕。您看到这个屏幕是因为您有一个仿真器和一个可用的设备。这里 Eclipse 会询问您将应用部署到哪里。如果你只有一个设备插入,没有模拟器运行,这个屏幕将不会出现。

图 2–27。 如果有多个设备或仿真器,DDMS 会提示用户选择部署应用的位置。
探索 PhoneGap 功能
本节将探索 PhoneGap 的更多特性。
下面是 PhoneGap 支持的功能的简短总结:
- PhoneGap 的加速计 API 使应用能够感知设备方向的变化,因此,它能够相应地采取行动。这在创建具有气泡水平仪的应用时很有用(确保手机与地面水平对齐)。可以选择读取一次器件方向的变化读数,或者连续接收器件方向的变化。
- PhoneGap 的相机 API 允许应用从相机中检索图片(这对脸书和 Picasa 应用非常有用),或者从现有的照片库中获取图像。
- PhoneGap 的 compass API 帮助应用了解手机的方位。这被证明对于地图和导航应用是有用的,因为地图随着用户改变电话的方位而旋转,存在获取设备航向变化的一个读数或连续接收设备航向变化的选项。
- PhoneGap 的联系人 API 是应用读写联系人的一种方式。许多社交应用可以从同步手机联系人和社交频道上的联系人中受益。
- PhoneGap 的文件 API 允许应用读取、写入和列出目录和文件系统。如果应用计划更改手机文件系统中的文件内容,这将非常方便。这个 API 也可以帮助编写文件浏览器应用。
- 地理位置 API 有助于检索设备的地理位置。这对许多应用都有好处,包括基于地图的应用,以及像 foursquare 这样的应用,用户可以通过使用他们的 GPS 位置来签到。可以选择读取一次设备地理位置的变化,或者连续接收设备地理位置的变化。
- 媒体 API 允许应用控制设备上的媒体传感器和应用。这个 API 允许应用记录和回放音频和视频记录。
- PhoneGap 的网络 API 为应用提供了查看网络状态的能力。这种状态不只是在线和离线,而是告诉应用设备是在 2G/3G/4G 网络上还是在 Wi-Fi 网络上。这些信息通常有助于应用决定何时检索某些类型的信息。
- 通知 API 允许应用通过发出哔哔声、振动或提供可视警报来通知用户发生了什么事情。
- PhoneGap 的存储 API 为应用提供了一个内置的 SQL 数据库。应用可以通过 SQL 语句插入、检索、更新和删除数据。应用可以查询数据库中的数据,并在本地存储的电子邮件列表中搜索特定的电子邮件。
PhoneGap 教程
并非所有的 PhoneGap 教程都可以在 Android 模拟器上完成,因此我们将解释以下检查教程的方法:
- 可以在 Android 模拟器上完成的教程。
- 需要安卓手机才能工作的教程。
仿真器示例
获取设备信息
PhoneGap 允许以编程方式读取设备信息。为此,您需要确保 PhoneGap 框架已经加载。一旦加载了框架,就可以使用 JavaScript 提取设备信息。设备信息的所有属性在表 2–1 中列出。

下面的代码将让您访问设备的信息。同样参见图 2–28。
`
<script type="text/javascript" src="phonegap-1.1.0.js">
Device Info
| Device Name | |
| PhoneGap Version | |
| Mobile Platform | |
| Platform Version | |
| UUID |
` 
图 2–28。??【PhoneGap 设备信息】HTML 源代码
运行这段代码时,图 2–29 中的屏幕应该出现在您的 Android 模拟器上。

图 2–29。在模拟器上运行 PhoneGap 的设备信息
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-DeviceInfo](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-DeviceInfo)下载这个例子的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_device_device.md.html#Device](http://docs.phonegap.com/en/1.1.0/phonegap_device_device.md.html#Device)的设备 API 官方文档。
抓取设备的联系人
我们将使用 PhoneGap 来获取设备的地址簿联系号码。在我们在 Android 模拟器上做这些之前,我们需要用一些联系信息来设置 Android 模拟器。
-
Click on the dialer application icon
seen in Figure 2–30. ![images]()
图 2–30。 点击 Android 模拟器上的 PhoneGap 应用。
-
This will open up the dialer application. Click on the Contacts tab, seen in Figure 2–31.
![images]()
图 2–31。 在手机应用中添加联系人
-
Click Menu and choose New Contact. In the new contact add the first name, last name, and phone number. Refer to Figures 2–32 and 2–33.
![images]()
图 2–32。点击菜单中的和点击新增联系人
![images]()
图 2–33。 添加联系人,点击完成。
-
输入所需的值后,点击完成,您应该会在联系人列表中看到一个联系人(如图 Figure 2–34 所示)。

图 2–34。 联系人列表
为了使用 PhoneGap 访问联系人列表,我们需要使用以下 API:
navigator.service.contacts.find(contactFields, contactSuccess, contactError, contactfindOptions);
Table 2–2 提供了每个参数的描述。

下面提供了生成获取联系人的完整代码的步骤:
-
创建 ContactFindOptions 对象。通过使 options.filter 等于"",我们说我们想要获取所有联系人。如果 options.filter 是 Bob,这意味着我们希望过滤我们的搜索,以便所有结果都必须在 contact 字段的某个位置包含关键字 Bob。
<ins>var</ins> options = new ContactFindOptions(); options.filter=""; -
我们需要定义想要获取的联系人字段。当我们搜索联系人时,会出现一个联系人列表。接触本身是接触字段的关联数组。这意味着,如果我们指定只获取姓名和电话号码联系人字段中的联系人,我们将只获取这些信息。
var fields = [“name”,”phoneNumbers”]; -
定义成功和失败的回叫方法。当我们调用方法
navigator . service . contacts . find()时,我们需要提供两个回调。这是因为 find()方法是一个异步方法。function onSuccess(contacts) { for(<ins>var</ins> index=0;index<contacts.length;index++){ <ins>var</ins> contact= contacts[index]; var contactName = contact.name.formatted; } } function onError(error) { } navigator.service.contacts.find(fields, onSuccess, onError, options); -
Use Android Linkify to allow us to dial numbers. While we list the contacts in the address book as a part of the HTML list (as seen in the following code), `
- Rohit Ghatol
当用户点击链接 Rohit Ghatol 时,Android 会读取要成为 tel 的 URL,并打开拨号器拨打该号码。
这在图 2–36 和图 2–37 中有所描述,它们显示了应用在 Android 模拟器上的外观。
使用下面的代码来应用我们到目前为止所学的内容。参考图 2–35 获取 index.html 源代码。
`
<script type="text/javascript" src="phonegap-1.1.0.js">
Contacts
` 
图 2–35。 PhoneGap 联系人应用 HTML/JavaScript 源代码

图 2–36。 清单联系人

图 2–37。 点击联系人打开电话拨号器。
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Contacts](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Contacts).下载这个例子的完整源代码
可以参考[docs.phonegap.com/en/1.1.0/phonegap_contacts_contacts.md.html#Contacts](http://docs.phonegap.com/en/1.1.0/phonegap_contacts_contacts.md.html#Contacts)的 Contacts API 官方文档。
获取 SD 卡列表
本节将解释如何列出 Android 设备的 SD 卡。本节结合使用了 W3C 标准和 PhoneGap API。
列出 Android 设备的 SD 卡有两个步骤。这些步骤如下:
- 我们解析目录
file:///sdcard并获得对目录条目的访问权。 - 当我们访问 directoryentry 时,我们可以从 directoryentry 创建一个 directoryreader,并获取目录(SD 卡)的内容。
在步骤 1 中,我们调用以下函数:
window.resolveLocalFileSystemURI("file:///<ins>sdcard</ins>", onResolveSuccess, onError);
为了响应前面的函数,onResolveSuccess 回调将被激活。onResolveSuccess 回调可以在下面的代码中看到。一旦我们获得了对 fileEntry 的访问权,我们就从它创建一个 directoryReader,并在这个 directoryReader 上调用 readEntries。
`function onResolveSuccess(fileEntry){
var directoryReader = fileEntry.createReader();
directoryReader.readEntries(onSuccess,onError);
}`
当路径file:///sdcard被成功解析时,onSuccess 方法被调用。onSuccess 方法如下:
function onSuccess(entries){ document.getElementById("loading").innerHTML=""; <ins>var</ins> <ins>ul</ins> = document.getElementById("file-listing"); for(<ins>var</ins> index=0;index<entries.length;index++){ <ins>var</ins> <ins>li</ins> = document.createElement('<ins>li</ins>'); li.innerHTML = entries[index].name; ul.appendChild(<ins>li</ins>); }
部署到模拟器
以下代码提供了如何部署到模拟器的完整示例:
`
List SDCard Contents
Loading ..
`
该代码如图 2–38 所示。

图 2–38。sd 卡上的清单文件
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-DirectoryListing](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-DirectoryListing)下载本章的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_file_file.md.html#File](http://docs.phonegap.com/en/1.1.0/phonegap_file_file.md.html#File)的 File API 官方文档。
写入和读取文件
这一节将向您展示如何使用 PhoneGap APIs 来操作文件系统。
注意: PhoneGap 实际上正在实现和支持在[www.w3.org/TR/file-system-api/](http://www.w3.org/TR/file-system-api/)提到的 W3C 的文件系统规范。
让我们熟悉一下文件系统 API 中的一些关键概念。这些关键概念是:
- 本地文件系统
- 文件系统
- 文件入口
- 目录项
本地文件系统
LocalFileSystem 为我们提供了对本地文件系统及其文件和目录的访问。有两种类型的文件系统:
- 本地文件系统。PERSISTENT :在没有用户明确授权的情况下,除了响应删除 API 调用之外,存储在持久性文件系统中的数据不应被 UA 删除。
- 本地文件系统。临时:UA 可以自行删除临时文件系统中存储的数据,无需应用或用户干预。
localFileSystem 方法是从 window 对象中访问的。这是通过以下方式完成的:
- window . request file system()–用于获得对根文件系统的访问权限。
- window . resolvelocalfilesystemuri()–用于直接访问 FileEntry 或 DirectoryEntry 对象,前提是 URI 可用于该目录或文件。
文件系统
文件系统代表文件系统。它有两个主要属性:
- 名称–在两个选项“永久”或“临时”之间选择。如果您希望文件即使在应用被终止时也能持久保存,请选择“持久保存”。
- Root—文件系统的根目录(DirectoryEntry)。
您需要使用以下 API 来访问文件系统:
void requestFileSystem ( short type, // LocalFileSystem.PERSISTENT or //LocalFileSystem.TEMPORARY long long size, //Size for TEMPORARY FS FileSystemCallback successCallback, //Success Callback optional ErrorCallback errorCallback); // Failure Callback
获得文件系统访问权限的代码片段如下:
window.requestFileSystem(LocalFileSystem.PERSISTENT ,0 //size ,function(fileSystem){ // success callbac alert(“Got FileSystem “+fileSystem); }, function(err){ //failure callback alert(“Got Error requesting FileSystem”); } );
您需要使用以下 API 来访问 fileEntry 或 directoryEntry 对象(代表文件或目录的对象):
void resolveLocalFileSystemURL ( DOMString url, //url of file or directory on //filesystem EntryCallback successCallback, //Success Callback optional ErrorCallback errorCallback); //FailureCallback
档案输入
为了操作一个文件,你需要一个 fileEntry 对象。有许多方法可以获得 fileEntry,但是假设您知道文件的 URI,您可以如下获得该对象:
window.resolveLocalFileSystemURL( “file:///sdcard/read-write.txt”, function(fileEntry){ }, function(err){ } );
为了查找 fileEntry 的所有属性和方法,您需要访问 fileEntry 的附录。有两种方法可以获得这种访问权限:
- createWriter():创建可用于写入文件的 FileWriter 对象。
- file():创建一个包含文件属性的 File 对象,包括读取其内容。
导演
为了列出目录中的文件,您需要一个 directoryEntry 对象。有许多方法可以获得 directoryEntry,但是假设您知道目录的 URI,您可以如下获得该对象:
window.resolveLocalFileSystemURL( “file:///sdcard/mydir/”, function(directoryEntry){ }, function(err){ } );
为了查找 directoryEntry 的所有属性和方法,您需要访问 directoryEntry 的附录。有一种方法可以获得这种访问:getFile():在给定目录中创建文件,或者从给定目录中获取文件。
程序布局
我们的文件读写程序很简单。它包含一个文本区域,我们可以在这里读取文件内容,也可以将文本区域的内容写入文件。我们使用两个按钮 Read 和 Write 来读/写一个名为 read-write.txt 的文件。
下面是程序的代码。
`
Read Write File
/sdcard/read-write.txt | |
`
运行时的该代码在图 2–39 中说明。

图 2–39。 读写文件。
现在,让我们实现 readFile()方法来读取文件并在 TextArea 中显示其内容。步骤非常简单:
第一步:解析网址file:///sdcard/read-write.txt。
步骤 2: 如果解决了,使用 fileEntry.file()方法创建一个读取器。
步骤 3: 如果没有解决,向用户显示一条消息,告诉用户他需要先写文件,然后才能读取它..参见图 2–40。
`function readFile(){
window.resolveLocalFileSystemURI( //filename to be read
filePath, //success callback
function(fileEntry){
fileEntry.file(
function(file){
var fileReader = new FileReader();
fileReader.onloadend =
function(evt){
document.getElementById("textarea").value
= evt.target.result;
};
fileReader.readAsText(file);
},
function(error){
alert("Got error while reading "+filePath);
})
}, //error callback
function(error){
alert(filename + " not present, please add content and click
Save first");
}
);
}` 
图 2–40。 由于没有写入文件,无法读取。
让我们实现 writeFile()方法读取 TextArea 中的文本,并将其写入file:///sdcard/read-write.txt。
步骤 1: 访问文件系统根目录。
步骤 2: 从文件系统根目录 Entry 创建文件 read-write.txt,如果它还不存在的话。
第三步:创建 fileWriter,将 TextArea 的内容写入文件。这显示在以下代码中:
`function saveFile() {
window.requestFileSystem(
LocalFileSystem.PERSISTENT, 0,
//Success Callback
function (fileSystem) {
var sdcardEntry = fileSystem.root;
sdcardEntry.getFile(
filename,
//Flag telling create file
{
create: true
},
//Success callbacks
function (fileEntry) {
fileEntry.createWriter(
function (fileWriter) {
fileWriter.onwrite = function (evt) {
alert("Write was successful!");
document.getElementById("textarea").value = "";
};
fileWriter.write(document.getElementById("textarea").value);
},
//Error callback
function (error) {
alert("Failed to get a file writer for " + filename);
});
},
//Error Callback
function (error) {
alert("Got error while reading " + filename + " " + error);
});
}, function (error) {
alert("Got Error while gaining access to file system");
});
}`
当用户在文本区域中键入文本并点击 Write 时,内容被写入文件并显示一条警告消息,提示 Write 成功。你会注意到当你点击 Write 时,程序会清空文本区。参见图 2–41 查看文件写入成功时的信息。

图 2–41。 写成功了
现在,点击 read 按钮,尝试读取您写入文件的内容。你写的内容应该出现在文本区。参考图 2–42 查看当读取成功时,文本区域是如何填充的。

图 2–42。 阅读成功
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/62c45e339662/android/PhoneGap-FileReadWrite](https://bitbucket.org/rohitghatol/apress-phonegap/src/62c45e339662/android/PhoneGap-FileReadWrite)下载这个例子的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_file_file.md.html#File](http://docs.phonegap.com/en/1.1.0/phonegap_file_file.md.html#File)的 File API 官方文档。
写入和读取数据库
本节将解释如何读取、存储和操作数据库。我们将使用在数据库中存储联系人列表(名字和姓氏)的例子,然后读取它,并删除条目。
有三个表:一个用于标题列,一个用于内容,还有一个允许用户向联系人列表添加条目。
以下是从数据库中读取和写入的 index.html 代码:
`
Read Write DB
First Name | Last Name | Action |
`
如果运行该程序,您应该会看到类似于图 2–43 所示的布局

图 2–43。 读写数据库
现在,让我们添加一些代码来读取、写入和删除数据库中的联系人条目。第一步是访问数据库对象。这是按如下方式完成的:
`var firstNameBox = null;
var lastNameBox = null;
var db = null;
var dataTable = null;
/** Called when phonegap javascript is loaded */
function onDeviceReady(){
var addButton = document.getElementById("add");
firstNameBox = document.getElementById("firstName");
lastNameBox = document.getElementById("lastName");
dataTable = document.getElementById("data-table");
db = window.openDatabase("contactDB", "1.0", "Contact
** Database", 1000000);**
//name,version,display name, size
}`
让我们把重点放在创建数据库对象的 API 上。这是按如下方式完成的:
window.openDatabase( databaseName, versionNumber, displayName, sizeInBytes);
现在让我们看一下代码(参考下面的 addButton.addEventListener ),它解释了单击 Add 按钮并向数据库中的 contacts 表添加条目的过程。
为了向 contacts 表添加条目,我们将在数据库对象上使用 transaction()方法。下面是这个方法的 API:
db.transaction( function(tx){ //Function to execute the sql statements //Use tx to execute sql statements }, function(err){ // Error callback //Use err.code and err.message to understand the error }, function(){ //Success callback // Update the UI, log a message } );
我们希望在用户点击按钮时添加新条目。因此,我们的添加功能位于添加按钮的 click 事件侦听器中。这可以在下面的代码中看到:
`addButton.addEventListener(
"click",
function(){
db.transaction(
//function sql statements
function (tx){
ensureTableExists(tx);
var firstName = firstNameBox.value;
var lastName = lastNameBox.value;
var sql = 'INSERT INTO Contacts
( firstName, lastName ) VALUES
("' + firstName + '","' + lastName + '")';
tx.executeSql(sql);
},
//error callback
function (err){
alert("error callback "+err.code);
},
//success callback
function (){
loadFromDB();
} );
},false);
function ensureTableExists(tx){
tx.executeSql('CREATE TABLE IF NOT EXISTS Contacts (id
INTEGER PRIMARY KEY, firstName,lastName)');
}`
我们使用一个名为 ensureTableExists(tx)的方法,它确保我们在数据库中执行 DB CRUD 操作之前拥有数据库表。
我们在数据库事务的 SQL 函数中使用 SQL insert 语句,以便在数据库中创建一个条目。
注意:默认情况下,SQLite 中的主键是自动递增的,因此,我们只写名字和姓氏,数据库实际上是递增 ID。
一旦数据库成功添加了操作,我们就调用 loadFromDB()方法从数据库表中填充 HTML 表。
请参考 Figure 2–44 查看添加联系人功能的 UI 屏幕。

图 2–44。 添加条目
现在,让我们来看看 loadFromDB()方法。这里我们使用相同的 tx.executeSql,但是在这种情况下,我们期望得到一些不同的结果,所以我们使用下面版本的 tx.executeSql:
tx.executeSql( sqlStatement, options, successCallbackWithResultSet, errorCallback);
successCallbackWithResultSet 是一个接收两个内容的函数:
- 税
- 结果集
`function loadFromDB(){
db.transaction(
//function sql statements
function (tx){
ensureTableExists(tx);
tx.executeSql('SELECT * FROM Contacts',
[],
//success callback
function(tx, results){
var htmlStr="";
for(var index=0;index<results.rows.length;index++){
var item =
results.rows.item(index);
htmlStr = htmlStr +""+
item.firstName+""
+item.lastName
+"<button
onclick="deleteEntry('"
+item.id+
"');">X";
}
dataTable.innerHTML=htmlStr;
},
//error callback
function(err){
alert("Unable to fetch result from Contacts
Table");
}
);
},
//error callback
function (err){
alert("error callback "+err.code+" "+err.message);
},
//success callback function (){
firstNameBox.value="";
lastNameBox.value="";
});
}`
当我们现在运行代码时,我们可以在 HTML 表中看到之前添加的条目。
参考图 2–45,它显示了之前在 html 表格中添加的行。

图 2–45。 从数据库中读取所有条目
最后要做的事情是当用户单击 X 按钮时删除条目。当我们填充 HTML 表时,我们在 HTML 中定义按钮如下:
<button onclick="deleteEntry(‘”+item.id+"’);’>X</button>
参考 Figure 2–46 查看这在 HTML 中的样子。
当用户单击 X 按钮时,调用 deleteEntry 函数,传递要删除的条目的主键。这里,我们使用 Delete SQL 语句删除主键。
function deleteEntry(id){ db.transaction( //function <ins>sql</ins> statements function (tx){ ` ensureTableExists(tx);
tx.executeSql('Delete FROM Contacts where id='+id);
},
//error callback
function (err){
alert("error callback "+err.code+" "+err.message);
},
//success callback
function (err){
loadFromDB();
}
);
}` 
图 2–46。 从数据库中删除条目
现在,当用户单击 X 按钮时,条目被删除,并调用 loadFromDB(),从数据库表刷新 HTML 表。

图 2–47。 删除条目被反映
完整的 index.html 资料如下:
`
Read Write DB
First Name | Last Name | Action |
`
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/62c45e339662/android/PhoneGap-DB](https://bitbucket.org/rohitghatol/apress-phonegap/src/62c45e339662/android/PhoneGap-DB)下载这个例子的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_storage_storage.md.html#Storage](http://docs.phonegap.com/en/1.1.0/phonegap_storage_storage.md.html#Storage)的存储 API 官方文档。
获取手机或无线网络的详细信息
通常,移动应用需要连接到某个服务器,以便获取某些数据。现代智能手机可能会使用 3G/4G 网络或 Wi-FI 网络下载数据。一个好的应用会尊重这种区别,在 3G/4G 网络上下载某些类型的数据,只有在智能手机在 Wi-Fi 网络上时才下载大量数据。
本节将解释如何使用 PhoneGap 来找出智能手机正在使用哪种网络。
我们将需要使用以下 API:
navigator.network.connection.type
这将返回连接的类型。不同连接类型的值如下所述:
Connection.UNKNOWN = "unknown"; Connection.ETHERNET = "ethernet"; Connection.WIFI = "wifi"; Connection.CELL_2G = "2g"; Connection.CELL_3G = "3g"; Connection.CELL_4G = "4g"; Connection.NONE = "none";
下面列出了 index.html 的完整源代码:
`
<script type="text/javascript" src="phonegap-1.1.0.js">
Phone Network Info
`
当该源运行时,它将显示网络信息,如图 2–48 所示。

图 2–48。 PhoneGap 网络信息显示网络连接属于 3G 类型
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Network](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Network)下载这个例子的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_connection_connection.md.html#Connection](http://docs.phonegap.com/en/1.1.0/phonegap_connection_connection.md.html#Connection)的连接 API 官方文档。
设备示例
鉴于这些特性的性质,以下示例只能在真实的 Android 设备上运行。Android 模拟器不支持以下功能。
获取地理位置
在本例中,我们将尝试获取设备的地理位置。为此,我们将使用 navigator.geolocation API。这个 API 是一个异步 API,这意味着一旦我们请求地理定位的 API,API 将通知被调用的程序,并使用向 API 注册的两个回调中的一个。
调用的 API 如下:
navigator.geolocation.getCurrentPosition(onSuccessCallback, onErrorCallback);
当 API 能够获取 GPS 坐标时,API 调用 onSuccessCallback 函数。当获取 GPS 坐标出现问题时,API 将调用 onErrorCallback。
onSuccessCallback 将获得一个名为 position 的参数。该位置将包含有关地理位置的详细信息,如表 2–3 所示。

完整的代码示例如下所示:
`
<script type="text/javascript" src="phonegap-1.1.0.js">
GeoLocation
| Latitue | |
| Longitude | |
| Altitude | |
| Timestamp | |
`
该代码如图 2–49 所示。

图 2–49。PhoneGap 地理位置运行示例
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-GeoLocation](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-GeoLocation)下载这个例子的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_geolocation_geolocation.md.html#Geolocation](http://docs.phonegap.com/en/1.1.0/phonegap_geolocation_geolocation.md.html#Geolocation)的地理定位 API 官方文档。
获取加速度计
在本例中,我们将尝试观察设备的加速度计读数。现代智能手机中的加速度计功能为用户提供了 x、y 和 z 坐标中的运动方向。
调用的 API 如下:
navigator.accelerometer.watchAcceleration(onSuccessCallback, onErrorCallback,accelerometerOptions);
该 API 将持续监控加速度计读数,并以预定义的时间间隔调用 onSuccessCallback,直到调用 navigator . accelerator . clear watch()为止。通过以{"frequency":"3000"}的形式提供值,在 accelerometerOptions 中定义间隔。间隔的单位是毫秒。如果 accelerometerOptions 不提供默认的间隔 1000,则使用毫秒。
正如前面的例子中提到的,当获取 GPS 坐标出现问题时,API 将调用 onErrorCallback。
onSuccessCallback 将获得一个名为 acceleration 的参数。加速度将包含设备运动的详细信息,如表 2–4 所示。

完整的代码示例如下:
<!DOCTYPE HTML> <ins><html></ins> <head> <title>PhoneGap</title> <script type="text/<ins>javascript</ins>" <ins>src</ins>="<ins>phonegap-1.1.0.js</ins>"></script> <script type="text/<ins>javascript</ins>"> /** Called when <ins>phonegap</ins> <ins>javascript</ins> is loaded */ `function onDeviceReady(){
var options = { frequency: 1000 }; // Update every 1 seconds
navigator.accelerometer.watchAcceleration(onSuccess,
onError,options);
}
function onSuccess(acceleration) {
document.getElementById('x').innerHTML = acceleration.x;
document.getElementById('y').innerHTML = acceleration.y;
document.getElementById('z').innerHTML = acceleration.z;
document.getElementById('timestamp').innerHTML
= acceleration.timestamp;
}
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
/** Called when browser load this page*/
function init(){
document.addEventListener("deviceready", onDeviceReady, false);
}
Accelerometer
| X | |
| Y | |
| Z | |
| Timestamp | |
`
该代码如图 2–50 所示。

图 2–50。 PhoneGap 加速计示例
在图 2–51 中可以找到相同加速度计的图示版本。通过将手机平放在某个表面上,加速度计可用于检查该表面的水平。
你可以在[code.google.com/p/beginingphonegap/downloads/list](http://code.google.com/p/beginingphonegap/downloads/list)找到这个例子的图形。

图 2–51。 使用 PhoneGap 加速计 API 构建气泡应用
在前一个例子中使用了四个图像。这些图像从圆形气泡变化到椭圆形气泡。完整的代码示例如下所示:
`
<script type="text/javascript" src="phonegap-1.1.0.js">
Accelerometer
<img id="circle" src="accelerometer-circle-bubble.png"
style="position:absolute">
<img id="x-y-base" src="x-y-accelerator-base.png">
<img id="x-base" src="z-accelerator-base.png">
<img id="oval" src="accelerometer-circle-oval.png"
style="position:absolute;left:0px">
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Accelerometer-Image](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Accelerometer-Image)下载这个例子的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_accelerometer_accelerometer.md.html#Accelerometer](http://docs.phonegap.com/en/1.1.0/phonegap_accelerometer_accelerometer.md.html#Accelerometer).的加速度计 API 官方文档
获取罗盘方位
让我们来看一个与加速度计功能相似的应用。一个指南针。像加速度计一样,指南针提供设备在 x、y 和 z 轴上的运动。指南针提供设备在顺时针方向上相对于正北方向以度为单位方向。
你可以在[code.google.com/p/beginingphonegap/](http://code.google.com/p/beginingphonegap/)找到这个例子的图形。
调用的 API 如下:
navigator.compass.watchHeading (onSuccessCallback, onErrorCallback,compassOptions);
这个 API 将持续监视指南针前进的方向,并以预定义的间隔调用 onSuccessCallback,直到 navigator.compass.clearwatch()被调用。间隔在 compassOptions 中定义,并以{"frequency":"3000"}的形式提供一个值。间隔的单位是毫秒。如果未提供 compassOptions,则使用默认的时间间隔 1000 毫秒。
正如前面的例子中提到的,当获取 GPS 坐标出现问题时,API 将调用 onErrorCallback。
onSuccessCallback 将获得一个名为 heading 的参数。航向是 0 度到 360 度之间的度数,从正北开始顺时针方向测量。
完整的示例如下。这个例子使用 CSS3 直观地显示一个指南针。为了做到这一点,我们使用了指南针指针图像。该图像如图 2–52 所示。

图 2–52。PhoneGap 示例中使用的指南针图像
首先,我们用 navigator.compass.watchHeading()方法注册 onSuccess 方法。当我们的 onsuccess 方法被调用时,我们使用 css3 旋转变换来改变指南针图像指向的方向。这是一个视觉罗盘应用。
此处提到了该应用的完整 index.html:
`
<script type="text/javascript" src="phonegap-1.1.0.js">
Compass
| Compass Heading | .... | Degrees |
<img id="compass" src="compass.png"
style="width:400px;height:400px;margin-left:auto;margin-
right:auto;auto;display:block">
该代码如图 2–53 所示。

图 2–53。 PhoneGap 视觉罗盘应用
2–53 中的图可以从这个网址下载- [beginingphonegap.googlecode.com/files/compass.png](http://beginingphonegap.googlecode.com/files/compass.png)。
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Compass](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Compass)下载这个例子的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_compass_compass.md.html#Compass](http://docs.phonegap.com/en/1.1.0/phonegap_compass_compass.md.html#Compass.).的 Compass API 官方文档
从相机中捕捉图像
本章的最后一节是关于从相机中捕捉图像。这是一个很酷的特性,它确实为基于 HTML 的应用增加了很多价值。让我们看看如何使用这个特性。
调用的 API 如下:
navigator.camera.getPicture (onSuccessCallback, onErrorCallback,cameraOptions);
虽然在 cameraOptions 中有许多选项,但我们只关注一个名为 quality 的属性。cameraOption 看起来会像{"quality":75}。
使用上面的 camera 选项,onSuccess()方法将获得一个 base64 编码的二进制图像。
相机应用的完整示例如下:
`
<script type="text/javascript" src="phonegap-1.1.0.js">
Camera
该代码如图图 2–54 和图 2–55 所示。

图 2–54。 PhoneGap 相机应用显示按钮捕捉图像

图 2–55。 拍摄图像后应用 PhoneGap 相机
您可以从[bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Camera](https://bitbucket.org/rohitghatol/apress-phonegap/src/67848b004644/android/PhoneGap-Camera)下载这个例子的完整源代码。
可以参考[docs.phonegap.com/en/1.1.0/phonegap_camera_camera.md.html#Camera](http://docs.phonegap.com/en/1.1.0/phonegap_camera_camera.md.html#Camera)的相机 API 官方文档。
三、设置环境
PhoneGap 环境可以通过以下两种方式建立:
- 您机器上的本地开发环境
- PhoneGap Build 上的云构建环境
本地开发环境设置包括开发人员为其想要启动 PhoneGap 应用的每个移动平台设置环境。本章详细介绍了本地环境设置,希望读者不需要任何其他文档就可以在每个平台模拟器上运行 PhoneGap 应用。
为了在特定平台的设备上运行 PhoneGap 应用,用户需要查看特定平台的文档。本章提供了该文档的参考资料。
另一方面,称为“PhoneGap Build”的云构建环境允许您在不需要本地开发环境的情况下构建 PhoneGap 应用。这意味着开发人员将只编写应用的 PhoneGap 部分,这需要 HTML、JavaScript 和 CSS。这段代码将被提供给 PhoneGap 构建服务。PhoneGap 构建服务将为每个平台构建所需的二进制文件,开发者可以下载这些文件。我们将在本章中更详细地研究这一过程。
当地发展环境
本地开发环境很像我们在第二章中为 Android 所做的。在本章中,我们将了解如何在您的开发机器上为以下平台设置 PhoneGap 环境:
- ios
- 黑莓
- 智能移动终端操作系统
- 操作系统
需要注意的是,iOS 只能在使用 Xcode 的 Mac 上运行,而黑莓的首选操作系统是 Windows。
先决步骤
在我们继续之前,我们将预先完成所有平台的通用步骤。第一步是下载 PhoneGap。
下载语音间隙
可以从[www.phonegap.com](http://www.phonegap.com)下载 PhoneGap sdk。这本书采用了 PhoneGap 1 . 1 . 0 版本,这是当时的最新版本。
下载 PhoneGap sdk 并解压缩后,您会看到如图图 3–1 所示的文件夹结构。

图 3–1。 PhoneGap SDK 目录结构
PhoneGap 支持的每个平台都有一个单独的目录。每个目录包含每个平台的库、工具和源代码,以帮助设置本地开发环境。
使用 Xcode 4 为 iOS 设置环境
为了使用 iOS,你需要一台基于英特尔的电脑,安装 Mac OS X 雪豹(10.6)。
为了在设备上测试 PhoneGap 应用,您还需要以下内容:
- 像 iPhone、iPad 或 iPod Touch 这样的苹果设备
- iOS 开发者帐户和证书
接下来,您需要执行以下安装步骤:
-
安装 Xcode 和 PhoneGap。Xcode 安装程序可以从苹果开发者门户网站
[developer.apple.com/xcode/index.php](http://developer.apple.com/xcode/index.php)下载。请注意,你需要一个苹果开发者账户。或者,你可以从 iTunes 上购买并下载 Xcode 4,价格约为 5 美元。 -
导航到您提取 PhoneGap sdk 的 iOS 目录。运行 PhoneGap 安装程序,直到完成。
-
Create a new PhoneGap project. Open Xcode and create a new project. This will present the following dialog box. Select the “PhoneGap Based Application” option and select the Next button (see Figure 3-2).
![images]()
图 3-2。 创建新的 iOS PhoneGap 项目
-
On the next screen (shown in Figure 3–3), provide the product name and company identifier to the project creation wizard. Click next.
![images]()
图 3–3。 创建一个新的 iOS PhoneGap 项目
-
Select the appropriate directory for the project and click the Create button.
Xcode 提供了一个为项目创建 git 存储库的选项。点击图 3–4 中所示的源控制复选框,可启用或禁用该功能。

图 3–4。 创建一个新的 iOS PhoneGap 项目
现在你应该看到 Xcode 中的 HelloWorld 项目了。
-
Input PhoneGap's HTML and JavaScript
请注意,我们的项目中没有 www 文件夹。要创建一个 www 文件夹,点击 Xcode 左上角的运行按钮。它将构建项目并在模拟器中启动它。不要担心您的模拟器中显示“index.html 未找到”的错误。这是意料之中的,因为我们还没有把我们的 HTML 放到文件中。
-
Open the project in Finder (see Figure 3–5).
![images]()
图 3–5。 为 PhoneGap 定制 iOS 项目
您将在项目文件夹旁边看到一个 www 文件夹。我们需要将这个文件夹复制到 Xcode 项目中。
-
Drag and drop the www folder into Xcode. Xcode will now prompt with a few options. Select Create Folder References for any added folders and click the Finish button. Now you should see the project structure shown in Figure 3–6 in Xcode.
![images]()
图 3–6。iOS 项目中的 PhoneGap WWW 文件夹
-
Write PhoneGap Application
您可以通过修改 index.html 文件来编写 PhoneGap 应用。为了打开 index.html,打开 www 文件夹并在编辑器中打开 index.html 页面。在 index.html 文件中键入您的内容。您还可以在 index.html 页面上指定关联的 Javascript 和 CSS 文件。
-
部署到模拟器。确保在左上角的菜单中选择模拟器版本作为活动 SDK。
-
Click the Run button in the Xcode project header to build the project and launch the application in the Simulator (see Figure 3–7).
![images]()
图 3–7。 运行在 iOS 上的 PhoneGap 示例应用
-
Deploy to Device
您可以在开发人员设备上启动 PhoneGap 应用。为了在设备上运行应用,打开 HelloWorld-info.plist 并更改 BundleIdentifier 。如果你有开发者许可证,你可以从苹果获得 BundleIdentifier。
-
确保在左上角的菜单中选择 Device-version 作为 Active SDK,然后点按 Xcode 项目标题中的“运行”按钮。它将在设备中构建项目并启动应用。
为黑莓手机设置环境
您需要一台基于英特尔的计算机,运行 Windows XP (32 位)或 Windows 7 (32 位和 64 位)来运行 BlackBerry。您需要在您的电脑上安装以下软件:
- Java se 6 jdk 32 位
- 阿帕奇人 ant
- BlackBerry webworks sdk v2.0+版
- 任何 Java IDE 环境
- BlackBerry 开发者专区帐户
- 安装 j2sdk 6 (32 位)
你可以从[www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html](http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html)下载 J2SDK。运行 J2SDK 安装程序,直到完成。在 PATH 环境变量中添加 Installation _ directory/J2SDK/bin。
接下来,您需要执行以下安装步骤:
-
Install Apache ant
你可以从
[ant.apache.org/bindownload.cgi](http://ant.apache.org/bindownload.cgi)下载 Apache ant 包。Apache ant 包是一个 zip 文件。提取 ant zip 文件并将Extracted–directory/apache-ant-1.8.2/bin放在 PATH 环境变量中。 -
Install BlackBerry SDK
从
[bdsc.webapps.blackberry.com/html5/download/sdk](https://bdsc.webapps.blackberry.com/html5/download/sdk)网站下载用于智能手机的 BlackBerry Webworks SDK。运行 BlackBerry 安装程序,直到完成。通常,BlackBerry Webwork SDK 安装程序会将文件安装在 C:\BBWP 文件夹中。如果您将其更改为其他目录,请记住安装路径,因为您将需要在后面的步骤中使用它。我们建议使用路径“c:\BBWP”,因为我们在本章的其余部分将使用该路径。 -
Create New PhoneGap project
为了创建 BlackBerry PhoneGap 应用,PhoneGap 框架提供了一个 ant 脚本。
- 导航到 PhoneGap BlackBerry 目录
- 在命令提示符下运行“ant create–d project . path = C:\ Dev \ Sample”命令
请注意,如果您无法运行上述命令,请尝试从
[github.com/callback/callback-blackberry/downloads](https://github.com/callback/callback-blackberry/downloads)下载 PhoneGap 的 BlackBerry 回调,并将其解压缩到 PhoneGap 的 BlackBerry-WebWorks 目录中。![images]()
图 3–8。 创建黑莓 PhoneGap 项目
这将创建项目文件夹,如图 3–9 所示。请注意 www 文件夹。该文件夹包含 html 文件和 PhoneGap JavaScript 文件。
![images]()
图 3–9。 黑莓 PhoneGap 项目目录结构
您必须将 project.properties 文件中的 bbwp.dir 属性的值更改为
C:\\BBWP。如果您在安装期间更改了 BlackBerry 安装目录,如步骤 3 所述,请确保您为 bbwp.dir 属性键入了相同的目录(参见图 3–10)。![images]()
图 3–10。 配置 project.properties 指向 BlackBerry Works SDK 目录
-
Write a PhoneGap Application
编写 PhoneGap 应用就像修改 index.html 文件一样简单。要打开 index.html,请打开 www 文件夹,并在您喜欢的编辑器中打开 index.html 页面。在 index.html 文件中包含您的 CSS 和 JavaScript 文件。
-
Deploy to Simulator
在 BlackBerry 模拟器上部署需要以下步骤。
- 启动 BlackBerry 模拟器,运行 ant 目标,如下所示。这将启动黑莓模拟器
C:\Dev\Sample>ant load-simulator - 选择模拟器上的 BlackBerry 按钮
- 选择下载文件夹
在那里,您将看到 PhoneGap 示例应用。选择它将其打开(参见图 3-11 )。
![images]()
图 3–11。 从黑莓模拟器下载运行 PhoneGap 应用
- 启动 BlackBerry 模拟器,运行 ant 目标,如下所示。这将启动黑莓模拟器
-
Deploy to Device
为了在 BlackBerry 设备上部署 PhoneGap 应用,您需要来自 RIM 的签名密钥。您可以使用以下网站获取您的签名密钥
[www.blackberry.com/SignedKeys](https://www.blackberry.com/SignedKeys)。导航到项目目录,并在命令提示符下运行以下 ant 命令:
C:\Dev\Sample>ant load-device
为 Symbian 设置环境
为了使用 Symbian,您需要一台基于 Intel 的计算机,并安装 Windows 操作系统。虽然 PhoneGap 的官方文档声称 Symbian 应用可以在所有操作系统上开发,但我们还是建议在 Windows 上使用诺基亚 Symbian s60 sdk 在 Symbian 仿真器上测试 PhoneGap 应用。
接下来,您需要执行以下安装步骤:
-
Install Cygwin
为了设置 Symbian 的环境,我们需要在 Windows 上安装 Cygwin。从
[cygwin.com/install.html](http://cygwin.com/install.html)下载 Cygwin.exe 文件,开始安装直到完成。请注意,在安装 Cygwin 时,您必须选择两个包,即 zip 包和 make 包。 -
Install the Symbian s60 sdk
从
[www.forum.nokia.com/info/sw.nokia.com/id/ec866fab-4b76-49f6-b5a5-af0631419e9c/S60_All_in_One_SDKs.html](http://www.forum.nokia.com/info/sw.nokia.com/id/ec866fab-4b76-49f6-b5a5-af0631419e9c/S60_All_in_One_SDKs.html)下载 Symbian s60 sdk。请注意,这个 sdk 大约 800+ mb,安装需要大约 3+ gb 的空间。安装大约需要 30 多分钟。 -
Create a New PhoneGap project
PhoneGap 目录里面有一个名为 Symbian 的文件夹;该目录是一个模板项目。为了创建一个新的 Symbian PhoneGap 项目,只需复制这个目录并粘贴到您希望创建新的 Symbian PhoneGap 项目的位置。该目录的内容如图 3–12 所示。
![images]()
图 3-12。 创建新的 PhoneGap 项目
-
Write PhoneGap Application
打开 www 文件夹,在您喜欢的编辑器中打开 index.html。编辑 HTML 内容,并根据需要包含 CSS 和 JavaScript。
-
Deploy to Simulator
Symbian PhoneGap 使用 makefile 来构建项目。在 Mac 或 Linux 机器上,只需在终端中运行 make 就可以构建它们。在 Windows 中,您将需要 Cygwin 来构建。只需在 terminal/Cygwin 中运行“make ”, Symbian 项目就构建好了,“wgz”文件也创建好了。这些步骤如图 3–13 所示。
![images]()
图 3–13。打造 Symbian 项目
![images]()
图 3–14。 打造塞班项目
app.wgz 文件需要加载到 Symbian 模拟器中。使用仿真程序的文件选项导入。wgz 文件。这将提示您安装应用。选择“是”安装应用。
一旦应用安装完毕,我们需要点击 Symbian 模拟器中间底部的按钮来查看所有已经安装的应用。从这个屏幕启动我们的应用。一旦你启动了这个应用,你将会得到提示,关于运行这个应用所需要的权限。允许应用使用所需的功能。
-
Deploy to Device
您需要使用蓝牙或电子邮件将 Symbian PhoneGap 项目部署到设备上。使用蓝牙或电子邮件将 app.wgz 加载到设备中,然后启动应用。
为 webOS 设置环境
您可以在 Windows、Mac 和 Linux 上开发 webOS 应用。您需要在开发箱上安装以下软件:
- Java se 6 jdk 32 位
- 虚拟机版本 3.0 到 3.2
- webOS sdk 版本 3.0.4
接下来,您需要执行以下安装步骤:
-
Install java se 6 jdk 32-bit
你可以从
[www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html](http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html)下载 J2SDK。运行 J2SDK 安装程序,直到完成。在 PATH 环境变量中添加 Installation _ directory/J2SDK/bin。 -
Install Virtual Box
从
[www.virtualbox.org/wiki/Download_Old_Builds_4_0](http://www.virtualbox.org/wiki/Download_Old_Builds_4_0)下载虚拟盒子 3.0–3.2。开始安装,直到完成。 -
Install webOS SDK
从
[developer.palm.com/content/resources/develop/sdk_pdk_download.html](https://developer.palm.com/content/resources/develop/sdk_pdk_download.html)下载 webOS sdk。开始安装,直到完成。 -
Install Cygwin for Windows only
如果您使用的是 Windows,您必须安装 Cygwin 来构建和部署用于 webOS 的 PhoneGap 应用。请看 Symbian 安装的第一步。
-
Create new PhoneGap project
PhoneGap 目录包含一个名为 webOS 的目录。这是 PhoneGap webOS 的模板项目。为了创建 PhoneGap webOS 项目,请将此目录复制到您的项目区域。
-
Write PhoneGap application
打开 www 文件夹,在你最喜欢的编辑器中打开 index.html。编辑 HTML 内容,并根据您的需要包含 CSS 和 JavaScript。
-
Deploy to Simulator
在部署项目之前,请确保 webOS 模拟器正在运行。从应用文件夹/开始菜单运行 palm-emulator。
在项目文件夹中运行“make”。这将创建最终的 javaScript 文件。将项目打包到 webOS 移动应用包中,并将其安装在 webOS 模拟器中。
-
Deploy to Device
为了在 webOS 设备中部署 PhoneGap 项目,您必须启用“开发人员模式”并将其插入。在 Cygwin 终端的项目文件夹中运行“make”。
使用 PhoneGap Build 构建云环境
到目前为止,我们认为在不同的移动平台上构建 PhoneGap 应用很乏味。虽然 PhoneGap 开发减轻了跨平台移动应用开发的痛苦,但对于开发人员来说,在每个移动平台上构建 PhoneGap 仍然是乏味的。
为了缓解这种痛苦,PhoneGap 推出了 PhoneGap Build。PhoneGap Build 是一个云构建服务。开发人员将他们的 PhoneGap 应用代码提交给 PhoneGap Build,PhoneGap Build 根据以下内容开发应用:
- ios
- 机器人
- 黑莓
- 操作系统
- 智能移动终端操作系统
在本节中,我们将了解如何在 PhoneGap 上建立一个帐户,并在其上构建应用。
向 PhoneGap Build 注册
- 第一步是获得 PhoneGap beta 的帐户。转到
[build.phonegap.com](http://build.phonegap.com)并提供您的详细信息。 - 提交您的详细信息后,您将收到 PhoneGap 的电子邮件。在这封电子邮件中,PhoneGap 将提供测试代码。您需要在 PhoneGap 的注册页面提供测试代码。
虽然 PhoneGap Build 会为您构建应用,但您需要拥有这些应用。这是必要的,因为您将在 Appstore、Android Market 和 BlackBerry market 上发布从 PhoneGap Build 获得的版本。
让我们试着理解拥有你的应用意味着什么。一个应用需要被某些证书签名,在应用上印上你的所有权。对于 iOS 这样的平台,你需要获得一个开发者账号,并从苹果获得证书。
PhoneGap 需要您提供这些证书来构建以下应用:
- ios
- 机器人
- 黑莓
以下部分将演示如何生成这些证书并将其提供给 PhoneGap Build。
向 PhoneGap Build 注册您的应用
构建 PhoneGap 的第一步是向 PhoneGap Build 注册您的应用。有三种方法可以注册 PhoneGap Build。
- 在 PhoneGap 服务器上创建一个新的 git 存储库,并将代码推送到那里。
- 从现有的 git 存储库中提取代码。
- 上传你的 PhoneGap 应用的档案。
为了简单起见,我们将采用第二种选择,即从 PhoneGap git 存储库中提取 starter PhoneGap 项目(如图 3–15 所示)。
注意: PhoneGap Build 需要访问您的源代码,因为它是一个构建工具。这意味着你需要与 PhoneGap Build 共享你的源代码。这就像说我们想在他们的 git 存储库中构建 PhoneGap 提供的 PhoneGap 样本代码。这样,我们不需要提供任何源代码,我们将使用示例源代码进行练习。

图 3–15。 从 PhoneGap 存储库中取出 PhoneGap 启动代码
现在,您可以看到您的应用列在“您的应用”部分。注意,对于每个平台,都有一个下载图标(如图图 3–16 所示)。单击 download 按钮允许您下载特定于平台的二进制文件。所有这些二进制文件都构建在 PhoneGap Build server 上,因此不需要您为 iOS、Android、BlackBerry、Symbian 和 webOS 设置环境。

图 3–16。 PhoneGap Starter 项目构建下载屏幕
请注意图 3–16 中 iOS 版本的橙色警告。对于 iOS,构建需要由开发者证书和预置描述文件签名。预置描述文件链接到 Apple 开发者帐户。如果开发人员希望在 iOS 设备上测试应用,该设备需要使用此预置描述文件进行注册。
现在,在上面列出的 5 个平台中,我们需要为 3 个平台的 PhoneGap Build 提供某种开发者私钥。这是获得特定于平台的版本所必需的,这些版本可以是:
- 安装在设备上。
- 上传到各自的应用商店。
这些平台是:
- 机器人
- ios
- 黑莓
设置 Android 构建环境
Android 应用在发布到 Android 市场之前由自签名密钥库进行签名。Android 不需要一个中央机构来认证开发者的应用。但是,如果应用的版本 1 是用 xyz 开发人员密钥库签名的,那么应用的下一个版本必须用相同的开发人员密钥库签名。如果不这样做,将导致下一个版本的应用被 Android Market 拒绝。
以下是配置 PhoneGap Build 的步骤,以生成可以在 Android Market 上部署的正确的 Android build:
- 创建私有密钥库
- 将私有密钥库上传到 PhoneGap Build
- 运行 PhoneGap 构建
1。创建私有密钥库
首先要理解在[developer.android.com/guide/publishing/app-signing.html#cert](http://developer.android.com/guide/publishing/app-signing.html#cert)列出的 Android 应用发布指南。在本节中,我们将引导您完成创建私有密钥库所需的步骤。
创建私有密钥库的要求是您需要在您的机器上安装 java jdk 1.6 和更高版本。通过打开终端/命令提示符并键入以下命令来确认这一点:
$> keytool
如果这给了你某种帮助,那么你就可以走了。如果这告诉您没有名为 keytool 的工具,请确保您的 java bin 目录在 path 中。
现在,要实际创建您的私有密钥库,请遵循下面提供的步骤:
$> keytool -genkey -v -keystore my-release-key.keystore
系统将提示您输入密码。输入密码,并写下来。
$>Enter keystore password: welcome
您将被要求重新输入密码。
$>Re-enter new password: welcome
接下来,将会询问您一些问题,以便在私有密钥库中记录您的身份。请回答这些问题。
$ >您的名和姓是什么?
` [Unknown]: Rohit Ghatol
$>What is the name of your organizational unit?
[Unknown]: Engineering
\(>What is the name of your organization?
[Unknown]: QuickOffice
\)>What is the name of your City or Locality?
[Unknown]: Pune
\(>What is the name of your State or Province?
[Unknown]: Maharahstra
\)>What is the two-letter country code for this unit?
[Unknown]: IN`
现在将要求您确认到目前为止您输入的数据是否正确。
$>Is CN=Rohit Ghatol, OU=Engineering, O=QuickOffice, L=Pune, ST=Maharahstra, C=IN correct? [no]: yes
注意:工具将询问您创建自签名证书的密码。要保持这个密码与之前的密码相同,只需按 enter 键。
$>Generating 1,024 bit DSA key pair and self-signed certificate (SHA1withDSA) with a validity of 90 days for: CN=Rohit Ghatol, OU=Engineering, O=QuickOffice, L=Pune, ST=Maharahstra, C=IN $>Enter key password for <mykey> (RETURN if same as keystore password): [Storing my-release-key.keystore]
现在创建了名为“my-release-key.keystore”的私有密钥库文件,并保存在同一个目录中。
2。将私有密钥库上传到 PhoneGap Build
在 PhoneGap Build 上导航到您的应用,点击编辑按钮,您将看到如图图 3–17 所示的屏幕。

图 3–17。 PhoneGap 构建编辑应用屏幕
导航到签名部分,并在该屏幕上上传 Android 密钥库信息(如图 3–18 所示)

图 3–18。进入安卓发布密钥库详情
在此为您的密钥库提供一个标题。在 PhoneGap Build 上,您可以提供多个密钥库,并选择使用哪个来构建您应用。标题是在浏览 PhoneGap Build 上上传的各种密钥库时识别密钥库。
接下来上传密钥库文件并提供任何别名。在密码字段(两者)中,您需要输入用于创建密钥库和私有证书的密码(在我们的例子中是“welcome”)。
3。运行 PhoneGap 构建
最后,点击 create 和 PhoneGap Build 将代表您存储这个密钥库。
现在,您应该会看到一个类似于 Figure 3–19 的屏幕,告诉您“我的发布密钥”密钥库用于构建 Android 版本。

图 3–19。PhoneGap app 注册的安卓密钥库
设置 iOS 构建环境
在我们开始之前,让我们注意一下在 PhoneGap 上构建 iOS 的先决条件列表。
- 苹果开发者计划(
[developer.apple.com/programs/ios/ 0](http://developer.apple.com/programs/ios/0))或苹果企业开发者计划([developer.apple.com/programs/ios/enterprise/](http://developer.apple.com/programs/ios/enterprise/))的苹果开发者账户。选择最符合您要求的一个。 - 带有 Xcode 的 Mac 计算机,用于提取开发者证书和预置描述文件。提取这些信息后,开发人员可以在任何操作系统上使用 PhoneGap Build。
接下来的步骤如下:
- Get iOS key
- Provide iOS key to PhoneGap build
1。获取 iOS 密钥
关于如何使用 iOS 开发者帐户配置 Xcode 的完整信息在[tiny.cc/appleprov](http://tiny.cc/appleprov)中有详细描述。
遵循上述步骤,并确保您能够在模拟器上构建和安装示例 iPhone 应用,最好是在 iOS 设备上(已经添加到您的预置描述文件中)。
现在下一步是从 Xcode 中导出开发者证书和预置描述文件,并将它们放入 PhoneGap Build 中。
2。为 PhoneGap Build 提供 iOS 密钥
在正确设置了 iOS 开发环境之后,我们需要提取开发者证书和移动配置文件,并将它们上传到 PhoneGap Build。
第一步是从 Mac 的钥匙串访问中提取开发者证书。打开“钥匙串访问”,找到开发者证书并将其导出。导出时,会要求您输入文件夹和密码。记下该密码,因为当您在 PhoneGap Build 网站上上传开发者证书时将需要该密码。
之后,我们将继续提取配置文件。预置描述文件在 Xcode 内部。打开 Xcode,进入窗口->管理器,启动它。从这里,导出“团队配置文件”。请注意,预置描述文件是您告诉 Apple 您已将 iPhone/iPod/iPad 注册为开发人员设备来测试您的应用的地方。PhoneGap Build 需要此配置文件来签署您的应用(ipa)。
我们现在已经在名为 ios-Keys 的目录中提取了开发人员证书和移动配置文件。

图 3–20。 包含开发者证书和预置描述文件的目录
我们需要在 PhoneGap Build 上上传这些密钥。再次访问应用的编辑屏幕,导航到签名部分,对于 iOS,单击添加密钥(下面的选择密钥下拉列表)。

图 3–21。 iOS 添加键屏幕
这将打开 iOS 证书和预配描述文件对屏幕。上传所需的密钥和用于导出开发者证书的密码。

图 3–22。 为 PhoneGap Build 提供开发者证书和配置文件
一旦你启动 PhoneGap Build,你应该注意到 iOS ipa build 上的橙色警告消失了,Build 变成了绿色。点击 ipa 按钮将为您带来 iOS ipa。
设置 BlackBerry 构建环境
设置 BlackBerry 构建环境所需的主要操作如下:
- 去拿黑莓钥匙
- 向 PhoneGap Build 提供 BlackBerry 密钥
1。获取 BlackBerry 密钥
PhoneGap Build 为构建 BlackBerry 应用提供现成的支持,这些应用可以安装在您的设备上。然而,为了上传这些应用进行分发,您需要 rim 提供密钥。为了获得这些密钥,您需要使用此网站- [www.blackberry.com/SignedKeys/](https://www.blackberry.com/SignedKeys/)向 rim 注册。
注册后,你会收到 rim 发来的电子邮件,其中提到了在黑莓开发环境中安装这些密钥的步骤。由于法律禁止共享这些指令,我们无法详细说明这些指令。
2。向 PhoneGap Build 提供 BlackBerry 键
下一步是从 BlackBerry 开发环境中提取密钥。可以使用 eclipse 或独立的 BlackBerry web works 来设置 BlackBerry 开发环境。BlackBerry 密钥位于 BlackBerry 的 sdk 目录中。
第一个任务是定位 sdk 目录。
如果 BlackBerry 开发环境是使用 eclipse 安装的,您应该可以在<<eclipse location>>\plugins\ net.rim.ejde.componentpackX.X.X_X.X.X.X \components找到 BlackBerry sdk 目录。这方面的一个例子是 d:\ work soft \ eclipse-Helios \ net . rim . ejde . component pack 5 . 0 . 0 _ 5 . 0 . 0 . 25 \ components。
如果 BlackBerry 开发环境是使用 BlackBerry Widget/web works Packager Standalone SDK 安装的(就像我们在本章前面部分展示的那样),安装目录就是 SDK 目录。这在本章前面部分显示为“c:\BBWP”目录。
代码签名文件/密钥位于 sdk 目录中。
`<<webworks_sdk_dir>\bin\sigtool.csk
<<webworks_sdk_dir>\bin\sigtool.db`
现在,我们已经获得了访问 BlackBerry 密钥的权限,请进入 PhoneGap Build 上的应用,单击编辑,然后转到签名部分。从下拉菜单中,为 BlackBerry 选择“添加密钥”选项。

图 3–23。 iOS 添加键屏幕
在如下所示的对话框中上传 BlackBerry 密钥。使用您按照说明创建的相同密码,该密码是从 BlackBerry 的电子邮件中获得的。这为 PhoneGap Build 提供了构建 BlackBerry 应用所需的所有信息,这些应用可以在 BlackBerry 分发渠道上分发。

图 3–24。 黑莓钥匙文件上传
启动 PhoneGap 构建
PhoneGap 构建可以通过两种方式启动:
- 手动点击 PhoneGap Build 上的“重建全部”,如下图所示。这将在 PhoneGap 构建服务器上对构建进行排队。
- 第二种方法是使用 PhoneGap Build restful api 来创建应用、更新代码和启动构建。您可以使 PhoneGap 构建成为您的 cit 构建的一部分(从 bamboo 或 jerkins 或任何 cit 系统)。让 cit 构建脚本调用 PhoneGap Build restful api。PhoneGap 构建 api 的细节可以在
[build.phonegap.com/docs/api](https://build.phonegap.com/docs/api)找到。
结论
随着云在托管 web 服务和应用方面越来越受欢迎,许多公司都在寻求基于云的 saas 服务来帮助他们的开发周期。
像 pivotal tracker 这样的公司用于敏捷规划,bitcode 用于托管源代码,甚至还有在线 cit 构建(例如 jira studio)。PhoneGap Build 的出现并不令人惊讶。
不仅仅为了 cit 而购买额外的 Windows 和 Mac 电脑,从而节省基础设施成本是有意义的。保持低成本和租用基础设施(就像我们支付电费一样)正成为当今的趋势。
PhoneGap Build 适合中小型公司的需求,这些公司希望摆脱基础设施负担,使用基于云的 saas 服务来构建 PhoneGap 应用。
四、通过 jQuery Mobile 使用 PhoneGap
虽然 PhoneGap 提供了一个允许 JavaScript 应用访问原生手机功能的平台,但还有许多其他因素有助于移动 HTML 应用。
移动 HTML 应用最重要的部分之一是 UI。您可以使用 HTML、JavaScript 和 CSS 手工编写整个 UI。然而,任何 web 开发人员都会告诉您,这种方法存在许多问题,包括以下问题:
- 不是所有的浏览器都一样;你需要一个跨浏览器的框架才能成功。即使大多数移动浏览器都是基于 webkit 的,最好还是使用一个框架,从开发者那里抽象出浏览器的差异。
- 如果您是手工编码,您的大部分代码将是绘制 UI、修改 DOM 和进行 Ajax 调用。一个让你少写多做的框架将会帮助你真正关注业务逻辑。
- 创建美观的 HTML 用户界面需要设计师的技能。同时,大多数移动客户端都有预定义的主题或模式。如果一个框架能提供开箱即用的好看的 UI,这将对开发者有所帮助。这样,开发人员可以专注于业务逻辑。
话虽如此,使用 PhoneGap 编写 UI 的最简单的框架之一是 jQueryMobile。首先,jQueryMobile 是建立在非常流行的 jQuery 之上的。众所周知,jQuery 是一个 JavaScript 库,可以提高开发人员的工作效率,并帮助开发人员实现跨浏览器兼容性。同时,jQuery 提供了许多免费的插件来做很多事情。
jQueryMobile 是一个为移动 UI 构建的 UI 框架。它有一个声明式 UI,这意味着你不必用 JavaScript 编写你的 UI,而是可以用 HTML 声明它。jQueryMobile 还提供了一个开箱即用的非常漂亮的 UI。
所有这些使得 jQueryMobile 成为最容易使用的 JavaScript UI 框架,也是最适合中等复杂程度的移动 UI 的框架。
话虽如此,jQueryMobile 为智能手机和平板电脑提供了相同的 UI。如果你的需求不一样,需要智能手机和平板电脑不同的布局,那就看第五章。
熟悉 jQuery
jQuery 是最好的 JavaScript 库之一,它可以帮助您执行 Ajax 调用、在 HTML DOM 中搜索特定元素以及修改 DOM。它也有自己的插件框架。最棒的是它的跨浏览器框架,消除了浏览器差异的困扰。可以参考下面的 jQuery 教程:[www.w3schools.com/jquery/default.asp](http://www.w3schools.com/jquery/default.asp)。
jQuery 初始化
jQuery 初始化是一个两步过程。
- 在 HTML 页面中包含 jQuery JavaScript。
- 声明一个回调,当 jQuery 的库被加载时,jQuery 将调用这个回调。
这是必要的,因为 HTML 页面可能包含许多文件,如 CSS、JavaScript 和图像。浏览器将下载所有这些资源,并开始执行所有的 JavaScript 块。如果在正确初始化之前开始使用 jQuery API 调用,将会出现错误。因此,您声明一个回调,这是我们的应用的入口点,jQuery 将调用这个回调并引导应用。
通常,当开发人员不使用 jQuery 时,他会按照以下方式编写代码:
`window.onload = function(){
alert("Page Loaded");
}
When using jQuery the same code would look like follows:
//Step 1 – include jquery library
jQuery Demo
`
当您在任何浏览器中运行这段代码时,您会看到在页面加载时弹出一个警告。警告会说“jQuery loaded”
jQuery 选择器
既然您已经了解了如何初始化 jQuery 和注册 onload()方法,那么让我们继续了解如何查找 HTML DOM 元素。
通常,开发人员会使用以下代码来获得 id 为“占位符”的 div
document.getElementById("placeholder").innerhtml = "hello world";
在 jQuery 中,您可以将上面的函数写成
$("#placeholder").html("hello world");
jQuery 提供了许多定位 HTML 元素的方法。一个例子是$("#placeholder "),它返回一个 jQuery 元素,包装 id 为" placeholder "的元素。一旦获得了这个 jQuery 包装器,就可以调用 jQuery 函数来操作 DOM。在上面的例子中,您将它的 HTML 内容更改为“hello world”
让我们参考一个代码示例来回顾一些其他有用的选择器示例:
`
JQUERY SELECTOR Tutorial
simple paragraph
Paragraph with class title
another paragraph
Element based - $("p")
Id based - $("#selector")
CSS Class based - $(".title")
Element + Class based - $("p.title");
Element+ID+Position - $("ui#selectorli:first)
`
基于元素的选择器
$("p")选择所有段落:
`
simple paragraph
Paragraph with class title
another paragraph
`基于 ID 的选择器
$("#selector")选择 id 为“选择器”的元素请记住,要搜索的 id 前面会添加#号。为此选择器选择了以下元素:
<ul id="selector">
基于 CSS 的选择器
$(".title")选择具有类“title”的元素记住,一个“.”在类名之前调用以搜索该类的元素。为此选择器选择了以下元素:
`
JQUERY SELECTOR Tutorial
Paragraph with class title
`选择器的组合
以下是一些如何混合和匹配选择器来定位特定元素的示例:
$("p.title")选择类别为“title”的段落元素,这将选择以下元素:
<p class="title">Paragraph with class title</p>
$("ul#selector li:first")用 id“选择器”从 UI 中选择第一个 li 元素这将选择以下元素:
<li>Element based - $("p")</li>
jQuery 选择器的完整列表可以在下面的链接中找到:[www.w3schools.com/jquery/jquery_ref_selectors.asp](http://www.w3schools.com/jquery/jquery_ref_selectors.asp)。
jQuery DOM 操控
首先,让我们看看如何从 HTML 中检索值。您可以检索元素或内部 HTML 的值。
如果您执行 javascript $(ul#selector).html(),,您将得到以下文本:
`
以下示例显示了如何从 jQuery 选择器结果中提取值。首先,这个例子展示了当您假设 jQuery 选择器只返回一个值时会发生什么。也就是说,假设$("p")只返回了一段。然后,您将尝试使用 html()函数获取段落的值。注意$("p")返回一个 jQuery 选择器,html()函数属于 jQuery 选择器。在这种情况下,jQuery 将对\(("p ")选择器找到的第一个元素运行 html()方法。这意味着当你说`\)("p").HTML(), $("p")`时,将定位如下的第一段,并给出值“简单段落”
<p>simple paragraph</p>
现在你知道$("p")应该给你很多值,因为在前一个例子中有很多段落,如下所示:
`
simple paragraph
Paragraph with class title
another paragraph
`为了迭代任何列表,jQuery 提供了一个方法:“each()”为了使用“each()”,您需要在 jQuery 选择器上调用它,就像我们的例子$(“p”)一样。“each()”方法有两个参数:第一个是索引(迭代中的位置),第二个是该位置的实际条目。
因此,当你说$(“p”)的时候。each(function(index,element){}),元素是每个段落上实际的 jQuery 选择器。
``
现在,让我们继续修改 HTML DOM。我们将很快介绍操作 DOM 的最简单的方法。
当您执行下面的 JavaScript 时,它会将段落的内容修改为“更改为 123”
<script type="text/javascript"> $(document).ready(function() { $("p.title").html("Changed to 123"); }); </script>
jQuery HTML 操作的完整列表可以在[www.w3schools.com/jquery/jquery_ref_html.asp](http://www.w3schools.com/jquery/jquery_ref_html.asp)找到。
jQuery Ajax 调用
jQuery 为 Ajax 调用提供了许多有用的方法。
下面是一个对 URL 进行 Ajax GET 调用的例子。这是“少写多做”的经典例子。以下代码执行 Ajax GET 调用 service/employee/details.txt,并将内容放入 id 为“details”的 div 中:
$.get("service/employee/details.txt", function (result) { $("div#details").html(result); });
以下是对 URL 进行 Ajax POST 调用的示例,发布数据{name:employeeName}:
$.post("service/employee/details", { name: employeeName }, function (result) { alert("Post successful"); });
jQuery HTML 操作的完整列表可以在 [www.w3schools.com/jquery/jquery_ref_ajax.asp](http://www.w3schools.com/jquery/jquery_ref_ajax.asp)找到。
熟悉 jQueryMobile
jQueryMobile 通过提供一个通用的 UI 平台来开发跨许多流行的移动平台的移动应用,将 jQuery“少写多做”的概念推向了一个新的高度。
jQueryMobile 建立在非常流行和健壮的 jQuery 和 jQuery UI 框架之上。jQueryMobile 提供了现成的、可触摸的移动小部件,比如列表视图、带有后退按钮的标题、导航动画等等。这些小部件具有专业而精致的外观和感觉,使得开发现成的应用变得更加容易。
jQueryMobile 的主页是[jquerymobile.com/](http://jquerymobile.com/)。
而且,jQueryMobile 提供了五种开箱即用的主题供你选择。下面的示例展示了按钮在不同主题中的外观。总的来说,我们有五个主题——主题 a、主题 b、主题 c、主题 d 和主题 d——如图图 4–1 所示。

图 4–1。 jQueryMobile 主题
此外,jQueryMobile 还为表 4–1 中列出的平台提供坡度支持。

在移动应用中包含 jQueryMobile
从[jquerymobile.com/download/](http://jquerymobile.com/download/)下载 jquery.mobile-1.0rc2.zip 并解压。解压缩后,您会看到如图图 4–2 所示的文件夹结构。它包含两对 jQueryMobile JavaScript 和一个 CSS 文件。顾名思义,您可以使用。最小化生产中的 JavaScript 和 CSS 文件,因为它们是缩小的 JavaScript 和 CSS 文件。
除此之外,你还需要在手机应用中包含图片文件夹。

图 4–2。 jQueryMobile 文件夹结构
以下是 jQueryMobile 示例的 HTML 模板:
`
…
jQueryMobile 声明式用户界面
声明式 UI 构建是 jQueryMobile 最好的部分。您不需要编写复杂的 JavaScript 代码来构建 UI。UI 构建就像添加带有一些 jQueryMobile 特定属性及其值的普通 HTML 元素一样。
页面和对话框
您在上一节中看到了 HTML 模板。现在,您将向其中添加 jQueryMobile 布局和小部件。
您可以在 body 标记内的 div 元素中使用数据角色属性来声明页面。因此,在 body 标记中,您可以通过声明以下内容来声明许多页面:
<div data-role="page"></div>
同样,您可以通过将数据角色声明为“页眉”、“内容”和“页脚”来声明页面的组件以下是 jQueryMobile 中的一个页面示例:
`
此处显示了一个完整的页面示例。
`
<html> <head> <title>jQuery Mobile Demo</title> <link href="jquery.mobile-1.0rc2.min.css" rel="stylesheet" type="text/css"/> <script src="jquery-1.6.4.min.js"></script> <script src="jquery.mobile-1.0rc2.min.js"></script> </head>
Page Title
Page content goes here.
Page Footer
`
在浏览器中运行该 html 时,会显示一个如图 4–3 所示的屏幕。

图 4–3。 jQueryMobile pages
现在,您已经了解了 jQueryMobile 中页面的概念,让我们来看一个拥有多个页面或对话框的场景。
典型的应用有多个页面和对话框。jQueryMobile 最棒的一点是,您可以在同一个 HTML 页面中定义所有这些不同的页面和对话框。
下面是怎么做的。在一个 HTML 页面中定义多个 div,并赋予它们以下内容:
- 一个名为 data-role 的属性设置为 page。这看起来像这样:data-role="page "
- 一个名为“id”的属性,用于在代码中标识它们
您可以使用链接和按钮导航到这些页面和对话框。最简单的方法是执行以下操作:
- 将 href 定义为#+ <
> - 给该链接一个 data-role="button "
注意,页面和对话框的声明是相同的。事实上,没有什么叫做对话框,但是你可以在弹出窗口中加载一个页面作为对话框。
下面是一个页面链接的示例。当单击此链接时,会转换到 id 为“page2”的页面。还要注意,因为链接被赋予了 data-role="button ",所以它看起来像一个按钮。
<a data-role="button" href="#page2">Page Navigation</a>
将页面作为对话框打开与导航到页面非常相似。您只需要向链接添加两个属性:
- data-rel="dialog "
- data-transition="pop "(这是动画效果)
<a data-role="button" href="#dialog1" data-rel="dialog" data-transition="pop">Open Dialog </a>
这里有一个完整的例子供你尝试。图 4–4 显示的是“主”页面,图 4–5 显示的是“第二页”页面,图 4–6 显示的是“对话 1”页面,相当于一个对话框:
`
Second Page
Second Page
Click back to go back to main page
Dialog Title
v
Dialog body
Click close button to go back to main page
` 
图 4–4。jquerymobile page navigation

图 4–5。jquerymobile page navigation

图 4–6。 jQueryMobile 对话框
工具栏和按钮
在 jQueryMobile 中,有两种类型的工具栏:
- 标题栏
- 页脚栏
一般来说,创建工具栏就像在标题栏或页脚栏中声明一些按钮一样简单。这在图 4–7 中进行了描述。
`
` 
图 4–7。 jQueryMobile 工具栏和按钮
表格元素
jQueryMobile 中的表单元素是典型的 HTML 表单元素——它们只是看起来不同。这意味着您可以使用您的 HTML JavaScript 技能来呈现好看、精美的 jQueryMobile 小部件,并使用传统的事件处理技术来快速编写您的移动 web 应用。
让我们看几个表单元素的例子。在第一个例子中,我们使用了一个输入文本、一个文本区域和一个搜索框。对于所有这些,都分配了一个标签。它们被包装在一个字段集中,形成一组标签和相关的小部件。请参见 Figure 4–8 以了解表单元素在 jQueryMobile 中的外观。
`
` 
图 4–8。 jQueryMobile 表单元素
在第二个例子中,HTML select 被包装在一个好看的开/关开关中。请注意,当您以编程方式从中获取值时,您将把它用作 HTML 选择框。您还用滑块包装了一个文本框。滑块的值放在文本框中。这相当于用户在文本框中填写一个数字,但是使用 jQueryMobile,用户可以使用滑块在给定的范围内选择一个值。参见 Figure 4–9 来看看这个 HTML 是如何呈现的。
`



button on the toolbar to open the Android SDK and the AVD Manager. Choose the Virtual Devices option as depicted in Figure 2–8. 






seen in Figure 2–30. 















浙公网安备 33010602011771号