android使用google map时无法显示地图或者只显示方格(或者模拟器上显示地图真机上却显示方格)的问题主要有两个原因:
1.没有配置好mapview的使用环境;
2.没有获取正确的Maps API Key。
至于可能是其他硬件原因,不作分析。
配置好mapview的使用环境:
(1.)需要在新建项目中选中正确的Build Target选项,即Google APIs版本;
(2.)在AndroidManifest.xml配置文件中引用maps library <uses-library android:name=”com.google.android.maps” />(application标签内)以及网络访问权限<uses-permission android:name=”android.permission.INTERNET” /> ;
(3.)在布局文件的MapView标签属性android:apiKey中引入Maps API Key,同时注意加上两个属性android:clickable=”true”
android:enabled=”true”。
大多数问题在于没有获取正确的Maps API Key,这会导致地图上面只显示方格而无法显示正确的地图。需要了解的是,每个android的应用程序都需要一个keystore,在调试过程中生成的apk文件就包含一个默认的debug.keystore,默认路径C:\Documents and Settings\Administrator\.android\debug.keystore,这个可以在eclipse->Windows->Preferences->Android->Build可以看到路径。
获取Maps API Key的教程,可以简单的两步实现:
1.打开http://code.google.com/intl/zh-CN/android/maps-api-signup.html页面,在windows cmd模式下,进入debug.keystore所在的目录输入keytool -list -keystore debug.keystore,输入默认的密码android,就可以在本机上获取认证指纹(MD5)。如图-1
图-1 cmd命令行获取认证指纹(MD5)
2.在上面的网页下面My certificate’s MD5 fingerprint输入框输入上面的认证指纹MD5,跳转页面可以获得Maps API Key。
上面的两个步骤是为debug.keystore获取Maps API Key。当应用程序再次发布时,需要使用新的keystore,而不是使用默认的debug.keystore,这时候需要重新获取API Key。至于如何生成新的keystore,可以参考eclipse 将android项目打包成签名的apk文件,重新获取Maps API Key,执行keytool -list -keystore debug.keystore命令时,将debug.keystore换成新生成的keystore文件,获取新Maps API Key。
上述过程就解释了模拟器上显示地图方格(没有获得正确的debug.keystore的API Key)与在真机上显示方格的两个问题(没有重新获取新的keystore文件的API Key)。采用真机调试模式连接到真机的应用程序,不需要重新获取API Key。至此,关于android使用google map时显示方格的问题得以解决。如果读者你认为还出现其他问题仍然无法显示正确的地图,可以留言讨论。
本文的第二部分内容就是MapView例子的使用,在google地图上实现多点标注地图的功能,并点击图标显示标注点的标题,片段等信息,如图-2。使用本例子需要再重新获取Maps API Key,否则还是会显示方格。
图-2 Mapview 地图实现多点标注功能
以下是文件源码。
1.MapViewDemoActivity .java源码
package com.mapview.demo; import java.util.ArrayList; import java.util.List; import com.google.android.maps.GeoPoint; import com.google.android.maps.ItemizedOverlay; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import com.google.android.maps.OverlayItem; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.widget.Toast; public class MapViewDemoActivity extends MapActivity { MapView mapView; MapController mc; List<Overlay> mapOverlays; Drawable drawable; MyItemizedOverlay itemizedOverlay; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取mapView并设置相关属性 mapView = (MapView) findViewById(R.id.map); // 缩放功能 mapView.setBuiltInZoomControls(true); // 获取地图覆盖层的List mapOverlays = mapView.getOverlays(); // 标注图标 drawable = this.getResources().getDrawable(R.drawable.pushpin); itemizedOverlay = new MyItemizedOverlay(drawable); // 定义两个地方的经纬度 Double lat = 22.534459 * 1E6; Double lng = 113.9928 * 1E6; Double lat2 = 22.536387 * 1E6; Double lng2 = 113.974507 * 1E6; // GeoPoint 1 GeoPoint point = new GeoPoint(lat.intValue(), lng.intValue()); OverlayItem overlayitem = new OverlayItem(point, "康佳集团", "正门"); // GeoPoint 2 GeoPoint point2 = new GeoPoint(lat2.intValue(), lng2.intValue()); OverlayItem overlayitem2 = new OverlayItem(point2, "世界之窗", "广场"); // 添加两个覆盖层并填充 itemizedOverlay.addOverlay(overlayitem); itemizedOverlay.addOverlay(overlayitem2); // mapview中添加itemizedOverlay mapOverlays.add(itemizedOverlay); //将point移至地图中间显示 mc = mapView.getController(); mc.setCenter(point); mc.setZoom(18); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } // 定义MyItemizedOverlay类 class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> { // 定义一个OverlayItem(覆盖的层)的ArrayList private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>(); public MyItemizedOverlay(Drawable defaultMarker) { // 在底部中间显示 super(boundCenterBottom(defaultMarker)); // TODO Auto-generated constructor stub } // 调用ArrayList的每一项(覆盖层) @Override protected OverlayItem createItem(int i) { // TODO Auto-generated method stub return mOverlays.get(i); } // 返回大小 @Override public int size() { // TODO Auto-generated method stub return mOverlays.size(); } // 用于显示标注信息 @Override protected boolean onTap(int index) { OverlayItem item = mOverlays.get(index); // 标题 String title = item.getTitle(); // 片段 String snippet = item.getSnippet(); Toast.makeText(MapViewDemoActivity.this, title + "\n" + snippet, Toast.LENGTH_LONG).show(); return true; } // 定义一个方法添加覆盖层 public void addOverlay(OverlayItem overlay) { // 添加覆盖层 mOverlays.add(overlay); // 填充 populate(); } } }
2.main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <com.google.android.maps.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="wrap_content" android:apiKey="0bICReSImsEvI16EsnPDUkwRIsqPitPYH7I5ugQ" android:clickable="true" android:enabled="true" /> </LinearLayout>
AndroidManifest.xml配置文件加入:
<uses-library android:name="com.google.android.maps" /> <uses-permission android:name="android.permission.INTERNET" />
源码下载:MapViewDemo.zip
你好,问一下,如何在地图上显示两个标记,你的代码我试了一下,只能显示一个标记位置
你定义了两个点,为什么地图上只显示了一个点
因为程序把其中一点移至中心显示(mc.setCenter(point);)而且放大到mc.setZoom(18);跨域太大无法显示,将倍数放小点,或者将地图缩放小点就能看到两点了
Thanks for the sensible critique. Me and my neighbor were just preparing to do a little research on this. We got a grab a book from our area library but I think I learned more from this post. I am very glad to see such great info being shared freely out there.
为何我按照这样做了,显示了,但是显示的是英文?怎么设置?
这个应该跟android系统设置的语言有关,将系统语言设置为中文试试。