- Day 1: Bower - 管理你的客户端依赖关系
- Day 2: AngularJS - 对 AngularJS 的初步认识
- Day 3: Flask - 使用 Python 和 OpenShift 进行即时 Web 开发
- Day 4:PredictionIO - 如何创建一个博客推荐器
- Day 5: GruntJS - 重复乏味的工作总会有人做(反正我不做)
- Day 6:在 Java 虚拟机上使用 Grails 进行快速 Web 开发
- Day 7: GruntJS 在线重载 提升生产率至新境界
- Day 8: Harp.JS - 现代静态 web 服务器
- Day 9: TextBlob - 对文本进行情感分析
- Day 10: PhoneGap - 开发手机应用如此简单
- Day 11: AeroGear 推送服务器:使应用的通知推送变得简单
- Day 12: OpenCV - Java 开发者的人脸检测
- Day 13: Dropwizard - 非常棒的 Java REST 服务器栈
- Day14:使用斯坦福 NER 软件包实现你自己的命名实体识别器(Named Entity Recognition,NER)
- Day 15:Meteor - 从零开始创建一个 Web 应用
- Day 16: Goose Extractor - 好用的文章提取工具
- Day 17: 使用 JBoss Forge 和 OpenShift 构建部署 JAVA EE 6 应用
- Day 18: BoilerPipe - Java 开发者的文章提取工具
- Day 19: EmberJS 入门指南
- Day 20: 斯坦福 CoreNLP - 用 Java 给 Twitter 进行情感分析
- Day 21:Docker 入门教程
- Day 22: 使用 Spring、MongoDB 和 AngularJS 开发单页面应用
- Day 23:使用 TimelineJS 构建精美的时间轴
- Day 24: 使用 Yeoman 自动构建 Ember 项目
- Day 25: 联合 Tornado、MongoDB 和 AngularJS 进行应用开发
- Day 26: TogetherJS - 让我们一起来编程!
- Day 27: Restify - 在 Node.js 中构建正确的 REST Web 服务
- Day 28: OpenShift 的 Eclipse 集成
- Day 29:编写你的第一个 Google Chrome 扩展程序
- Day 30: Play Framework - Java 开发者的梦想框架
Day 10: PhoneGap - 开发手机应用如此简单
今天又是 “30 天学习 30 种新技术” 的一天。长期以来,我觉得手机开发很恐怖,大部分应用都没有商业模式。事实上,编写手机应用从来都不能让我兴奋。然而,考虑到手机领域的飞速发展,以及更多的人通过手机而不是桌面访问互联网,我决定尝试下手机开发。我的手机开发之旅将从 PhoneGap 起步。
本文首先介绍 PhoneGap 的基本情况,接着我们使用 PhoneGap 开发一个手机应用。
手机应用
我们将为是 “30 天学习 30 种新技术” 开发一个手机阅读器。用户可以将该应用安装在 Android、Symbian、webOS 或 Windows 设备上。该手机应用可以在 https://build.phonegap.com/apps/635001/share 下载。
这个应用可以做到:
给出所有已经发布的系列文章的列表。用户点击列表中的条目则调用浏览器打开链接。
读者可以使用该应用回馈想法。
什么是 PhoneGap?
PhoneGap 是一个自由开源的手机开发框架,可以使用标准的 web 技术,即 HTML,CSS 和 JavaScript 进行手机应用开发。
它将应用的 web 资源封装在原生应用中,这些应用可以提交到各大应用商店。更重要的是,我们可以通过 PhoneGap 进行跨平台的手机应用开发。这意味着,在理想情况下,我们只需编写一次手机应用,就可以将该应用移植到多个平台。例如,我为 Android 设备编写了这个应用,然而使用 PhoneGap build ,我同时为其他设备打包了应用。大多数标准的设备特性,例如照相、地理位置、存储等都由 JavaScript API 提供了。取决与目标设备,PhoneGap 提供的 JavaScript API 会有所不同。
关于 PhoneGap 的一些事实:
- 2009 年,Nitobi 开发了 PhoneGap 框架。
- 2011 年 10 月,Adobe 购买了 Nitobi(PhoneGap)背后的公司。
- Adobe 将 PhoneGap 贡献给 Apache 基金会。
- 此开源项目被命名为 Apache Cordova.
- PhoneGap 是 Adobe 完成的 开源项目 Apache Cordova 的实现。 PhoneGap 的核心使用 Apache Cordova.
- PhoneGap 使用基于插件的架构。所有设备的特性以插件方式提供。本文中,我们将使用一些插件。
为什么我关心 PhoneGap?
- 没有必要为每个平台学习一种原生的开发环境。如果开发者打算针对多个平台,那么 PhoneGap 的跨平台特性可以节约开发者大量的时间和精力。我了解 HTML、CSS 和 JavaScript,可以很平滑地进入手机世界。
- 对于开发基于 REST API 的 CRUD 手机应用,PhoneGap 很好用。
- 它不强迫开发者选择特定的 CSS 库。开发者可以使用任何他们喜欢的移动端的库。本应用中我使用 jQuery mobile。
PhoneGap Prerequisites
PhoneGap 依赖 NodeJS,我们需要使用 npm 来安装 PhoneGap。Npm 是 NodeJS 的包管理器,新版的 NodeJS 自带 npm。你可以从 官网 下载最新版的 NodeJS。
你需要同时安装目标机器的 SDK。例如,如果我们创建 Android 程序,我们需要在操作系统上安装 Android 开发者工具。PhoneGap 使用 SDK 为目标平台构建包。
PhoneGap 起步
使用如下命令安装 PhoneGap:
sudo npm install -g phonegap
以上命令将全局安装 phonegap 包,这样任何目录下都可以使用 phonegap。
安装插件需要安装 Cordova.
使用如下命令安装 Cordova。
sudo npm install -g cordova
GitHub 仓库
今天的 demo 应用的代码在 github 上。
创建 PhoneGap 应用
phonegap
命令行提供了使用模板创建新 phonegap 项目的命令:
phonegap create reader --id io.reader --name Reader30
上面的命令会创建一个 reader
目录。
io.reader
和 Reader30
是可选的: io.reader
提供了一个类似反域名的识别符,而 Reader30
提供了应用的显示文本。
应用的文件结构如下:
让我们看下这些生成的目录:
merges
文件夹存放专门针对某个特定平台的资源。例如,我们可能使用merges
来为 Android 设备改变字体大小。platforms
目录存放平台构建文件。plugins
存放应用使用的插件。当我们安装一个插件的时候,插件会被存放在这个目录下。www
目录存放应用资源,例如html
、css
、js
和img
。这是我们要花最多时间的目录。config.xml
包含了生成和分发应用所需的元信息。元信息也包括应用名称、描述、作者详情、应用权限等信息。在 这里 可以看到一个完整的列表。
运行下列命令即可在 android 上运行应用:
phonegap run android
这是我们的 android 平台阅读器应用的第一次构建。如果有真实设备连接,应用会跑在真实设备上。如果没有设备,会启动 Android 虚拟器,应用会被部署到虚拟器上。
注意:Android 虚拟器的性能相当差劲,所以我建议你总是连接上你的真实手机设备。Grant Shipley 的 博客 提供了一些加速 Android 虚拟器的信息。
开发手机应用
如上所述,我们的应用有两个页面。我们先开发第一个。
博客列表
初始页面列出所有已发布文章的列表。我们修改下 index.html
,请从我的 github 仓库 中复制 css 和 javascript 资源。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>Learn 30 technologies in 30 days</title>
<link rel="stylesheet" href="css/vendor/jquery.mobile-1.3.1.min.css">
<link rel="stylesheet" href="css/vendor/jquery.loadmask.css">
</head>
<body>
<div data-role="page" id="mainPage">
<div data-role="header" data-position="fixed">
<h1>30Technologies30Days</h1>
<a href="#feeback" data-icon="edit" data-theme="b" class="feedback ui-btn-right" data-role="button" data-inline="true" data-ajax="false">Feedback</a>
<div data-role="navbar">
<ul>
<li><a href="#home" class="home ui-btn-active" data-icon="home">Home</a></li>
</ul>
</div>
</div>
<div id="main" data-role="content">
</div>
<div data-theme="a" data-role="footer">
<h3>
© Shekhar Gulati 2013
</h3>
</div>
</div>
<script type="text/x-mustache-template" id="home-template">
<ul id="blogs" data-role="listview" data-filter="true" data-filter-placeholder="Search blogs..." data-inset="true">
</ul>
</script>
<script type="text/x-mustache-template" id="blog-template">
<li>
<a href="{{url}}" target="_blank">
<h3>{{title}}</h3>
<p><strong>{{publishedOn}}</strong></p>
</li>
</script>
<script src="phonegap.js"></script>
<script src="js/vendor/jquery-1.9.1.min.js"></script>
<script src="js/vendor/jquery.mobile-1.3.1.min.js"></script>
<script src="js/vendor/jquery.ui.map.js"></script>
<script src="js/vendor/jquery.loadmask.min.js"></script>
<script src="js/vendor/jquery.timeago.js"></script>
<script type="text/javascript" src="js/vendor/mustache.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
上面的 html 导入了所需的 css 和 javascript 文件。它使用 jQuery mobile 达到原生效果。我们同时定义了一个 mustache 模板来呈现列表。
应用相关的 javascript 代码放在 app.js
文件中:
$(document).ready(function(){
homeView();
$('.home').on('tap', renderHomeView);
$('.feedback').on('tap', renderFeedbackFormView);
});
function renderHomeView(event){
event.preventDefault();
homeView();
}
function homeView(){
$('#main').empty();
$('.home').addClass("ui-btn-active");
$('#main').html(template("home"));
var url = 'http://30technologiesin30days-t20.rhcloud.com/api/v1/blogs';
$.mobile.loading( 'show',{});
$.ajax({
url : url,
dataType : 'json',
success : function(data){
$.mobile.loading( 'hide',{});
$.each(data , function(i , obj){
var template = $("#blog-template").html();
obj.publishedOn = $.timeago(obj.publishedOn);
$("#blogs").append(Mustache.to_html(template,obj));
$('#blogs').listview('refresh');
});
},
error : function(XMLHttpRequest,textStatus, errorThrown) {
$.mobile.loading( 'hide',{text:"Fetching blogs.."});
alert("Something wrong happended on the server. Try again..");
}
})
$('#main').trigger('create');
}
function template(name) {
return Mustache.compile($('#'+name+'-template').html());
}
function showNotification(message , title){
if (navigator.notification) {
navigator.notification.alert(message, null, title, 'OK');
} else {
alert(title ? (title + ": " + message) : message);
}
}
上面的 app.js
做了这些事:
- 绑定了文档的就绪事件。一旦就绪,将渲染初始页面。
- 初始页面进行 REST 调用以获取所有博客。我们使用 jQuery 来调用 REST。
- 接受信息后,我们创建一个列表。最后刷新下。
允许访问 REST 服务
PhoneGap 默认不允许应用访问远程资源。这就意味着应用无法进行 REST 调用。为了允许应用进行 REST 调用,我们需要允许它访问。我们可以通过通配符 *
允许应用访问一切资源。请参阅 文档 了解更多信息。
在 config.xml
下修改访问控制信息:
<access origin="*" />
安装插件
应用使用一些插件来访问特定设备的特性。
cordova plugin add org.apache.cordova.geolocation
cordova plugin add org.apache.cordova.dialogs
- 第一个命令安装了
geolocation
插件。Geolocation 提供了设备位置的信息,例如经度和纬度。我们稍后将使用此特性。参阅 文档 了解更多信息。 - 第二个命令安装了
dialogs
插件。dialogs 插件提供了原生的设备视觉提醒。参阅 文档 了解更多信息。
反馈提交表单
第二个屏幕允许用户提交反馈。
我们增加了一个反馈表单,来记录用户的反馈。
<script type="text/x-mustache-template" id="feedback-form-template">
<form action="" id="feedbackForm">
<div data-role="fieldcontain">
<label for="name">
Describe
</label>
<input type="text" name="name" id="name" placeholder="Full Name eg. Shekhar Gulati ">
</div>
<div data-role="fieldcontain">
<label for="description">
Describe
</label>
<textarea name="description" id="description" placeholder="Message for author.."></textarea>
</div>
<div id="checkboxes1" data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="vertical">
<legend>
Share my location
</legend>
<input id="sharemylocation" name="sharemylocation" type="checkbox" value="true">
<label for="sharemylocation">
Share
</label>
</fieldset>
</div>
<button id="create-button" data-inline="true">Feedback</button>
</form>
</script>
修改 app.js
文件,监听 tap 事件。
$(document).ready(function(){
homeView();
$('.home').on('tap', renderHomeView);
$('.feedback').on('tap', renderFeedbackFormView);
});
function renderFeedbackFormView(event){
event.preventDefault();
$('#main').empty();
$('#main').html(template("feedback-form"));
$('#main').trigger('create');
$('#create-button').bind('tap',shareFeedback);
}
function shareFeedback(event){
event.preventDefault();
$('#feedbackForm').mask();
var name = $('#name').val();
var description = $('textarea#description').val();
var sharemylocation = $("#sharemylocation:checked").val() === undefined ? "false" : "true";
var data = {name:name , description:description , lngLat :[]};
if(sharemylocation === "true"){
navigator.geolocation.getCurrentPosition(function(position){
var lngLat = [position.coords.longitude , position.coords.latitude];
data.lngLat = lngLat;
postFeedback(data);
} , function(error){
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
$('#feedbackForm').unmask();
});
}else{
postFeedback(data);
}
}
function postFeedback(data){
$.ajax({
type : 'POST',
url : 'http://30technologiesin30days-t20.rhcloud.com/api/v1/feedback',
crossDomain : true,
data : JSON.stringify(data),
dataType : 'json',
contentType: "application/json",
success : function(data){
$('#feedbackForm').unmask();
$('#feedbackForm')[0].reset();
showNotification('Received your feedback', 'Info');
homeView();
},
error : function(XMLHttpRequest,textStatus, errorThrown) {
$('#feedbackForm').unmask();
alert("Error status :"+textStatus);
alert("Error type :"+errorThrown);
}
});
}
当反馈表单提交后,我们从表单获取了数据。如果用户勾选了“分享我的位置”,我们会使用 geolocation 插件来获取用户的位置。最后,我们将 POST 请求提交到我们的 REST 服务。一旦成功提交,我们显示一个提醒。
运行应用
现在我们可以在设备上安装和运行应用了。使用如下命令:
phonegap run android
今天就到这里了。多多回馈。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论