在百度地圖看了幾個小時的教程,發現種種問題,很大部分是百度對於定位API 網頁上的DEMO代碼一大堆錯誤!這很可能是定位SDK升級後而網頁上的DEMO部分代碼沿用舊版致使的。html
在該示例中取了個變量叫mLocationClient,後面竟然叫mLocClient,我找了半天,說這變量哪來的呢java
這個錯誤是最致命的,在網頁上的DEMO(開發指南)裏竟然連開始定位這個函數至始至終都沒調用過!!!android
新手咋看覺得調用這個就能夠定位了,擦,其實還應該調用mLocClient.start(); 才行,不然壓根就沒啓動定位。。。git
http://developer.baidu.com/map/sdkandev-2.htm
api
http://developer.baidu.com/map/geosdk-android-developv4.0.htm緩存
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(); } }
<?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>
上述代碼我的作了些刪除和修改,代碼只包含主要的,若是有問題,請酌情修改配置便可。網絡
而後程序效果如圖:app
百度定位號稱使用GPS、網絡定位(WIFI、基站)混合定位模式,如今我使用的是移動的2G手機網絡,定位結果誤差仍是很大的,由於它使用的基站定位,意思就是需找到了我手機發送信號的基站(信號塔)的位置,誤差至少500米,實際上我應該在紫薇北路附近。ide
可是當打開WIFI去定位,發現很準確,偏差在50米之內!因此若是你在外面逛的話,建議打開WIFI聯網,進行定位,效果更可靠。函數
若是你使用GPS定位的話,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵。。。。