解决android使用google map时显示方格的问题
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