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应用短小轻快吧。