一、吐槽
在百度地圖看瞭幾個小時的教程,發現種種問題,很大部分是百度對於定位API 網頁上的DEMO代碼一大堆錯誤!這極可能是定位SDK升級後而網頁上的DEMO部分代碼沿用舊版導致的。
錯誤1:
在該示例中取瞭個變量叫mLocationClient,後面居然叫mLocClient,我找瞭半天,說這變量哪來的呢
錯誤2:
這個錯誤是最致命的,在網頁上的DEMO(開發指南)裡居然連開始定位這個函數至始至終都沒調用過!!!
新手咋看以為調用這個就可以定位瞭,擦,其實還應該調用mLocClient.start(); 才行,否則壓根就沒啟動定位。。。
二、使用百度地圖V2.2和定位V4.0實現地圖和定位功能
1、首先將必要的庫文件導入到你的項目裡,具體參看這裡
http://developer.baidu.com/map/sdkandev-2.htm
http://developer.baidu.com/map/geosdk-android-developv4.0.htm
2、編寫代碼 (MainActivity.java)
package com.android.test; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Menu; import android.view.MenuItem; 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.MapController; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.MyLocationOverlay; import com.baidu.platform.comapi.basestruct.GeoPoint; public class MainActivity extends Activity { //百度Key private static final String BD_KEY="請在這裡輸入你的百度地圖Key,這裡我刪除瞭我自己的,你自己填"; //地圖管理器 private BMapManager mBMapMan=null; //地圖視圖 private MapView mMapView=null; private LocationClient mLocationClient=null; //我的位置覆蓋物 private MyLocationOverlay myOverlay; //位置在圖層中的索引 private int myOverlayIndex=0; //是否定位到我的位置 private boolean bmyLocal=true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mBMapMan=new BMapManager(getApplication()); mBMapMan.init(BD_KEY, null); setContentView(R.layout.activity_main); //註意:請在試用setContentView前初始化BMapManager對象,否則會報錯 setContentView(R.layout.activity_main); mMapView=(MapView)findViewById(R.id.bmapsView); mMapView.setBuiltInZoomControls(true); //設置啟用內置的縮放控件 MapController mMapController=mMapView.getController(); // 得到mMapView的控制權,可以用它控制和驅動平移和縮放 GeoPoint point =new GeoPoint((int)(39.915* 1E6),(int)(116.404* 1E6)); //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6) mMapController.setCenter(point);//設置地圖中心點 mMapController.setZoom(12);//設置地圖zoom級別 ////////////////////////定位功能代碼開始 mLocationClient=new LocationClient(this); mLocationClient.setAK(BD_KEY); myOverlay=new MyLocationOverlay(mMapView); LocationClientOption option=new LocationClientOption(); option.setOpenGps(true); option.setAddrType("all");//返回的定位結果包含地址信息 option.setCoorType("bd09ll");//返回的定位結果是百度經緯度,默認值gcj02 //當不設此項,或者所設的整數值小於1000(ms)時,采用一次定位模式。 //option.setScanSpan(5000);//設置發起定位請求的間隔時間為5000ms option.disableCache(true);//禁止啟用緩存定位 option.setPoiNumber(5); //最多返回POI個數 option.setPoiDistance(1000); //poi查詢距離 option.setPoiExtraInfo(true); //是否需要POI的電話和地址等詳細信息 mLocationClient.setLocOption(option); //註冊位置監聽 mLocationClient.registerLocationListener(locationListener); if(mLocationClient!=null&&!mLocationClient.isStarted()) { mLocationClient.requestLocation(); mLocationClient.start(); } else Log.e("LocSDK3", "locClient is null or not started"); } private BDLocationListener locationListener=new BDLocationListener() { @Override public void onReceiveLocation(BDLocation arg0) { Dispose(arg0); } @Override public void onReceivePoi(BDLocation arg0) { Dispose(arg0); } private void Dispose(BDLocation location) { if(location==null) return; StringBuffer sb = new StringBuffer(256); sb.append("time : "); sb.append(location.getTime()); sb.append("\nerror code : "); sb.append(location.getLocType()); sb.append("\nlatitude : "); sb.append(location.getLatitude()); sb.append("\nlontitude : "); sb.append(location.getLongitude()); sb.append("\nradius : "); sb.append(location.getRadius()); if (location.getLocType() == BDLocation.TypeGpsLocation){ sb.append("\nspeed : "); sb.append(location.getSpeed()); sb.append("\nsatellite : "); sb.append(location.getSatelliteNumber()); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation){ sb.append("\naddr : "); sb.append(location.getAddrStr()); } //poiLocation if(location.hasPoi()){ sb.append("\nPoi:"); sb.append(location.getPoi()); }else{ sb.append("\nnoPoi information"); } //需要定位到我的位置? if(bmyLocal) { double lat=location.getLatitude(); double lon=location.getLongitude(); LocationData data=new LocationData(); data.latitude=lat; data.longitude=lon; data.direction=2.0f; myOverlay.setData(data); //檢查覆蓋物是否存在,存在則修改,否則則添加 if(mMapView.getOverlays().contains(myOverlay)) { mMapView.getOverlays().set(myOverlayIndex,myOverlay); } else{ myOverlayIndex=mMapView.getOverlays().size(); mMapView.getOverlays().add(myOverlay); } GeoPoint geoPoint=new GeoPoint((int)(lat* 1E6),(int)(lon* 1E6)); mMapView.getController().setCenter(geoPoint); mMapView.refresh(); bmyLocal=false; } Log.e("定位結果:",sb.toString()); } }; //創建菜單 @Override public boolean onCreateOptionsMenu(Menu menu) { //組、ID、排序、菜單名 menu.add(0,1,1,"我的位置").setIcon(R.drawable.root_icon); return true; } //處理菜單 @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case 1: //我的位置 bmyLocal=true; mLocationClient.requestLocation(); mLocationClient.start(); break; } return true; } @Override protected void onDestroy(){ if(mLocationClient!=null&&mLocationClient.isStarted()) mLocationClient.stop(); mMapView.destroy(); if(mBMapMan!=null){ mBMapMan.destroy(); mBMapMan=null; } super.onDestroy(); } @Override protected void onPause(){ mMapView.onPause(); if(mBMapMan!=null){ mBMapMan.stop(); } super.onPause(); } @Override protected void onResume(){ mMapView.onResume(); if(mBMapMan!=null){ mBMapMan.start(); } super.onResume(); } }
3、在AndroidManifest.xml裡註冊和添加權限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test" android:versionCode="1" android:versionName="1.0" > <!-- 添加屏幕及版本支持 --> <supports-screens android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:resizeable="true" android:anyDensity="true"/> <uses-sdk android:minSdkVersion="7" /> <!-- 在sdcard中創建/刪除文件的權限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 掛載和反掛載的權限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 讀取手機狀態 ,如來瞭新電話--> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 震動權限 --> <uses-permission android:name="android.permission.VIBRATE" /> <!-- 網絡訪問權限 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <!-- 百度地圖定位功能所需權限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" /> <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_GPS"/> <uses-permission android:name="android.permission.READ_LOGS" /> <application android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.Black" android:persistent="true" > <activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="portrait" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 百度定位服務 android:permission="android.permission.BAIDU_LOCATION_SERVICE">--> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"> </service> </application> </manifest>