0. PhoneGap介紹
0.1 什么是PhoneGap?
PhoneGap是一個基於HTML、CSS、JS創建跨平台移動應程序的快速開發平台。與傳統Web應用不同的是,它使開發者能夠利用iPhone、Android等職能手機的核心本地功能,比如GPS、傳感器、震動。
0. PhoneGap介紹
0.1 什么是PhoneGap?
PhoneGap是一個基於HTML、CSS、JS創建跨平台移動應程序的快速開發平台。與傳統Web應用不同的是,它使開發者能夠利用iPhone、Android等職能手機的核心本地功能,比如GPS、傳感器、震動。
0.2 PhoneGap 歷史
0.2.1 產生:08年、hackathon
在蘋果08年舉行的iOSDevCamp(黑客馬拉松)中,一名iOS程序員無法忍受OC的語法,覺着簡單的HTML和JavaScript如果能部署在移動端並能實現同iphone實現簡單的交互(比如調用攝像頭、重力感應)該多好,於是phonegap便產生了!
0.2.2 流行:流行、獲獎、支持7個平台
09年,PhoneGap 0.6版本發布,這是第一個穩定版,不僅支持iOS,還支持Android、BlackBerry平台,這使得PhoneGap在移動開發領域越來越重要。
到10年7月,又實現了對WindowsMoible、Palm、Symbian的支持,支持平台達到6個。
11年7月,發布1.0版本,其中加入了很多訪問本地設備的API;
11年11月,發布1.2版本,正事支持Windows Phone7,支持平台數字達到7個!
0.2.3 收購
11年10月,Adobe宣布收購PhoneGap;
收購之后PhoneGap團隊將核心代碼貢獻給Adobe,但保留PhoneGap商標所有權,其實是做為Adobe的商業項目存在的(收購是為了掙錢!);

Adobe將PhoneGap貢獻的代碼作為一個新的項目,名為Cordova
0.2.4 現在版本
截止到16年7月份,PhoneGap已經更新到了6.2.0版本,已經支持windows mobile10
0.3 Phonegap與Cordova的區別、聯系
0.3.1 區別
Cordova是PhoneGap貢獻給Apache的項目,是一個開源的、核心的跨平台模塊。
PhoneGap是Adobe的商業產品;
0.3.2 關系
Cordova與PhoneGap的關系就像是WebKit與Chrome的關系。
0.4 為什么出現PhoneGap這種技術?
有了PhoneGap,Web開發人員便可以利用他們非常熟悉的JavaScript、HTML和CSS技術,或者結合移動Web UI框架jQuery Mobile、Sencha Touch來開發跨平台移動客戶端,還能非常方便地發布程序到不同移動平台上。
0.5 核心特點
0.5.1 兼容性
完全做到了written once,run everywhere;代碼編寫完之后,通過phonegap的build工具構建
0.5.2 標准化
采用w3c標准,包括但不限於HTML5、CSS3、JavaScript,比如說W3C標准中的命名方式等
0.5.3 大眾化
不需要手機編程基礎,只要會HTML就能做應用,且能通過js調用設備底層硬件(比如攝像頭、傳感器。。。)
0.6 如何學習?
網站推薦:
http://phonegap.com/ https://cordova.apache.org/
http://www.phonegap100.com/
htt://cordova.apache.org
http://phonegap-plugins.com/
1、搭建環境
1.1 模式1:通過命令行安裝、編譯運行
1.1.1 安裝
官網建議安裝方式:npm install -g cordova
問題:速度很慢,基本下載不下來,怎么辦?
http://npm.taobao.org/ 這是淘寶做的npm鏡像,和npm官網資源保持一致(每隔10分鍾更新一次)
解決方案: npm install -g cordova --registry http://registry.npm.taobao.org info
如何檢驗是否安裝成功?
windows+R->Cmd->cordova
cmd命令:
①刪除非空文件夾 rmdir 某個目錄 /s

②進入某個文件夾
cd 文件夾
③顯示文件夾下的內容
dir 文件夾名稱
④清除屏幕內容
cls
1.1.2 cordova 常用命令
cordova項目平台部署操作
增加或者刪除ios平台
cordova platform add ios
cordova platform remove ios
增加或刪除android平台
cordova platform add android
cordova platform remove android
查看當前項目所支持的平台
cordova platfrom ls
檢查cordova項目build時是否具備條件(比如android,必須配置好了sdk)
cordova requirements
將cordova項目通過命令行的方式生產指定平台下的應用
cordova run android(檢查是否有真機,沒有真機的話,去模擬器執行,沒有模擬器就報錯)
cordova emulate android(在模擬器中執行)
檢查cordova項目可運行的設備列表
cordova run --list
1.1.3 生成Android應用
必備條件:
①安裝JDK(必須是JDK7或者更高的版本),並且配置環境變量JAVA_HOME(為JDK安裝的路徑)
②安裝AndroidSDK,並且配置環境變量ANDROID_HOME(Android SDK安裝的路徑)
1.1.4 構建iOS應用
①必須在OS X操作系統的Mac上才能編譯
②安裝ios的SDK
③。。。
1.2 方式2 :借助圖形化工具
cordova的商業項目phonegap,為了方便開發者使用,在命令行操作的基礎上,推出了圖形化工具,該工具分兩部分:
1.2.1桌面端
可以安裝在windows、Mac操作系統中
下載地址:https://github.com/phonegap/phonegap-app-desktop/releases
移動端:可以安裝在iOS、Android、WindowsPhone手機或者平板中
桌面版可以創建或者刪除一個cordova項目,並且對項目做簡單配置,然后提供一個服務;
1.2.2移動端
主要是用來直接在指定的設備上預覽app效果,而跳過編譯代碼、購買設備、注冊賬號(蘋果開發者需要支付最低688元/年的費用)等繁瑣的步驟,那么移動端是如何知道你在電腦中的代碼並展示呢?這是在移動端應用打開時,需要指定服務器的地址和端口號,只要連上服務器就會自動從服務器讀取內容並展示!
2、第一個cordova程序
2.1 選擇開發模式
我們如何來創建自己的第一個Cordova程序呢?
命令行模式雖然在企業中使用較多,但對於我們新手過於極客,我們從圖形化工具作為切入點開始學習,圖形化開發的模式分兩塊,桌面端和移動端,在我給大家提供的資料中提供了一個windows安裝版本(PhoneGapSetup-win32.exe),接下來,我們找到該文件並雙擊安裝。
接下來安裝移動端應用,在實際開發的時候,有兩種選擇:
一是通過模擬器,啟動Android模擬器,通過adb將apk安裝到模擬器中。
二是通過真機進行測試,將手機通過帶有存儲標識的數據線插入電腦,將apk直接拷貝到手機內存中,然后在手機中查找apk文件並點擊安裝,安裝之后,如果想能夠連接服務器端,需要保證在同一局域網內
那么我們應該選擇哪種呢?顯然,方式2的話,每個人需要一個手機且和自己的電腦在同一網絡在公司中更合適,但是目前,方式1,也就是模擬器的方式更適合我們,所以接下來大家打開我們的eclipse,並啟動模擬器。
2.2 開始
2.2.1 啟動桌面版
默認界面是這樣的:

步驟1:創建用來存儲項目的文件夾
首先在c盤根目錄創建一個文件夾:phonegapDemo, 進入phonegaoDemo目錄中
步驟2:創建cordova項目
點擊+號,在彈窗中可以創建或者打開一個cordova項目,我們在這里點擊create來創建一個新的cordova項目!


步驟3:判斷是否創建成功
檢查服務器是否跑起來

2.2.2 啟動移動端
啟動eclipse,啟動虛擬設備管理器

接下來,需要將apk安裝到虛擬機中,
有兩個問題:從哪里下載apk?如何將apk安裝到虛擬機中?
如何下載
下載方式1:
通過官方提供的方式,直接去應用市場去下載:
iOS版本需要去AppleStore中下載
Android版本需要翻牆去GooglePlay去下載
WindowsPhone版本需要去Windows Phone Stroe下載
下載方式2:
https://github.com/phonegap/phonegap-app-developer/tree/master/resources/release

比如說我要下載Android版本,怎么下載?
點擊上圖中的android文件夾,然后找到最新的版本:

點擊下載即可。
如何安裝
通過adb來安裝,那么什么是ADB?
ADB全稱為Android Debug Bridge,是一個命令行工具,可以和模擬器或者Android真機進行通訊,可以通過adb命令來講apk應用安裝到模擬器或者真機上。
adb常用命令:
adb version 查看adb的版本
adb install **.apk 安裝某個應用
adb devices 獲取連接到本電腦的設備列表
adb-s "emulator-5554" install **.apk 為指定的某個設備安裝某個應用
adb shell ** 后邊可以接一些命令,比如查看目錄,或者查看某個文件內容
adb shell ls //查看當前目錄有哪些內容
adb shell cat init.rc | more //查看某個文件,並將文件內容多次查看
adb shell pwd //打印當前的路徑
adb start-server
adb kill-server
那么我們要安裝肯定要用adb install就行了,如圖操作:

安裝成功之后,在模擬器找到PhoneGap點擊啟動,啟動之后修改ip地址和端口號,連接成功之后會顯示一個機器人圖標!



2.3 顯示helloWorld
打開webStorm,將之前創建的demo01文件夾導入到項目中,如下圖所示:

2.3.1 修改文件
同時修改www目錄下的index.html文件,將h1內容PhoneGap修改為HelloWorld,即完成第一個cordova的helloworld項目!
2.3.2 目錄介紹
index.html
工程根目錄下的www目錄的index.html文件,我們一起來分析一下:
<script type="text/javascript" src="cordova.js"></script>
cordova.js文件時phonegap的庫文件,可以用來在JS中調用原生設備硬件(攝像頭、聯系人、GPS等),從而實現webapp無法實現的一些功能,更好的模擬原生應用。
但是我們會發現,在我們工程中是無法找到該文件的,是因為該文件已經集成apk文件,也就是Developer app或命令行的配置的工程中了
<meta name="format-detection" content="telephone=no" />
這個meta標簽時在iOS系統中用來識別電話號碼並自動產生連接可以直接撥號,但是很多時候像地址、ISBN或者其他數據,容易搞錯,所以在這里設置為no
<meta name="msapplication-tap-highlight" content="no" />
這個是用在windowsPhone8或者以上版本用來禁止某種高亮效果等
app.initialize()
<script type="text/javascript">
app.initialize();
</script>
哪來的app對象?帶着大家看index.js文件,在該文件中注意點如下:
事件:deviceReady,意味着Cordova設備api已經加載完畢可以調用了
index.js文件都做了那些事?
當接收到deviceReady事件之后,以冒泡的方式(第三個參數為false),執行onDeviceReady方法,在回調函數中又指定了receivedEvent方法,在這里,查找元素設置樣式,就這么多!
config.xml
該文件是一個全局配置文件,控制着cordova應用各個方面,根元素為一個widget,屬性可以設置版本號、id編號等信息。
name為app正式名字,會在設備主屏幕上和應用市場里顯示的
description為在應用市場中顯示的app描述信息
author為作者信息
content會指定app啟動時會執行的文件,默認值為項目目錄下的www文件夾中的index.html文件
plugin會指定在項目中需要准備什么插件,會默認添加到工程中
preference可以指定一些鍵值對,比如config.xml中的:

3、cordova基礎知識
在剛才的案例中,有一個注意點是deviceReady事件,這個事件是cordova本身的事件,那么cordova除此之外都有哪些事件?cordova又是如何和硬件進行溝通從而實現讀寫操作的?接下來,首先我們就從如何操作硬件來學習
3.1 如何讀取硬件信息
步驟1:首先,打開網頁phonegap-plugins.com
步驟2:我們以device這個插件為例,在上述網頁中找到device這個插件 -->
https://github.com/apache/cordova-plugin-device
步驟3:找到www目錄下的device.js文件
可以看到這是個function,function有一些屬性,比如platform、model,那么這些值是什么時候完成賦值的呢?在cordova進行初始化的時候,也就是在ondeviceready事件觸發之前,在device.js中,會執行exec的方法,
步驟4:資料中的cordova.js
如果是在android平台運行的話,會自動觸發android平台下的cordova.js文件中的androidExec方法,在這里會通過nativeApiProvider這個對象調用get方法,然后執行exec方法,得到返回的json對象,那么這個json對象哪來的?
步驟4:找到android目錄下的device.java文件
在該文件中,會通過execute方法,獲取到一個json對象,這個對象包含了本設備的一些基本信息,比如操作系統名稱、型號信息
3.2 都有哪些事件
| 名稱 |
說明 |
| deviceready |
當設備加載完畢后會觸發該事件 |
| pause |
當程序被暫停到后台運行時 |
| resume |
當程序從后台激活到前台 |
| online |
網絡斷開切換到網絡連接 |
| offline |
網絡連接切換到網絡斷開 |
| batterycritical |
電量低於10%時會觸發 |
| batterylow |
電量低於某個指定值觸發 |
| batterystatus |
剩余電量發生變化會觸發 |
| backbutton |
按下返回按鈕 |
| menubutton |
按下菜單按鈕 |
| startcallbutton |
通話按鈕 |
| endcallbutton |
掛斷通話按鈕 |
| volumedownbutton |
按下音量減按鈕 |
| volumeupbutton |
按下音量加按鈕 |
| searchbutton |
按下搜索按鈕 |
3.3 監聽音量的增減操作
練習1:修改index.js文件,對音量的增減進行監聽。
步驟1:在index.html文件中,在剛才修改為helloworld的h1標簽下邊,加一個p標簽,id設置為p_id

步驟2:在index.js文件中,找到bindEvents方法,在方法中添加音量加減的監聽
bindEvents: function() { document.addEventListener('deviceready', this.onDeviceReady, false); var p = document.getElementById('p_id'); document.addEventListener('volumedownbutton', function () { p.innerHTML="volume down"; }); document.addEventListener('volumeupbutton', function () { p.innerHTML="volume up"; }) },
步驟3:在保證phonegap desktop(桌面版)和移動端phonegap developer(移動端)已經連接的情況下,去查看結果
4、和硬件溝通
除了能夠將HTML頁面打包成可以直接安裝運行的app外,phoneGap的最大優勢在於通過js調用設備來訪問設備上的硬件信息,從而實現一些原本只有依靠原生SDK才能達到的目的,接下來,我們利用cordova給我們提供的api來獲取設備信息
4.1 獲取設備信息
要想獲取設備信息,必須在deviceready之后,否則是獲取不到數據的。
練習2:獲取設備信息(操作系統、版本)
步驟1: 在index.html文件中,添加一個p標簽,設置id為device-info

步驟2:在index.js文件中,找到deviceready之后的回調函數,調用device,將設備信息展示在標簽中
var deviceInfo = document.getElementById('device_info'); deviceInfo.innerHTML="設備名稱:"+device.name +"<br/>操作系統為:"+device.platform +"<br/> 操作系統版本為:"+device.version;
步驟3:檢查結果


通過上述案例,我們可以看到device這個api可以獲取設備信息,那么cordova都有哪些核心api?
cordova給我們提供了十幾個核心api如下所示:
| 核心api |
描述 |
| accelerometer |
加速度傳感器 |
| camera |
攝像頭 |
| capture |
采集 |
| compass |
羅盤 |
| contacts |
聯系人 |
| device |
設備 |
| events |
事件 |
| file |
文件 |
| geolocation |
地理位置 |
| media |
媒體 |
| notification |
通知(提醒) |
| storage |
存儲 |
4.2 消息提示
phonegap的notification類中封裝了一系列設備視覺、聽覺、觸覺的通知,可以為應用定制專門的消息推送、警告或者提示。
notification.alert() 彈出一個警告或者對話框
notification.confirm() 顯示一個可定制的確認對話框
notification.prompt() 彈出一個對話框
notification.beep() 控制蜂鳴器發出蜂鳴聲
notification.vibrate() 產生震動
練習3:調用phonegap的notification api讓手機發出聲音、震動
步驟1:修改index.html,添加兩個h1標簽
<h1 onclick="playBeep()">蜂鳴器發聲</h1>
<h1 onclick="vibrate()">使設備震動</h1>
步驟2:添加點擊時的回調函數
<script type="text/javascript"> app.initialize(); function playBeep() { navigator.notification.beep(3); }; function vibrate() { navigator.notification.vibrate(300); } </script>
步驟3:給學生解釋下,模擬器是無法觀察到震動和發生操作的,怎么辦?
演示下,如何通過雲打包的方式來生成apk。
登錄build.phonegap.com,需要登錄(用戶名kunyashaw@gmail.com),然后打包上傳,等待打包完成即可。(注意按照這種方式,目前還有問題,會提示cordova class not founf) 。
練習4:各種對話框
演示一個alert的用法,其余的自己去嘗試
步驟1:修改index.html

步驟2:在js中添加個function
function showAlert(){ navigator.notification.alert( "content",//內容 function () {//按鈕點擊的回調函數 playBeep(); alert("hello world"); } ); }
4.3 加速度傳感器
加速度傳感器是一種用來檢測物體相對運動方向以及沿着xyz三個方向運動的部件,phonegap提供了accelerometer類用來接收來自加速度傳感器的數據,從而檢測到設備在控件上的位置變化,比如說現在很流行的手環,或者說實現類似微信搖一搖功能的,傳感器加上一些算法,那么我們如何使用phonegap是來得到傳感器數據呢?
首先我們先開看第一個,如果獲取加速度信息:
function getDeviceAcceletate(){ navigator.accelerometer.getCurrentAcceleration(function (acceleration) { alert("x is "+acceleration.x+"\n y is "+acceleration.y+"\n z is "+acceleration.z); }, function () { alert('獲取加速度信息失敗') }) }
那么通過上述方式,如果要檢測運動數據的話,是不是得一直調用該方法啊,其實phonegap還給我們提供了一個方法:watchAcceleration(),我們一起來看下用法
function startWatch(){ var info = document.getElementById("accel_info"); id = navigator.accelerometer.watchAcceleration( function (accel) { info.innerHTML= "x is "+accel.x+"\nyis "+accel.y+"\nz is "+accel.z+"\n"; }, function () { alert('error'); }, {frequency:300}); } function stopWatch() { if (id) { navigator.accelerometer.clearWatch(id); } id=null; }
4.4 音視頻的錄制
可以實現音視頻的播放、錄制
接下來,我們來看下phonegap是如何實現音頻的錄制的.
navigator.device.capture.captureAudio(captureSuccess, captureError, options);
// 限制采集上限為3個媒體文件,每個文件不超過10秒
var options = { limit: 3, duration: 10 };
function record(){ // 采集操作成功完成后的回調函數 var captureSuccess = function(mediaFiles) { var i, path, len; for (i = 0, len = mediaFiles.length; i < len; i += 1) { path = mediaFiles[i].fullPath; // 對文件進行感興趣的操作 alert(path); } }; // 采集操作出錯后的回調函數 var captureError = function(error) { navigator.notification.alert('Error code: ' + error.code, null, 'Capture Error'); }; // 開始采集音頻 navigator.device.capture.captureAudio(captureSuccess, captureError, {limit:2}); }
在phonegap中,如果想進行拍照、錄制視頻的話,只需要將captureAudio,修改為captrueImage、captureVideo就行了。
4.5 文件操作
phoneGap通常是將一類操作完全封裝在同一個對象中,比如設備信息都在device類中,但是phoneGap對文件的操作方法卻封裝在了許多不同的對象中,所以這是phoneGap最為復雜的一類對象。接下來,我們一起來學習下phoneGap的文件操作的基礎知識。
如何操作一個文件?phoneGap提供了兩個類分別是fileReader類和fileWriter類,在這兩個類中,調用不同的方法去操作文件,插件名稱是file,該插件是基於h5的file api,所以如果大家接觸過h5的文件api的話,其實phonegap這里基本是一致的。
插件地址:https://github.com/apache/cordova-plugin-file/
4.5.1 fileReader
首先先來看第一個類fileReader,是一個允許用戶讀取文件的對象,文件以文本或者Base64編碼的字符串樣式讀出來,用戶注冊自己的事件監聽器來接受loadstart、loadend等事件
屬性:
readyState:當前讀取器所處的狀態,取值為以下三者之一:EMPTY、LOADING和DONE。
result:已讀取文件的內容。(DOMString類型)
error:包含錯誤信息的對象。(FileError類型)
onloadstart:讀取啟動時調用的回調函數。(函數類型)
onprogress:讀取過程中調用的回調函數,用於匯報讀取進度(progress.loaded和progress.total)。(函數類型) 不支持
onload:讀取安全完成后調用的回調函數。(函數類型)
onabort:讀取被中止后調用的回調函數,例如通過調用abort()方法。(函數類型)
onerror:讀取失敗后調用的回調函數。(函數類型)
onloadend:請求完成后調用的回調函數(無論請求是成功還是失敗)。(函數類型)
方法:
abort:中止讀取文件。
readAsDataURL:讀取文件,結果以Base64編碼的data URL形式返回。(data URL的格式由IETF在RFC2397中定義)
readAsText:讀取文件,結果以文本字符串返回。
使用案例
修改index.html
<!-- 讀取文件操作--> <br/> <button onclick="readFile()">讀取文件</button> <h1 id="file_read_id">example</h1>
在index.html中添加js代碼
function readFile(){ window.requestFileSystem(LocalFileSystem.PERSISTENT,0,gotFSRead,fail);//只有執行了該函數,才能操作系統中的文件 } function gotFSRead(fileSystem) { fileSystem.root.getFile("readme.txt",null,getFileEntryRead,fail);//得到一個fileEntry對象,代表文件系統中的一個文件 } function getFileEntryRead(fileEntry) { fileEntry.file(function (file) { var reader = new FileReader();//獲取對文件進行讀操作的對象 reader.onloadend = function (evt) { alert(evt.target.result); document.getElementById('file_read_id').innerHTML = evt.target.result; }; reader.readAsText(file); },fail) } function fail(evt) { alert(evt.target.error.code); }
4.5.2 fileWriter
<!-- 寫入文件操作--> <br/> <button onclick="writeFile()">寫入文件</button> <input id="file_write_id"/> function writeFile(){ window.requestFileSystem(LocalFileSystem.PERSISTENT,0,gotFSRead,fail);//只有執行了該函數,才能操作系統中的文件 } function gotFSWrite(fileSystem) { alert('call getFile Write'); fileSystem.root.getFile("readme2.txt",{create:true},getFileEntryWrite,fail);//得到一個fileEntry對象,代表文件系統中的一個文件 } function getFileEntryWrite(fileEntry){ fileEntry.createWriter(function (writer) { //writer 獲取對文件進行寫操作的對象 writer.onwrite = function (evt) { alert("success"); }; writer.write(document.getElementById('file_write_id').value); },fail); }
5、每日一練
根據今天學習的加速度傳感器的知識,實現搖一搖,改變頁面背景色為一個隨機顏色。
如何實現:
1、要實現對加速度傳感器的監聽
2、判斷傳感器上下左右任意一個值的變化,如果前后兩次變化的值超過了25,就改變背景色
3、多久判斷一次呢,可以創建個定時器相隔1s判斷一次
function startWatch(){ var info = document.getElementById("accel_info"); id = navigator.accelerometer.watchAcceleration(function (accel) { info.innerHTML= "x is "+accel.x+"\nyis "+accel.y+"\nz is "+accel.z+"\n"; x1=accel.x; y1=accel.y; z1=accel.z; }, function () { alert('error'); },{frequency:300}); } function stopWatch() { if (id) { navigator.accelerometer.clearWatch(id); } id=null; } var x1= 0,x2= 0,y1= 0,y2= 0,z1= 0,z2=0; setInterval(function () { var change = Math.abs(x1-x2+y1-y2+z1-z2); if(change>25) { document.getElementById("btn_id").style.backgroundColor = getRandomColor(); } x2=x1; y2=y1; z2=z1; },100); function getRandomColor(){ var r = Math.floor(Math.random()*256); var g = Math.floor(Math.random()*256); var b = Math.floor(Math.random()*256); var hexR = r.toString(16); var hexG = g.toString(16); var hexB = b.toString(16); return "#"+hexR+hexG+hexB; }


