最近在做一个项目,其中就需要用到咱们今天要说的主角Google Map。开始做的时候感觉没多难的,可是慢慢的慢慢的就发现问题越来越多了,当然本人水平有限是其中之一,也有一些让不少人蛋疼的问题。废话不多说,一步步来看看咱们可能回碰到的问题吧! 如果你要做一个google Map的项目,首先你用的sdk 应该是对应版本的google api ,这个不多说了,大家应该都知道的。然后你需要注册google账号(当然如果你已经有了的话就不用了),然后用你的MD5去https://developers.google.com/android/maps-api-signup?hl=zh-CN申请apikey。至于MD5怎么得到,这个大家可以去网上搜搜,很多的。这里就出现了大家可能会碰到的第一个蛋疼的问题,刚刚那个申请的网址打开后可能申请不了。所以,翻墙吧。好了,准备工作做完了,现在就正式开始了!!!!
首先,需要有必须的权限,比如:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
在manifest.xml中加上要用的maps库:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.package.name">
...
<application android:name="MyApplication" >
<uses-library android:name="com.google.android.maps" />
...
</application>
...
</manifest>
这里又隐形的出现了另外一个问题,那就是com.google.android.maps.jar 这个文件可能在你的真机上不存在(如果你用真机测试的话),模拟机上是存在的,真机不存在是有可能的,这是因为很多厂商没有开通这个。解决真机文件不存在的问题步骤如下:
1、首先进入到你的adb.exe安装目录下,然后执行命令adb -d shell;进入shell模式:$
2、打开模拟器的DDMS视图,将/system/framework 的com.google.android.maps.jar , com.google.android.gtalkservice.jar文件以及/system/etc下面的com.google.android.maps.xml , com.google.android.gtalkservice.xml文件导出(android 2.2以上系统里没有 com.google.android.gtalkservice.jar 和 com.google.android.gtalkservice.xml文件,所以只需导前一个)。
文件导出既可以直接在DDMS中导出,也可以用命令导出,如:
adb pull /system/framework/com.google.android.maps.jar d:/yourdir/com.google.android.maps.jar;
adb pull /system/framework/com.google.android.gtalkservice.jar d:/yourdir/com.google.android.gtalkservice.jar;
adb pull /system/framework/com.google.android.maps.xml d:/yourdir/com.google.android.maps.xml;
adb pull /system/framework/com.google.android.gtalkservice.xml d:/yourdir/com.google.android.gtalkservice.xml;
3、将这些文件导入你的真机系统里:
adb push d:/yourdir/com.google.android.maps.jar /syetem/framework;
adb push d:/yourdir/com.google.android.gtalkservice.jar /syetem/framework;
adb push d:/yourdir/com.google.android.maps.xml /syetem/etc;
adb push d:/yourdir/com.google.android.gtalkservice.xml /syetem/etc;
现在你的真机里就有了这些文件了。当然上面步骤能成功的前提是获得root权限!!!!!
现在来分析一下Maps 库:
Maps库提供了十几个类,具体可以参考这里http://code.google.com/intl/ja/android/add-ons/google-apis/reference/index.html,包括Mapview,MapController,MapActivity等。
(1)MapController
控制地图移动,伸缩,以某个GPS坐标为中心,控制MapView中的view组件,管理Overlay,提供View的基本功能。使用多种地图模式(地图模式(某些城市可实时对交通状况进行更新),卫星模式,街景模式)来查看Google Map。
常用方法有:animateTo(GeoPoint point) setCenter(GeoPoint point) setZoom(int zoomLevel) 等
(2)MapView
Mapview是用来显示地图的view, 它派生自android.view.ViewGroup。当MapView获得焦点,可以控制地图的移动和缩放。地图可以以不同的形式来显示出来,如街景模式,卫星模式等,通过setSatellite(boolean) setTraffic(boolean), setStreetView(boolean) 方法。MapView只能被MapActivity来创建,这是因为mapview需要通过后台的线程来连接网络或者文件系统,而这些线程要由mapActivity来管理。
需要特别说明的一点是,android 1.5中,map的zoom采用了built-in机制,可以通过setBuiltInZoomControls(boolean)来设置是否在地图上显示zoom控件。
(3)MapActivity
管理Activity的生命周期,为mapview建立及取消对map service的连接。
MapActivity是一个抽象类,任何想要显示MapView的activity都需要派生自MapActivity。并且在其派生类的onCreate()中,都要创建一个MapView实例,可以通过MapViewconstructor (然后添加到View中ViewGroup.addView(View)) 或者通过layout XML来创建。
(4)Overlay
Overlay是覆盖到MapView的最上层,可以扩展其ondraw接口,自定义在MapView中显示一些自己的东西。MapView通过MapView.getOverlays()对Overlay进行管理。除了Overlay这个基类,Google还扩展了2个比较有用的Overlay
1)MylocationOverlay—集成了Android.location中接收当前坐标的接口,集成SersorManager中CompassSensor的接口
我们只需要enableMyLocation(),enableCompass就可以让我们的程序拥有实时的MyLocation以及Compass 功能(Activity.onResume()中)。
2)ItemlizedOverlay—管理一个OverlayItem链表,用图片等资源在地图上作风格相同的标记。
(5)Projection:MapView中GPS坐标与设备坐标的转换(GeoPoint和Point)。
其中主要的代码如下:
xml文件里的MapView代码
<com.google.android.maps.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="???????????????????????????????????"
/>
Activity里的主要代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取MapView
map=(MapView)findViewById(R.id.map);
// 设置显示模式
map.setTraffic(true);
map.setSatellite(false);
map.setStreetView(true);
// 设置可以缩放
map.setBuiltInZoomControls(true);
// 设置初始地图的中心位置
GeoPoint geoBeijing=new GeoPoint((int)(39.95*1000000), (int)(116.37*1000000));
mapCon=map.getController();
mapCon.setCenter(geoBeijing);
}
这里的Activity是继承了MapActivity的哦!!!