在百度地图看了几个小时的教程,发现种种问题,很大部分是百度对于定位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定位的话,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵。。。。