今天的30天挑戰,我決定學習手機開發。長期以來,我對手機開發心存疑慮,認爲大部分的應用沒有手機市場,實際上,我一直對手機開發提不起興趣。而後,在移動方面的大力發展,事實上愈來愈多的人選擇用手機上網,我決定試試手機開發。我將用PhoneGap開啓個人移動開發之旅。 javascript
在這篇博客裏,咱們先看看PhoneGap的基礎,而後用它開發一個手機應用。 css
咱們今天要開發的手機應用是一個對30天學習30種技術挑戰的閱讀器。用戶能夠在任何Android, Symbian, webOS, 或者 Windows Phone上安裝,能夠從https://build.phonegap.com/apps/635001/share下載。 html
這個應用能夠作如下: java
PhoneGap是一個免費開源的移動開發框架,採用如HTML, CSS和JavaScript的標準Web技術。 node
它封裝了Web應用資源,而不單單是本地App,而且能夠上傳到各類App 商店。更重要的是,能夠用它跨平臺開發,意味着,理論上你只要對這個應用寫一次,就能夠發到不一樣的平臺上。好比,這個程序我是爲Android寫的,可是用PhoneGap build, 也能夠生成其餘平臺的包。大部分的標準功能,如相機,定位,存儲等等能夠用JavaScript API寫,PhoneGap提供的JavaScript API是基於目標平臺的。 jquery
一些關於PhoneGap的事蹟:android
我考慮PhoneGap的緣由: git
PhoneGap須要NOdeJS,咱們用npm安裝。NPM是NodeJS的包管理器,新版本的NodeJS自帶,能夠從官網下載最新版本。 github
同時你也須要安裝目標平臺的SDK, 例如,你想建立Android程序,就須要安裝Android開發工具。PhoneGap用他們的SDK去建目標平臺的包。 web
使用如下方式安裝PhoneGap.
$ sudo npm install -g phonegap
這個命令會全局安裝PhoneGap包,容許Phonegap命令在任何路徑可用。
要安裝插件,就要安裝Cordova 命令器。
輸入如下命令安裝Cordova.
$ sudo npm install -g cordova
今天的demo在 github: 30technologies30days-mobile-app.
phonegap提供了用命令新建模板phonegap項目,輸入如下命令。
$ phonegap create reader --id io.reader --name Reader30
這個命令會建立一個reader路徑。
第一個參數指定了閱讀器生成的路徑,另外兩個參數可選,io.reader提供項目的反轉域標識,Reader30提供程序顯示的文字。
這個phonegap閱讀器程序的文件夾結構如圖。
來看看各生成的文件夾.
在Android上運行程序,輸入如下命令。
$ phonegap run android
它會先爲Android建立閱讀器程序,若是有設備鏈接好就會在上面跑這個示例程序。若是沒有鏈接的,Android模擬器會啓動並在上面運行程序。
注意:Android模擬器的性能不好,因此建議你鏈接真實移動設備。加速Android模擬器的建議參考Grant Shipley的博客。
咱們的程序如上所示有兩個頁面,一個一個來寫。
主頁列出這段時間發表的全部博客,先更新index.html,從個人git上覆制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>
以上代碼會導入全部須要的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作了如下動做:
PhoneGap默認是不容許程序訪問遠程資源,這就意味着程序不能使用REST 調用,爲了讓程序能使用REST調用,就得使PhoneGap容許訪問,能夠用一個 * 通配符使程序可訪問全部資源,參照文檔。
在config.xml裏更新訪問配置。
<access origin="*" />
這個程序用了幾個插件來訪問設備的特定功能。
$ cordova plugin add org.apache.cordova.geolocation
$ cordova plugin add org.apache.cordova.dialogs
第二個頁面容許用戶對這個系列提交反饋。
添加feedback表來記錄。
<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文件更新了監聽feedback類裏全部元素的tap事件,feedbakck類在頂部添加了feedback連接。
$(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); } }); }
提交feedback表後咱們能夠從表裏獲得數據,若是用戶勾選了sharemylocation,咱們就用geolocation API獲取用戶位置。最後,咱們給REST web服務器提交POST, 對一個成功的反饋提交,能夠給用戶提示。
如今能夠輸入如下命令安裝和運行程序。
$ phonegap run android
這是今天的內容,繼續給反饋吧。
原文:https://www.openshift.com/blogs/day-10-phonegap-mobile-development-for-the-dummies