一、引言
本项目将开发一个集成了 Google Maps JavaScript API V3 的 jQuery Mobile Web App , 并通过 Phonegap 开发框架将应用部署到本地 Android 平台上运行。
二、开发环境搭建
1.环境下载:
Eclipse: Juno Service Release 2 (4.2.2)
PhoneGap 2.6.0 : Cordova (已更新至2.7.0)
Android SDK :Bundle for Windows (已更新至r22)
其它(如JDK、ADT等)环境及基本部署不是本项目重点将不再赘述,请参考其他开发文档。
2.Eclipse Phonegap 构建:
Step 1:
新建项目: Android Application Project -> Compile With : API 15 Android 4.0.3 , 此时的项目名会默认为生成的APK包名,也可以之后通过右键单击项目->重构->重命名修改。
我们可以参考已经下载解压后的Phonegap文件中自带的教程(如下图所示):
Step 2:
在项目根目录的assets文件下新建一个www文件夹用来存放网站的内容。
Step 3:
• 将phonegap-2.6.0/lib/android文件夹下的cordova-2.6.0.js和cordova-2.6.0.jar这两个文件分别复制到项目根目录下的/assets/www和/libs文件夹中。
• 其次,我们需要将cordova-2.6.0.jar库添加到该 Android 项目的构建路径中:
右键单击libs文件夹选择构建路径->配置构建路径->Java构建路径->库(L),单击添加JAR,选择之前在本项目libs文件夹中的cordova-2.6.0.jar路径,单击确定即可。
• 再把phonegap-2.6.0/lib/android文件夹下的xml(xml整个文件夹)复制到本项目的res目录下。
Step 4:
在 assets/www 文件夹中创建一个名为 index.html 的文件。此文件将用作 PhoneGap 应用程序界面的主要入口点。
最好声明成HTML5文档,即:<!DOCTYPE HTML> 。
Step 5:
• 更新Actvity类:在主类 MainActivity.java 文件中引入 DroidGap :
import org.apache.cordova.DroidGap;
• 将继承的基类由Actvity更改为DroidGap
;它位于类定义中extends
一词的后面:
public class MainActivity extends DroidGap {
• 同时删去import android.app.Activity; (不解释)
• 修改onCreate函数 protected void onCreate(Bundle savedInstanceState)) { 由私有protected替换为公共public,即:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
• 删去setContentView(...);语句,替换成:
super.loadUrl(file:///android_asset/www/index.html);
• 请看官方给的示例图:
Step 6:
最后是配置项目元数据,以使 PhoneGap 运行:
• 在项目的根目录下打开使用 Eclipse 文本编辑器 AndroidManifest.xml 文件。方法是右键单击 AndroidManifest.xml 文件,然后选择打开方式->文本编辑器。
• 在 AndroidManifest.xml 中,添加以下节点作为根节点 <manifest> 的子节点:
<supports-screens android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:resizeable="true" android:anyDensity="true" />
<supports-screens> 节点可识别应用程序支持的屏幕大小,我们可以通过更改此条目的内容来调整屏幕和外观设置支持。
• 在修改 AndroidManifest.xml , 增加需要的权限:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission>的值可识别要为应用程序启用的功能。上述代码行可启用 PhoneGap 所有功能正常运行所需的全部权限。
构建完应用程序后,您可能希望删除不会实际用到的所有权限;这将会删除应用程序安装过程中出现的安全警告。
了解有关 Android 权限和<uses-permission>元素的更多信息,请访问 Android 开发人员主题–用户权限元素。
• 在默认的那个activity标签中追加如下语句:
android:configChanges="orientation|screenSize|keyboardHidden">
注意:API>13(即3.2以上)时,加上"|screenSize|"属性,就不会在旋转屏幕时重启activity报错了。
• 最后在 AndroidManifest.xml 里追加一个新的 Activity , 即需要再为 org.apache.cordova.DroidGap 类创建一个 <activity> 节点。
添加下面的 <activity> 节点作为现有 <activity> 节点的同级节点:
<activity android:name="org.apache.cordova.DroidGap" android:label="@string/app_name" android:configChanges="orientation|screenSize|keyboardHidden"> <intent-filter></intent-filter> </activity>
三、项目开发:
1. index.html
• 首先,样式化我们的页面和地图容器,以便它能够全屏显示:
<meta name="viewport" content="width=device-width, initial-scale=1">
• 接下来,导入自定义的JavaScript,用以确定用户的地理位置,并绘制出地图视图。稍后我们会给出该文件的细节。
<script type="text/javascript" src="maps.js"></script>
• 然后导入Google Maps API :
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&v=3&libraries=geometry"></script>
• 最后,标识我们的地图容器。我们的地图会绘制在该元素内:
<div data-role="content" id="map-canvas"> <!-- map loads here... --> </div>
自定义的JavaScript用来确定用户的地理位置,以及绘制出地图视图,接下来我们将讨论它。
2. maps.js
• 首先,确定浏览器是否支持地理定位:
if ( navigator.geolocation ) { ...
}
• 如果浏览器支持地理定位,我们就尝试获取用户的当前位置,这会尝试使用GPS来进行定位(如果支持的话)。
我们还将设置超时时间为8秒,如果8秒之后还未找到用户的位置,则会调用error回调。
同时,我们也对查询进行了配置,使其能够使用3分钟之内的缓存位置。
// Find the users current position. Cache the location for 3 minutes, timeout after 8 seconds navigator.geolocation.watchPosition(success, fail, {maximumAge:180000, enableHighAccuracy:true, timeout:8000});
• 当成功定位后,将会调用success回调,我们将使用位置坐标来绘制地图:
function success(pos) { // Location found, show map with these coordinates drawMap(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude)); }
• 最后,用drawMap方法绘制出Google地图,而且在地图中心位置显示一个覆盖坐标(overlay icon),用来显示当前你所在的位置。
function drawMap(latlng) { var myOptions = { zoom: 10, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map-canvas"), myOptions); // Add an overlay to the map of current lat/lng var marker = new google.maps.Marker({ position: latlng, map: map, title: "Greetings!" });
然而,如果不支持地理定位或者是定位不成功,则会显示默认的地理位置坐标:
function fail(error) { console.log(error); drawMap(defaultLatLng); // Failed to find location, show default map } ...
}//if
else { drawMap(defaultLatLng); // No geolocation support, show default map }
四、项目优化:
• 应用启动运行时,先弹出程序名才加载初始画面和内容,解决方法:
修该AndroidManifest.xml文件中,<application 代码:
默认:android:theme="@style/AppTheme">
修改为:android:theme="@android:style/Theme.Black.NoTitleBar" > //黑色背景,并且不显示应用程序标题栏
(备注:Android平台定义的主题样式如下:请参考其他人总结的博文。)
• 为应用程序添加初始画面,在MainActivity.java中加入如下代码:
super.setIntegerProperty("splashscreen", R.drawable.qidong); super.loadUrl("file:///android_asset/www/index.html",4300); //添加预留时间4.3秒
• 有关其他优化和改进暂时不予提供。
五、运行效果截图:
注:本项目灵感及基本代码来源于Brad Broulik所著的《Pro jQuery Mobile》一书。