android使用百度地图、定位SDK实现地图和定位功能

一、吐槽

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

 

[java][/java] view plaincopy

  1. package com.android.test;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.util.Log;
  6. import android.view.Menu;
  7. import android.view.MenuItem;
  8. import com.baidu.location.BDLocation;
  9. import com.baidu.location.BDLocationListener;
  10. import com.baidu.location.LocationClient;
  11. import com.baidu.location.LocationClientOption;
  12. import com.baidu.mapapi.BMapManager;
  13. import com.baidu.mapapi.map.LocationData;
  14. import com.baidu.mapapi.map.MapController;
  15. import com.baidu.mapapi.map.MapView;
  16. import com.baidu.mapapi.map.MyLocationOverlay;
  17. import com.baidu.platform.comapi.basestruct.GeoPoint;
  18. public class MainActivity extends Activity {
  19.     //百度Key
  20.     private static final String BD_KEY=”请在这里输入你的百度地图Key,这里我删除了我自己的,你自己填”;
  21.     //地图管理器
  22.     private BMapManager mBMapMan=null;
  23.     //地图视图
  24.     private MapView mMapView=null;
  25.     private LocationClient mLocationClient=null;
  26.      //我的位置覆盖物
  27.     private MyLocationOverlay myOverlay;
  28.     //位置在图层中的索引
  29.     private int myOverlayIndex=0;
  30.     //是否定位到我的位置
  31.     private boolean bmyLocal=true;
  32.     @Override
  33.     protected void onCreate(Bundle savedInstanceState) {
  34.         super.onCreate(savedInstanceState);
  35.         mBMapMan=new BMapManager(getApplication());
  36.         mBMapMan.init(BD_KEY, null);
  37.         setContentView(R.layout.activity_main);
  38.         //注意:请在试用setContentView前初始化BMapManager对象,否则会报错
  39.         setContentView(R.layout.activity_main);
  40.         mMapView=(MapView)findViewById(R.id.bmapsView);
  41.         mMapView.setBuiltInZoomControls(true);
  42.         //设置启用内置的缩放控件
  43.         MapController mMapController=mMapView.getController();
  44.         // 得到mMapView的控制权,可以用它控制和驱动平移和缩放
  45.         GeoPoint point =new GeoPoint((int)(39.915* 1E6),(int)(116.404* 1E6));
  46.         //用给定的经纬度构造一个GeoPoint,单位是微度 (度 * 1E6)
  47.         mMapController.setCenter(point);//设置地图中心点
  48.         mMapController.setZoom(12);//设置地图zoom级别
  49.         ////////////////////////定位功能代码开始
  50.         mLocationClient=new LocationClient(this);
  51.         mLocationClient.setAK(BD_KEY);
  52.         myOverlay=new MyLocationOverlay(mMapView);
  53.         LocationClientOption option=new LocationClientOption();
  54.         option.setOpenGps(true);
  55.         option.setAddrType(“all”);//返回的定位结果包含地址信息
  56.         option.setCoorType(“bd09ll”);//返回的定位结果是百度经纬度,默认值gcj02
  57.         //当不设此项,或者所设的整数值小于1000(ms)时,采用一次定位模式。
  58.         //option.setScanSpan(5000);//设置发起定位请求的间隔时间为5000ms
  59.         option.disableCache(true);//禁止启用缓存定位
  60.         option.setPoiNumber(5); //最多返回POI个数
  61.         option.setPoiDistance(1000); //poi查询距离
  62.         option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息
  63.         mLocationClient.setLocOption(option);
  64.         //注册位置监听
  65.         mLocationClient.registerLocationListener(locationListener);
  66.         if(mLocationClient!=null&&!mLocationClient.isStarted())
  67.         {
  68.             mLocationClient.requestLocation();
  69.             mLocationClient.start();
  70.         }
  71.         else
  72.             Log.e(“LocSDK3”, “locClient is null or not started”);
  73.     }
  74.     private BDLocationListener locationListener=new BDLocationListener()
  75.     {
  76.         @Override
  77.         public void onReceiveLocation(BDLocation arg0) {
  78.             Dispose(arg0);
  79.         }
  80.         @Override
  81.         public void onReceivePoi(BDLocation arg0) {
  82.             Dispose(arg0);
  83.         }
  84.         private void Dispose(BDLocation location)
  85.         {
  86.             if(location==null)
  87.                 return;
  88.              StringBuffer sb = new StringBuffer(256);
  89.              sb.append(“time : “);
  90.              sb.append(location.getTime());
  91.              sb.append(“\nerror code : “);
  92.              sb.append(location.getLocType());
  93.              sb.append(“\nlatitude : “);
  94.              sb.append(location.getLatitude());
  95.              sb.append(“\nlontitude : “);
  96.              sb.append(location.getLongitude());
  97.              sb.append(“\nradius : “);
  98.              sb.append(location.getRadius());
  99.              if (location.getLocType() == BDLocation.TypeGpsLocation){
  100.                  sb.append(“\nspeed : “);
  101.                  sb.append(location.getSpeed());
  102.                  sb.append(“\nsatellite : “);
  103.                  sb.append(location.getSatelliteNumber());
  104.              }
  105.              else if (location.getLocType() == BDLocation.TypeNetWorkLocation){
  106.                  sb.append(“\naddr : “);
  107.                  sb.append(location.getAddrStr());
  108.              }
  109.              //poiLocation
  110.              if(location.hasPoi()){
  111.                  sb.append(“\nPoi:”);
  112.                  sb.append(location.getPoi());
  113.                  }else{
  114.                  sb.append(“\nnoPoi information”);
  115.             }
  116.              //需要定位到我的位置?
  117.              if(bmyLocal)
  118.              {
  119.                  double lat=location.getLatitude();
  120.                  double lon=location.getLongitude();
  121.                  LocationData data=new LocationData();
  122.                  data.latitude=lat;
  123.                  data.longitude=lon;
  124.                  data.direction=2.0f;
  125.                  myOverlay.setData(data);
  126.                  //检查覆盖物是否存在,存在则修改,否则则添加
  127.                  if(mMapView.getOverlays().contains(myOverlay))
  128.                  {
  129.                      mMapView.getOverlays().set(myOverlayIndex,myOverlay);
  130.                  }
  131.                  else{
  132.                      myOverlayIndex=mMapView.getOverlays().size();
  133.                      mMapView.getOverlays().add(myOverlay);
  134.                  }
  135.                  GeoPoint geoPoint=new GeoPoint((int)(lat* 1E6),(int)(lon* 1E6));
  136.                  mMapView.getController().setCenter(geoPoint);
  137.                  mMapView.refresh();
  138.                  bmyLocal=false;
  139.              }
  140.              Log.e(“定位结果:”,sb.toString());
  141.         }
  142.     };
  143.     //创建菜单
  144.         @Override
  145.         public boolean onCreateOptionsMenu(Menu menu)
  146.         {
  147.             //组、ID、排序、菜单名
  148.             menu.add(0,1,1,”我的位置”).setIcon(R.drawable.root_icon);
  149.             return true;
  150.         }
  151.         //处理菜单
  152.         @Override
  153.         public boolean onOptionsItemSelected(MenuItem item)
  154.         {
  155.             switch(item.getItemId())
  156.             {
  157.             case 1:  //我的位置
  158.                 bmyLocal=true;
  159.                 mLocationClient.requestLocation();
  160.                 mLocationClient.start();
  161.                 break;
  162.             }
  163.             return true;
  164.         }
  165.         @Override
  166.         protected void onDestroy(){
  167.                 if(mLocationClient!=null&&mLocationClient.isStarted())
  168.                     mLocationClient.stop();
  169.                 mMapView.destroy();
  170.                 if(mBMapMan!=null){
  171.                         mBMapMan.destroy();
  172.                         mBMapMan=null;
  173.                 }
  174.                 super.onDestroy();
  175.         }
  176.         @Override
  177.         protected void onPause(){
  178.                 mMapView.onPause();
  179.                 if(mBMapMan!=null){
  180.                        mBMapMan.stop();
  181.                 }
  182.                 super.onPause();
  183.         }
  184.         @Override
  185.         protected void onResume(){
  186.                 mMapView.onResume();
  187.                 if(mBMapMan!=null){
  188.                         mBMapMan.start();
  189.                 }
  190.                super.onResume();
  191.         }
  192. }

 

3、在AndroidManifest.xml里注册和添加权限

 

[html][/html] view plaincopy

  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <manifest xmlns:android=”http://schemas.android.com/apk/res/android”
  3.     package=”com.android.test”
  4.     android:versionCode=”1″
  5.     android:versionName=”1.0″
  6.     >
  7.     <!– 添加屏幕及版本支持 –>
  8.     <supports-screens android:largeScreens=”true”
  9.                 android:normalScreens=”true”
  10.                 android:smallScreens=”true”
  11.                 android:resizeable=”true”
  12.                 android:anyDensity=”true”/>
  13.     <uses-sdk android:minSdkVersion=”7″ />
  14.    <!– 在sdcard中创建/删除文件的权限 –>
  15.     <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />
  16.     <!– 挂载和反挂载的权限 –>
  17.     <uses-permission android:name=”android.permission.MOUNT_UNMOUNT_FILESYSTEMS” />
  18.     <!– 读取手机状态 ,如来了新电话–>
  19.     <uses-permission android:name=”android.permission.READ_PHONE_STATE” />
  20.     <!– 震动权限 –>
  21.     <uses-permission android:name=”android.permission.VIBRATE” />
  22.     <!– 网络访问权限 –>
  23.     <uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />
  24.     <uses-permission android:name=”android.permission.ACCESS_WIFI_STATE” />
  25.     <uses-permission android:name=”android.permission.CHANGE_WIFI_STATE” />
  26.     <uses-permission android:name=”android.permission.INTERNET” />
  27.     <!– 百度地图定位功能所需权限 –>
  28.     <uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” />
  29.     <permission android:name=”android.permission.BAIDU_LOCATION_SERVICE” />
  30.     <uses-permission android:name=”android.permission.BAIDU_LOCATION_SERVICE” />
  31.     <uses-permission android:name=”android.permission.ACCESS_COARSE_LOCATION” />
  32.     <uses-permission android:name=”android.permission.ACCESS_MOCK_LOCATION” />
  33.     <uses-permission android:name=”android.permission.ACCESS_GPS”/>
  34.     <uses-permission android:name=”android.permission.READ_LOGS” />
  35.     <application
  36.         android:allowBackup=”true”
  37.         android:icon=”@drawable/icon”
  38.         android:label=”@string/app_name”
  39.         android:theme=”@android:style/Theme.Black”
  40.         android:persistent=”true” >
  41.         <activity
  42.             android:name=”.MainActivity”
  43.             android:label=”@string/app_name”
  44.             android:screenOrientation=”portrait”
  45.             >
  46.             <intent-filter>
  47.                   <action android:name=”android.intent.action.MAIN” />
  48.                    <category android:name=”android.intent.category.LAUNCHER” />
  49.             </intent-filter>
  50.         </activity>
  51.         <!– 百度定位服务    android:permission=”android.permission.BAIDU_LOCATION_SERVICE”>–>
  52.         <service android:name=”com.baidu.location.f” android:enabled=”true” android:process=”:remote”>
  53.         </service>
  54.     </application>
  55. </manifest>

 

上述代码个人做了些删除和修改,代码只包含主要的,如果有问题,请酌情修改配置即可。

然后程序效果如图:

 

百度定位号称使用GPS、网络定位(WIFI、基站)混合定位模式,现在我使用的是移动的2G手机网络,定位结果偏差还是很大的,因为它使用的基站定位,意思就是需找到了我手机发送信号的基站(信号塔)的位置,偏差至少500米,实际上我应该在紫薇北路附近。

 

但是当打开WIFI去定位,发现很准确,误差在50米以内!所以如果你在外面逛的话,建议打开WIFI联网,进行定位,效果更可靠。

 

如果你使用GPS定位的话,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵。。。。

标签