本文将讲述安卓调用百度地图的实现方法,刚接触百度地图的童鞋可以作为参考,先看效果图:
再看工程文件:
注意,该项目所用百度sdk为最新版,需用最新密钥,再次声明,那些在调用百度地图时老是不正常的童鞋,一定要根据你的sdk版本申请对应密钥,这个我已经在上一篇文章中讲过了,大家可以去参考下。
首先看,主界面布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.byl.testbaidumap.MyLocationMapView android:id="@+id/bmapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="10dp" android:background="@drawable/edit_bg_all" > <EditText android:id="@+id/txtAddr" android:layout_width="fill_parent" android:layout_height="40dp" android:layout_centerVertical="true" android:layout_marginRight="2dp" android:layout_toLeftOf="@+id/btOk" android:background="@drawable/edit_bg_all" android:completionThreshold="2" android:drawableLeft="@drawable/qz_icon_seabar_search" android:hint="请输入搜索关键字" /> <TextView android:id="@+id/btOk" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginRight="2dp" android:layout_toLeftOf="@+id/s2" android:text="搜索" android:textSize="18sp" /> <ImageView android:id="@+id/s2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginRight="2dp" android:layout_toLeftOf="@+id/btget" android:src="@drawable/slide_center" /> <TextView android:id="@+id/btget" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="定位" android:textSize="18sp" /> </RelativeLayout> </FrameLayout> </RelativeLayout>
再看主Activity:
package com.byl.testbaidumap; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TextView; import android.widget.Toast; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.map.LocationData; import com.baidu.mapapi.map.MKEvent; import com.baidu.mapapi.map.MapController; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.MyLocationOverlay; import com.baidu.mapapi.map.PoiOverlay; import com.baidu.mapapi.map.MyLocationOverlay.LocationMode; import com.baidu.mapapi.map.PopupClickListener; import com.baidu.mapapi.map.PopupOverlay; import com.baidu.mapapi.search.MKAddrInfo; import com.baidu.mapapi.search.MKBusLineResult; import com.baidu.mapapi.search.MKDrivingRouteResult; import com.baidu.mapapi.search.MKPoiInfo; import com.baidu.mapapi.search.MKPoiResult; import com.baidu.mapapi.search.MKSearch; import com.baidu.mapapi.search.MKSearchListener; import com.baidu.mapapi.search.MKShareUrlResult; import com.baidu.mapapi.search.MKSuggestionResult; import com.baidu.mapapi.search.MKTransitRouteResult; import com.baidu.mapapi.search.MKWalkingRouteResult; import com.baidu.platform.comapi.basestruct.GeoPoint; /** * 此demo用来展示如何结合定位SDK实现定位,并使用MyLocationOverlay绘制定位位置 * 同时展示如何使用自定义图标绘制并点击时弹出泡泡 * */ public class MainActivity extends Activity { private EditText txtAddr; // 定位相关 LocationClient mLocClient; LocationData locData = null; public MyLocationListenner myListener = new MyLocationListenner(); //public BMapManager mBMapManager=null; public MyApplication app; //定位图层 locationOverlay myLocationOverlay = null; //弹出泡泡图层 private PopupOverlay pop = null;//弹出泡泡图层,浏览节点时使用 private TextView popupText = null;//泡泡view private View viewCache = null; //地图相关,使用继承MapView的MyLocationMapView目的是重写touch事件实现泡泡处理 //如果不处理touch事件,则无需继承,直接使用MapView即可 public MyLocationMapView mMapView = null; // 地图View private MapController mMapController = null; private MKSearch mMKSearch = null;//用于信息检索服务 //UI相关 OnCheckedChangeListener radioButtonListener = null; TextView requestLocButton ,btSerach; boolean isRequest = false;//是否手动触发请求定位 boolean isFirstLoc = true;//是否首次定位 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 使用地图sdk前需先初始化BMapManager. * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建, * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁 */ app = (MyApplication)this.getApplication(); if (app.mBMapManager == null) { app.mBMapManager = new BMapManager(getApplicationContext()); /** * 如果BMapManager没有初始化则初始化BMapManager */ app.mBMapManager.init(MyApplication.strKey,new MyApplication.MyGeneralListener()); } setContentView(R.layout.activity_main); txtAddr=(EditText)findViewById(R.id.txtAddr);//关键字输入框 //监听搜索单击事件 btSerach= (TextView)findViewById(R.id.btOk); btSerach.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mMKSearch.poiSearchInCity("", txtAddr.getText().toString()); } }); //定位按钮 requestLocButton = (TextView)findViewById(R.id.btget); requestLocButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { requestLocClick(); } }); //地图初始化 mMapView = (MyLocationMapView)findViewById(R.id.bmapView); mMapView.setTraffic(true);//设置地图模式为交通视图(也可为卫星视图) mMapController = mMapView.getController(); mMapView.getController().setZoom(15); mMapView.getController().enableClick(true); mMapView.setBuiltInZoomControls(true); //信息检索初始化 mMKSearch = new MKSearch(); mMKSearch.init(app.mBMapManager, new MKSearchListener() { @Override public void onGetAddrResult(MKAddrInfo arg0, int arg1) { } @Override public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) { } @Override public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) { } @Override public void onGetPoiDetailSearchResult(int arg0, int arg1) { } @Override public void onGetPoiResult(MKPoiResult res, int type, int error) { if (error == MKEvent.ERROR_RESULT_NOT_FOUND) { Toast.makeText(MainActivity.this, "抱歉,未找到结果", Toast.LENGTH_LONG).show(); return; } else if (error != 0 || res == null) { Toast.makeText(MainActivity.this, "搜索出错啦..", Toast.LENGTH_LONG).show(); return; } PoiOverlay poiOverlay = new PoiOverlay(MainActivity.this, mMapView); poiOverlay.setData(res.getAllPoi()); mMapView.getOverlays().clear(); mMapView.getOverlays().add(poiOverlay); mMapView.refresh(); for (MKPoiInfo info : res.getAllPoi()) { if (info.pt != null) { mMapView.getController().animateTo(info.pt); break; } } } @Override public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1, int arg2) { } @Override public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) { } @Override public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) { } @Override public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) { } }); createPaopao(); //定位初始化 mLocClient = new LocationClient( this ); locData = new LocationData(); mLocClient.registerLocationListener( myListener ); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);//打开gps option.setAddrType("all");//返回的定位结果包含地址信息 option.disableCache(false);//禁止启用缓存定位 option.setCoorType("bd09ll"); //设置坐标类型 option.setScanSpan(1000); mLocClient.setLocOption(option); mLocClient.start(); //定位图层初始化 myLocationOverlay = new locationOverlay(mMapView); //设置定位数据 myLocationOverlay.setData(locData); //添加定位图层 mMapView.getOverlays().add(myLocationOverlay); myLocationOverlay.enableCompass(); //修改定位数据后刷新图层生效 mMapView.refresh(); } /** * 手动触发一次定位请求 */ public void requestLocClick(){ isRequest = true; mLocClient.requestLocation(); Toast.makeText(MainActivity.this, "正在定位……", Toast.LENGTH_SHORT).show(); } /** * 创建弹出泡泡图层 */ public void createPaopao(){ viewCache = getLayoutInflater().inflate(R.layout.custom_text_view, null); popupText =(TextView) viewCache.findViewById(R.id.textcache); //泡泡点击响应回调 PopupClickListener popListener = new PopupClickListener(){ @Override public void onClickedPopup(int index) { } }; pop = new PopupOverlay(mMapView,popListener); MyLocationMapView.pop = pop; } /** * 定位SDK监听函数 */ public class MyLocationListenner implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location == null) return ; locData.latitude = location.getLatitude(); locData.longitude = location.getLongitude(); //如果不显示定位精度圈,将accuracy赋值为0即可 locData.accuracy = location.getRadius(); // 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。 locData.direction = location.getDerect(); //更新定位数据 myLocationOverlay.setData(locData); //更新图层数据执行刷新后生效 mMapView.refresh(); //是手动触发请求或首次定位时,移动到定位点 if (isRequest || isFirstLoc){ //移动地图到定位点 //Log.d("LocationOverlay", "receive location, animate to it"); mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6))); isRequest = false; myLocationOverlay.setLocationMode(LocationMode.FOLLOWING); } //首次定位完成 isFirstLoc = false; } public void onReceivePoi(BDLocation poiLocation) { if (poiLocation == null){ return ; } } } //继承MyLocationOverlay重写dispatchTap实现点击处理 public class locationOverlay extends MyLocationOverlay{ public locationOverlay(MapView mapView) { super(mapView); } @Override protected boolean dispatchTap() { //处理点击事件,弹出泡泡 popupText.setBackgroundResource(R.drawable.popup); popupText.setText(mLocClient.getLastKnownLocation().getAddrStr()); pop.showPopup(BMapUtil.getBitmapFromView(popupText),new GeoPoint((int)(locData.latitude*1e6), (int)(locData.longitude*1e6)),8); return true; } } @Override protected void onPause() { mMapView.onPause(); if(app.mBMapManager!=null){ app.mBMapManager.stop(); } super.onPause(); } @Override protected void onResume() { mMapView.onResume(); if(app.mBMapManager!=null){ app.mBMapManager.start(); } super.onResume(); } @Override protected void onDestroy() { //退出时销毁定位 if (mLocClient != null) mLocClient.stop(); mMapView.destroy(); if(app.mBMapManager!=null){ app.mBMapManager.destroy(); app.mBMapManager=null; } super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mMapView.onRestoreInstanceState(savedInstanceState); } @Override public boolean onCreateOptionsMenu(Menu menu) { return true; } }
注意,密钥是在aplication中声明的:
package com.byl.testbaidumap; import android.app.Application; import android.content.Context; import android.widget.Toast; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.MKGeneralListener; import com.baidu.mapapi.map.MKEvent; public class MyApplication extends Application { private static MyApplication mInstance = null; public boolean m_bKeyRight = true; public BMapManager mBMapManager = null; public static final String strKey = "58byjGtcTxxOBRBCYBGCj8dt"; @Override public void onCreate() { super.onCreate(); mInstance = this; initEngineManager(this); } public void initEngineManager(Context context) { if (mBMapManager == null) { mBMapManager = new BMapManager(context); } if (!mBMapManager.init(strKey,new MyGeneralListener())) { Toast.makeText(MyApplication.getInstance().getApplicationContext(), "BMapManager 初始化错误!", Toast.LENGTH_LONG).show(); } } public static MyApplication getInstance() { return mInstance; } // 常用事件监听,用来处理通常的网络错误,授权验证错误等 public static class MyGeneralListener implements MKGeneralListener { @Override public void onGetNetworkState(int iError) { if (iError == MKEvent.ERROR_NETWORK_CONNECT) { //Toast.makeText(DemoApplication.getInstance().getApplicationContext(), "您的网络出错啦!",Toast.LENGTH_LONG).show(); } else if (iError == MKEvent.ERROR_NETWORK_DATA) { Toast.makeText(MyApplication.getInstance().getApplicationContext(), "输入正确的检索条件!",Toast.LENGTH_LONG).show(); } // ... } @Override public void onGetPermissionState(int iError) { //非零值表示key验证未通过 if (iError != 0) { //授权Key错误: // Toast.makeText(DemoApplication.getInstance().getApplicationContext(), // "请在 DemoApplication.java文件输入正确的授权Key,并检查您的网络连接是否正常!error: "+iError, Toast.LENGTH_LONG).show(); // DemoApplication.getInstance().m_bKeyRight = false; MyApplication.getInstance().m_bKeyRight = true; } else{ MyApplication.getInstance().m_bKeyRight = true; //Toast.makeText(DemoApplication.getInstance().getApplicationContext(), "key认证成功", Toast.LENGTH_LONG).show(); } } } }
当然,不要忘了在清单文件中配置aplication:
<application android:name="com.byl.testbaidumap.MyApplication"
还有调用百度地图相关的权限都已在清单文件中写的很清楚,以及代码中注释也比较详细,大家可以下载我的源码作为参考:
http://download.csdn.net/detail/baiyuliang2013/7109585