要想使用百度地圖SDK,就必須申請一個百度地圖的api key。申請流程很簡單。php
首先註冊成爲百度的開發者,而後打開http://lbsyun.baidu.com/apiconsole/key 這個網址,添加應用:android
建立應用最重要的一步是【安全碼】。安全碼所由【數字簽名】和【;】以及【包名】組成。包名就是建立的項目的包結構,git
是指AndroidManifest.xml中的mainfest標籤下的package的值。api
數字簽名指android的簽名證書的SHA1值。打開eclipse的preferences菜單,在Android的【Build】中能夠看到SHA1的值,以下圖:安全
打開http://developer.baidu.com/map/index.php?title=androidsdk/sdkandev-download 網址下載sdk,能夠所有下載或自定義下載。從V2.3.0以後的版本,網絡
SDK的開發包以可定製的形式提供下載,用戶能夠根據本身的項目須要勾選相應的功能下載對應的SDK開發包。app
a) 將開放包中的jar包和so文件添加到libs文件下。eclipse
b) 在AndroidManifest.xml中添加開放祕鑰和所需權限。ide
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="填寫你申請的AK" />
權限函數
<!-- 百度API所需權限 --> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
c) 在佈局文件中添加地圖控件:
<com.baidu.mapapi.map.MapView android:id="@+id/bmapview" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" />
d) 在應用程序建立時初始化SDK引用的Context全局變量。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); init(); }
這裏須要注意一下:initialize方法中必須傳入的是ApplicationContext,傳入this或MAinActivity.this會報運行時異常,因此百度建議把該方法放到Application的初始化方法中。
而後重寫activity的生命週期的幾個方法來管理地圖的生命週期。在activity的onResume、onPause、onDestory方法中
分別執行mapview的onReusme、onPause、onDestory方法。
public class MainActivity extends Activity { // 百度地圖控件 private MapView mMapView = null; // 百度地圖對象 private BaiduMap bdMap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); init(); } /** * 初始化方法 */ private void init() { mMapView = (MapView) findViewById(R.id.bmapview); } @Override protected void onResume() { super.onResume(); mMapView.onResume(); } @Override protected void onPause() { super.onPause(); mMapView.onPause(); } @Override protected void onDestroy() { mMapView.onDestroy(); mMapView = null; super.onDestroy(); } }
完成以上步驟,此時就能夠完成一個簡單的」Hello Map「程序了。
百度地圖將地圖的類型分爲兩種:普通矢量地圖和衛星圖
mMapView = (MapView) findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); //普通地圖 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL); //衛星地圖 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
//開啓交通圖 mBaiduMap.setTrafficEnabled(true);
熱力圖就是以特殊高亮的形式顯示訪客熱衷的頁面區域和訪客所在的地理區域的圖示。通俗來講就是顯示地圖上某一塊區域的人的密集程度。
//開啓熱力圖 mBaiduMap.setBaiduHeatMapEnabled(true);
一、SDK下載
從網站相關下載下載開發包並解壓。
爲保證服務能夠正常使用,您須要註冊成爲開發者並申請Key。每一個賬戶,最多能夠申請 30 個 Key。申請流程請參照獲取密鑰。
二、配置工程
步驟1:開發工程中新建「 libs 」文件夾,將地圖包(2D或3D)、搜索包拷貝到 libs 的根目錄下。若選擇3D地圖包,還須要將各庫文件夾一塊兒拷貝。拷貝完成後的工程目錄(以3D V2.2.0爲例)如圖所示:
注意:若您在 Eclipse 上使用 adt22 版本插件,則須要在 Eclipse 上進行以下配置:
選中 Eclipse 的工程,右鍵選擇 「Properties > Java Build Path > Order and Export」,勾選 「Android Private Libraries」。
三、代碼混淆
在生成apk進行代碼混淆時進行以下配置(若是爆出warning,在報出warning的包加入相似的語句:-dontwarn 包名)
3D 地圖 -keep class com.amap.api.mapcore.**{*;} -keep class com.amap.api.maps.**{*;} -keep class com.autonavi.amap.mapcore.*{*;} 定位 -keep class com.amap.api.location.**{*;} -keep class com.amap.api.fence.**{*;} -keep class com.autonavi.aps.amapapi.model.**{*;} 搜索 -keep class com.amap.api.services.**{*;} 2D地圖 -keep class com.amap.api.maps2d.**{*;} -keep class com.amap.api.mapcore2d.**{*;} 導航 -keep class com.amap.api.navi.**{*;} -keep class com.autonavi.**{*;}
Hello AMap完成地圖顯示功能,是地圖應用的開始。經過如下幾步操做,便可在您的應用中使用高德地圖SDK:
第一步:添加用戶key 在工程的「 AndroidManifest.xml 」文件以下代碼中添加您的用戶 Key。
<application android:icon="@drawable/icon" android:label="@string/app_name"> <meta-data android:name="com.amap.api.v2.apikey" android:value="請輸入您的用戶Key"></meta-data> <activity android:name="com.amap.map3d.demo.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"> <category android:name="android.intent.category.LAUNCHER"> </category></action></intent-filter> </activity> </application>
第二步:添加所需權限 在工程的「 AndroidManifest.xml 」文件中進行添加,請直接拷貝。
//地圖包、搜索包須要的基礎權限 <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <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.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
第三步:在佈局xml文件中添加地圖控件
<com.amap.api.maps.MapView android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent"> </com.amap.api.maps.MapView>
第四步,建立地圖Activity,管理地圖生命週期
public class MainActivity extends Activity { MapView mMapView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //獲取地圖控件引用 mMapView = (MapView) findViewById(R.id.map); //在activity執行onCreate時執行mMapView.onCreate(savedInstanceState),實現地圖生命週期管理 mMapView.onCreate(savedInstanceState); } @Override protected void onDestroy() { super.onDestroy(); //在activity執行onDestroy時執行mMapView.onDestroy(),實現地圖生命週期管理 mMapView.onDestroy(); } @Override protected void onResume() { super.onResume(); //在activity執行onResume時執行mMapView.onResume (),實現地圖生命週期管理 mMapView.onResume(); } @Override protected void onPause() { super.onPause(); //在activity執行onPause時執行mMapView.onPause (),實現地圖生命週期管理 mMapView.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //在activity執行onSaveInstanceState時執行mMapView.onSaveInstanceState (outState),實現地圖生命週期管理 mMapView.onSaveInstanceState(outState); } }
編譯運行,效果以下圖:
一、定位效果
地圖支持定位效果以下,能夠根據應用實際場景進行選擇。
定位模式,即只第一次定位到地圖中心點顯示
跟隨模式,即每次定位結果地圖居中顯示
旋轉模式,即每次定位結果地圖居中顯示,而且定位圖標跟隨手機方向旋轉
二、代碼示例:
public class NavigationActivity extends Activity implements LocationSource, AMapLocationListener { MapView mMapView; AMap mAmap; private AMapLocationClient mlocationClient; private AMapLocationClientOption mLocationOption; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home_navigation); mMapView = (MapView) findViewById(R.id.mapview_home_navigatiom_map); mMapView.onCreate(savedInstanceState); initMapOpitions(); } private void initMapOpitions() { mAmap = mMapView.getMap(); mAmap.setLocationSource(this);// 設置定位監聽 UiSettings uiSettings = mAmap.getUiSettings(); // 設置默認定位按鈕是否顯示 uiSettings.setMyLocationButtonEnabled(true); // 設置爲true表示顯示定位層並可觸發定位 mAmap.setMyLocationEnabled(true); //uiSettings.setScrollGesturesEnabled(true);// 平移(滑動)手勢 //aMap.moveCamera(CameraUpdateFactory.zoomTo(15)); // 設置縮放級別 // 設置定位的類型爲定位模式 ,能夠由定位、跟隨或地圖根據面向方向旋轉幾種 mAmap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE); // 覆蓋物點擊事件 mAmap.setOnPOIClickListener(new OnPOIClickListener() { @Override public void onPOIClick(Poi poi) { // 獲得座標,跳轉 LatLng latLng = poi.getCoordinate(); changeCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition( latLng, 17, 0, 30)), null); // 畫標記 drawMarkers(latLng); } }); } /** * 激活定位 */ @Override public void activate(OnLocationChangedListener listener) { if (mlocationClient == null) { mlocationClient = new AMapLocationClient(this); mLocationOption = new AMapLocationClientOption(); //設置爲高精度定位模式 mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy); //設置是否強制刷新WIFI,默認爲強制刷新 mLocationOption.setWifiActiveScan(true); //是否容許模擬位置 mLocationOption.setMockEnable(false); //定位時間間隔 mLocationOption.setInterval(2000); //設置定位參數 mlocationClient.setLocationOption(mLocationOption); //設置定位監聽 mlocationClient.setLocationListener(this); // 設置定位一次 //mLocationOption.setOnceLocation(true); // 此方法爲每隔固定時間會發起一次定位請求,爲了減小電量消耗或網絡流量消耗, // 注意設置合適的定位時間的間隔(最小間隔支持爲2000ms),而且在合適時間調用stopLocation()方法來取消定位請求 // 在定位結束後,在合適的生命週期調用onDestroy()方法 // 在單次定位狀況下,定位不管成功與否,都無需調用stopLocation()方法移除請求,定位sdk內部會移除 mlocationClient.startLocation(); } } /** * 定位監聽回調 */ @Override public void onLocationChanged(AMapLocation amapLocation) { if (amapLocation != null && amapLocation.getErrorCode() == 0) { // 跳轉到該座標 LatLng latLng = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude()); changeCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition( latLng, 17, 0, 30)), null); LatLonPoint latLonPoint = new LatLonPoint(amapLocation.getLatitude(), amapLocation.getLongitude()); //mCity = amapLocation.getCity(); mlocationClient.stopLocation(); } else { String errText = "定位失敗," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo(); Log.e("AmapErr",errText); } } /** * 調用函數animateCamera或moveCamera來改變可視區域(動畫) */ private void changeCamera(CameraUpdate update, CancelableCallback callback) { mAmap.animateCamera(update, 1000, callback); } /** * 畫標記 * @param latlng */ public void drawMarkers(LatLng latlng) { // 清空地圖的mark mAmap.clear(); // 添加標記 .title(address) 暫時去掉 Marker marker = mAmap.addMarker(new MarkerOptions() .position(latlng) .icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_AZURE)) .draggable(true)); // 設置默認顯示一個infowinfow marker.showInfoWindow(); } /** * 中止定位 */ @Override public void deactivate() { if (mlocationClient != null) { mlocationClient.stopLocation(); mlocationClient.onDestroy(); } mlocationClient = null; } @Override protected void onResume() { super.onResume(); mMapView.onResume(); } @Override protected void onPause() { super.onPause(); mMapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mMapView.onDestroy(); } }
高德地圖路徑規劃須要設定起始座標和結束座標,而後設置路徑搜索的回調接口setRouteSearchListener(this),經過BusRouteQuery、DriveRouteQuery、WalkRouteQuery類來搜索線路,
當搜索到結果後,會回調onBusRouteSearched()、onDriveRouteSearched()、onWalkRouteSearched()等三個方法,表示公交、自駕、步行三種方案。
反饋的結果busRouteResult、DriveRouteResult、WalkRouteResult,調用它們的getPaths()方法能夠得到線路方案的List集合。
/** * 導航類 * @author Legend-pc */ public class NavigationActivity extends Activity implements RouteSearch.OnRouteSearchListener { MapView mapView; AMap aMap; RouteSearch.FromAndTo fromAndTo;// 起始點和終點的經緯度 RouteSearch routeSearch; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home_navigation); mapView = (MapView) findViewById(R.id.mapview_home_navigatiom_map); mapView.onCreate(savedInstanceState); if (aMap == null) { aMap = mapView.getMap(); } // 起點座標 LatLonPoint start = new LatLonPoint(39.923271, 116.396034); // 終點座標 LatLonPoint end = new LatLonPoint(39.984947, 116.494689); // 實例化FromAndTo,從哪裏到達哪裏 fromAndTo = new RouteSearch.FromAndTo(start, end); // 實例化routeSearch(路徑搜索) routeSearch = new RouteSearch(this); routeSearch.setRouteSearchListener(this); // 初始化標記起始點 setfromandtoMarker(start, end); } private void setfromandtoMarker(LatLonPoint startLatLonPoint, LatLonPoint endLatLonPoint) { LatLng startLatLng = new LatLng(startLatLonPoint.getLatitude(), startLatLonPoint.getLongitude()); LatLng endLatLng = new LatLng(endLatLonPoint.getLatitude(), endLatLonPoint.getLongitude()); aMap.addMarker(new MarkerOptions() .position(startLatLng) .icon(BitmapDescriptorFactory.fromResource(R.drawable.start))); aMap.addMarker(new MarkerOptions() .position(endLatLng) .icon(BitmapDescriptorFactory.fromResource(R.drawable.end))); } public void click(View view) { switch (view.getId()) { case R.id.btn_home_navigatiom_bus: // 公交 // 第一個參數表示路徑規劃的起點和終點, // 第二個參數表示公交查詢模式, // 第三個參數表示公交查詢城市區號, // 第四個參數表示是否計算夜班車,0表示不計算 RouteSearch.BusRouteQuery busRouteQuery = new RouteSearch.BusRouteQuery( fromAndTo, RouteSearch.BusDefault, "北京", 0); routeSearch.calculateBusRouteAsyn(busRouteQuery); break; case R.id.btn_home_navigatiom_car: // 駕車 RouteSearch.DriveRouteQuery driveRouteQuery = new RouteSearch.DriveRouteQuery( fromAndTo, RouteSearch.DrivingDefault, null, null, ""); routeSearch.calculateDriveRouteAsyn(driveRouteQuery); break; case R.id.btn_home_navigatiom_walk: // 步行 RouteSearch.WalkRouteQuery walkRouteQuery = new RouteSearch.WalkRouteQuery( fromAndTo, RouteSearch.WalkDefault); routeSearch.calculateWalkRouteAsyn(walkRouteQuery); break; } } /** * 公交搜索方案 */ @Override public void onBusRouteSearched(BusRouteResult busRouteResult, int i) { BusPath busPath = busRouteResult.getPaths().get(0);// 取其中一個路線 aMap.clear(); BusRouteOverlay routeOverlay = new BusRouteOverlay(this, aMap, busPath, busRouteResult.getStartPos(), busRouteResult.getTargetPos()); routeOverlay.removeFromMap(); routeOverlay.addToMap(); routeOverlay.zoomToSpan(); } /** * 駕車搜索方案 */ @Override public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) { DrivePath drivePath = driveRouteResult.getPaths().get(0);// 取其中一個路線 aMap.clear(); DrivingRouteOverlay routeOverlay = new DrivingRouteOverlay(this, aMap, drivePath, driveRouteResult.getStartPos(), driveRouteResult.getTargetPos()); routeOverlay.removeFromMap(); routeOverlay.addToMap(); routeOverlay.zoomToSpan(); } /** * 步行搜索方案 */ @Override public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) { WalkPath walkPath = walkRouteResult.getPaths().get(0);// 取其中一個路線 aMap.clear();// 清除地圖上的標註之類 WalkRouteOverlay routeOverlay = new WalkRouteOverlay(this, aMap, walkPath, walkRouteResult.getStartPos(), walkRouteResult.getTargetPos()); routeOverlay.removeFromMap(); routeOverlay.addToMap(); routeOverlay.zoomToSpan(); } @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); } }
a) 佈局文件
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/btn_home_navigatiom_bus" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="click" android:text="bus" /> <Button android:id="@+id/btn_home_navigatiom_car" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="click" android:text="car" /> <Button android:id="@+id/btn_home_navigatiom_walk" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="click" android:text="walk" /> </LinearLayout> <com.amap.api.maps.MapView android:id="@+id/mapview_home_navigatiom_map" android:layout_width="match_parent" android:layout_height="match_parent" > </com.amap.api.maps.MapView> </LinearLayout>