google的開源移動操作系統Android給智能手機市場帶來了風暴。不像Apple,對想要為水果市場(Iphone App Store)提供應用軟件的開發者們有着嚴格的指導原則以及要求,Google將Android平台 完全開放。現在你甚至能夠用PHP來實現Android應用程序。Irontech的人們已經創建了一個在Android上運行的PHP接口(見PFA ),而通過 Scripting Layer for Android (SL4A),你可以建立PHP的Android應用程序。
在這篇文章里,我會介紹如何安裝,設置及使用PHP for Android and SL4A,我將給出一個演示程序作為例子,並以使用PHP for Android開發的經驗給出第一手的報告。
安裝PHP for Android
為了安裝PHP for Android,你得擁有一部運行着版本1.5或以上版本Android的電話或模擬器,並且你必須激活應用設置下的“未知來源”(Unknown Source)。如果你已經滿足了上述條件,你只需要簡單地安裝 SL4A環境 和PHP for Android APK .
安裝SL4A不復雜,不過在你安裝完PHP for Android后,你需要再次點擊“安裝”以獲得完整功能。如果你在安裝時碰到困難,在Vimeo上有一個功略:handy video demonstration 。
設置PHP for Android開發環境
如果你已經安裝好PHP for Android,理論上,你可以在你的手機上寫PHP應用了。但從實際效果上來說,並不能做地很好。你要做的是 下載Android SDK ,配置一個模擬器,然后在你喜歡的編輯器敲打代碼。
你下載完SDK后,解壓到你選定的目錄,運行位於tools 目錄下的Android程序,並配置一個模擬器。在Android SDK and AVD Manager 菜單下, 選擇 Virtual Devices 並點擊按鈕 New 。命名你的新模擬器(如 “Droid2″)並選擇Android 2.2作為目標。設定SD卡大小為 10 MiB ,點擊 Create AVD 。
現在你已經配置好Droid模擬器,點擊Start 按鈕。這里有一些棘手,因為你無法直接將文件復制到你剛剛配置的虛擬機中。你必須配置端口轉發並將你的PHP腳本通過一個叫做adb 的程序(Android SDK的一部分)推送到虛擬機中,這個程序也在目錄tools下。
下一步,你可以在虛擬機中開啟一個服務。你可以鏈接到服務器上來發送你的腳本。下面的步驟將幫助你盡快地啟動和運行(你可以從這里 讀到關於這個步驟的完整文檔).
- 保持你的新虛擬機運行,進入Applications 界面並點擊SL4A。
- 在SL4A界面中,點擊Menu 按鈕,點中View 並選中Interpreters 。
- 再次點擊Menu ,選擇Start Server 並選中Private 。
- 將Android notification欄往下拖動你會看到SL4A服務(點擊服務並確認你的服務正在監聽的端口,如47000)。
- 打開一個shell或命令行,通過adb 工具來設置轉發端口。例如,輸入指令
adb forward tcp:9999 tcp:47000
,將47000
替換成你的端口數。 - 設置名為
AP_PORT
的環境變量。在UNIX 或 Mac,執行export AP_PORT=9999
。在Windows,輸入set AP_PORT=9999
。 - 要在你的模擬器中測試你的代碼,只需要運行
adb push my_script.php /sdcard/sl4a/scripts
,用你自己寫的代碼替換my_script.php
。
你也可以在一個真實手機中配置並運行。只需要把你在你的模擬器中做的在手機上重復一次。為了更簡單些,你可以設置一個環境變量ANDROID_HOME
指向你的Android SDK路徑並添加子目錄tools 到你的路徑中。
用PHP建立一個Android應用程序
當你配置完你的開發環境后,你會發現寫一個在Android上跑的PHP應用是相當簡單的事情。你會發現PHP for Android中的PHP版本是一個精簡版。你擁有基本的PHP核心函數和JSON支持–僅此而已。如果你是一個熟悉JAVA框架的Android開發 者,你還會發現SL4A並不提供和所有你在使用java創建成熟Anrdoid應用時已經習慣了的所有組件的接口。
SL4A所提供的是Android API子集的“殼”。(SL4A支持的完整方法列表在這里 查看。) 但PHP for Android有趣的地方在於你可以只用幾行代碼快速搭建一個應用的原型並讓它跑起來。我用不到60行的代碼寫了一個演示代碼:查詢股票報價 。
- <span style="color: #000000; font-weight: bold;"><?php</span>
- <br>
- <span style="color: #990000;">define</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">'QUOTE_SERVER'</span>
- <span style="color: #339933;">,</span>
- <span style="color: #0000ff;">'http://quoter.take88.com/?ticker=%s'</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #b1b100;">require_once</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">"Android.php"</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">=</span>
- <span style="color: #000000; font-weight: bold;">new</span>
- Android<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$action</span>
- <span style="color: #339933;">=</span>
- <span style="color: #0000ff;">'get_tickers'</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$tickers</span>
- <span style="color: #339933;">=</span>
- <span style="color: #0000ff;">''</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #b1b100;">while</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900; font-weight: bold;">TRUE</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">{</span>
- <br>
- <span style="color: #b1b100;">switch</span>
- <span style="color: #009900;">(</span>
- <span style="color: #000088;">$action</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">{</span>
- <br>
- <span style="color: #b1b100;">case</span>
- <span style="color: #0000ff;">'quote'</span>
- <span style="color: #339933;">:</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">dialogCreateSpinnerProgress</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">"Querying stock information server ..."</span>
- <span style="color: #339933;">,</span>
- <span style="color: #0000ff;">"Please wait"</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">dialogShow</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$quotes</span>
- <span style="color: #339933;">=</span>
- <span style="color: #339933;">@</span>
- <span style="color: #990000;">array_slice</span>
- <span style="color: #009900;">(</span>
- <span style="color: #990000;">json_decode</span>
- <span style="color: #009900;">(</span>
- <span style="color: #990000;">file_get_contents</span>
- <span style="color: #009900;">(</span>
- <span style="color: #990000;">sprintf</span>
- <span style="color: #009900;">(</span>
- QUOTE_SERVER<span style="color: #339933;">,</span>
- <span style="color: #000088;">$tickers</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">,</span>
- <span style="color: #cc66cc;">0</span>
- <span style="color: #339933;">,</span>
- <span style="color: #cc66cc;">3</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">vibrate</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">dialogDismiss</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #666666; font-style: italic;">// Possible data points.</span>
- <br>
- <span style="color: #666666; font-style: italic;">// "SYMBOL","NAME","LAST_TRADE","MORE_INFO",</span>
- <br>
- <span style="color: #666666; font-style: italic;">//"LAST_TRADE_DATE","LAST_TRADE_TIME","OPEN",</span>
- <br>
- <span style="color: #666666; font-style: italic;">//"DAYS_HIGH","DAYS_LOW","DIVIDEND_SHARE",</span>
- <br>
- <span style="color: #666666; font-style: italic;">//"PE_RATIO","52_WEEK_LOW","52_WEEK_HIGH","VOLUME"</span>
- <br>
- <span style="color: #000088;">$output</span>
- <span style="color: #339933;">=</span>
- <span style="color: #0000ff;">''</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #b1b100;">for</span>
- <span style="color: #009900;">(</span>
- <span style="color: #000088;">$i</span>
- <span style="color: #339933;">=</span>
- <span style="color: #cc66cc;">0</span>
- <span style="color: #339933;">,</span>
- <span style="color: #000088;">$cnt</span>
- <span style="color: #339933;">=</span>
- <span style="color: #990000;">count</span>
- <span style="color: #009900;">(</span>
- <span style="color: #000088;">$quotes</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #000088;">$i</span>
- <span style="color: #339933;"><</span>
- <span style="color: #000088;">$cnt</span>
- <span style="color: #339933;">;</span>
- <span style="color: #000088;">$i</span>
- <span style="color: #339933;">++</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">{</span>
- <br>
- <span style="color: #000088;">$output</span>
- <span style="color: #339933;">.=</span>
- <span style="color: #0000ff;">"Company: "</span>
- <span style="color: #339933;">.</span>
- <span style="color: #000088;">$quotes</span>
- <span style="color: #009900;">[</span>
- <span style="color: #000088;">$i</span>
- <span style="color: #009900;">]</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">NAME</span>
- <span style="color: #339933;">.</span>
- <span style="color: #0000ff;">"<span style="color: #000099; font-weight: bold;">/n</span>
- "</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$output</span>
- <span style="color: #339933;">.=</span>
- <span style="color: #0000ff;">"Ticker: "</span>
- <span style="color: #339933;">.</span>
- <span style="color: #000088;">$quotes</span>
- <span style="color: #009900;">[</span>
- <span style="color: #000088;">$i</span>
- <span style="color: #009900;">]</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">SYMBOL</span>
- <span style="color: #339933;">.</span>
- <span style="color: #0000ff;">"<span style="color: #000099; font-weight: bold;">/n</span>
- "</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$output</span>
- <span style="color: #339933;">.=</span>
- <span style="color: #0000ff;">"Last trade: $"</span>
- <span style="color: #339933;">.</span>
- <span style="color: #000088;">$quotes</span>
- <span style="color: #009900;">[</span>
- <span style="color: #000088;">$i</span>
- <span style="color: #009900;">]</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">LAST_TRADE</span>
- <span style="color: #339933;">.</span>
- <span style="color: #0000ff;">"<span style="color: #000099; font-weight: bold;">/n</span>
- "</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$output</span>
- <span style="color: #339933;">.=</span>
- <span style="color: #0000ff;">"<span style="color: #000099; font-weight: bold;">/n</span>
- "</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #009900;">}</span>
- <br>
- <span style="color: #000088;">$output</span>
- <span style="color: #339933;">=</span>
- <span style="color: #990000;">html_entity_decode</span>
- <span style="color: #009900;">(</span>
- <span style="color: #000088;">$output</span>
- <span style="color: #339933;">,</span>
- <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span>
- <span style="color: #339933;">,</span>
- <span style="color: #0000ff;">"UTF-8"</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #666666; font-style: italic;">// Something is wrong with '</span>
- <br>
- <span style="color: #000088;">$output</span>
- <span style="color: #339933;">=</span>
- <span style="color: #990000;">str_replace</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">"'"</span>
- <span style="color: #339933;">,</span>
- <span style="color: #0000ff;">"'"</span>
- <span style="color: #339933;">,</span>
- <span style="color: #000088;">$output</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">dialogCreateAlert</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">"Your stock quotes"</span>
- <span style="color: #339933;">,</span>
- <span style="color: #000088;">$output</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">dialogSetPositiveButtonText</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">"Get new quote"</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">dialogSetNegativeButtonText</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">"Exit"</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">dialogShow</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$response</span>
- <span style="color: #339933;">=</span>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">dialogGetResponse</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #b1b100;">if</span>
- <span style="color: #009900;">(</span>
- <span style="color: #000088;">$response</span>
- <span style="color: #009900;">[</span>
- <span style="color: #0000ff;">'result'</span>
- <span style="color: #009900;">]</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">which</span>
- <span style="color: #339933;">==</span>
- <span style="color: #0000ff;">'negative'</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">{</span>
- <br>
- <span style="color: #000088;">$action</span>
- <span style="color: #339933;">=</span>
- <span style="color: #0000ff;">"exit"</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #009900;">}</span>
- <span style="color: #b1b100;">else</span>
- <span style="color: #009900;">{</span>
- <br>
- <span style="color: #000088;">$action</span>
- <span style="color: #339933;">=</span>
- <span style="color: #0000ff;">'get_tickers'</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #009900;">}</span>
- <br>
- <span style="color: #b1b100;">break</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #b1b100;">case</span>
- <span style="color: #0000ff;">'get_tickers'</span>
- <span style="color: #339933;">:</span>
- <br>
- <span style="color: #000088;">$response</span>
- <span style="color: #339933;">=</span>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">getInput</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">"Stock Tickers (max. 3)"</span>
- <span style="color: #339933;">,</span>
- <span style="color: #0000ff;">"Enter Tickers.<span style="color: #000099; font-weight: bold;">/n</span>
- Separate with spaces."</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <br>
- <span style="color: #000088;">$tickers</span>
- <span style="color: #339933;">=</span>
- <span style="color: #990000;">str_replace</span>
- <span style="color: #009900;">(</span>
- <span style="color: #0000ff;">' '</span>
- <span style="color: #339933;">,</span>
- <span style="color: #0000ff;">'+'</span>
- <span style="color: #339933;">,</span>
- <span style="color: #000088;">$response</span>
- <span style="color: #009900;">[</span>
- <span style="color: #0000ff;">'result'</span>
- <span style="color: #009900;">]</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">vibrate</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #000088;">$action</span>
- <span style="color: #339933;">=</span>
- <span style="color: #0000ff;">'quote'</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #b1b100;">break</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #b1b100;">case</span>
- <span style="color: #0000ff;">'exit'</span>
- <span style="color: #339933;">:</span>
- <br>
- <span style="color: #000088;">$droid</span>
- <span style="color: #339933;">-></span>
- <span style="color: #004000;">exit</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #990000;">exit</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #b1b100;">break</span>
- <span style="color: #339933;">;</span>
- <br>
- <span style="color: #009900;">}</span>
- <br>
- <span style="color: #009900;">}</span>
- <br>
- <span style="color: #000000; font-weight: bold;">?></span>
復制黏貼上述代碼進你的編輯器,並保存為quoter4android.php,上傳至你的模擬器。如果你的模擬器沒有運行,發動它,配置你的端口轉發並通過位於Android SDK的tools目錄下的adb上傳quoter4android.php 文件。
為了在你的模擬器運行這個程序,切換到Applications 界面,點擊圖標SL4A 並單擊quoter4android.php 選項。
要安裝quoter4android.php 到你的手機上的話,你可以配置端口轉發。不過更簡單的方法就是將你的手機和電腦通過USB線連接,並將這個腳本復制進目錄 sl4a/scripts 。不過,為了在你的手機中運行腳本,你得將你的手機與電腦斷開,否則當你點擊圖標SL4A 時你不會看到任何已經安裝的腳本。
你會注意到這個程序的第一行設置了一個常量QUOTE_SERVER
。如果你習慣於傳統的商用PHP web應用的建設,你不需要去擔心分發你的代碼並且在未來改變它—那不是它在android上應該做的事。你必須發布你原始的PHP代碼。所以如果你決定 將你的PHP android應用放進菜市場(Android Market),你將把一個你無法控制的網址硬編碼進你的應用,你的應用會拋錨。
例如,這個股票報價應用程序實際上是從一個Yahoo Web Service中獲取股票信息。但與其將Yahoo的鏈接直接硬編碼進這個Android應用,我選擇的是創建一個連接應用和Yahoo股票服務的簡單 web service。這樣即使Yahoo決定停止提供這個服務,或者它們改變了連接地址,我只需要簡單地更新位於quoter.take88.com 的web service。而這個Android代碼不需要做任何改變,沒人會在他的手機上發現一個掛掉的應用。而且,我可以將一些復雜度超出Android應用允 許的功能轉移到我的web service,在那我可以使用完整的語言支持而不只是一個精簡版的PHP。在這個例子中,我通過mod_perl
來用perl實現我的web service。
結論
通過SL4A和PHP for Android你可以做很多事,這篇文章只是管中窺豹而已。這兩個項目都非常年輕—實際上,在我打字的時候SL4A的新版本已經誕生(放心使用最新版吧) —隨着它們的成長,它們可以實現更多的可能性。在任何情況下,保持你的Android應用短小輕快吧。