zoukankan      html  css  js  c++  java
  • 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)

    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("
    error code : ");
    			 sb.append(location.getLocType());
    			 sb.append("
    latitude : ");
    			 sb.append(location.getLatitude());
    			 sb.append("
    lontitude : ");
    			 sb.append(location.getLongitude());
    			 sb.append("
    radius : ");
    			 sb.append(location.getRadius());
    			 if (location.getLocType() == BDLocation.TypeGpsLocation){
    				 sb.append("
    speed : ");
    				 sb.append(location.getSpeed());
    				 sb.append("
    satellite : ");
    				 sb.append(location.getSatelliteNumber());
    			 } 
    			 else if (location.getLocType() == BDLocation.TypeNetWorkLocation){
    				 sb.append("
    addr : ");
    				 sb.append(location.getAddrStr());
    			 }
    			 //poiLocation
    			 if(location.hasPoi()){
    				 sb.append("
    Poi:");
    				 sb.append(location.getPoi());
    				 }else{
    				 sb.append("
    noPoi 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>
    


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

    然后程序效果如图:


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


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


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


  • 相关阅读:
    padding magin 盒子模型
    background元素背景--font字体
    border 边框
    浅析mvvm模式和mvc模式的区别和联系
    Win10下小米路由器4A百兆版刷Openwrt固件【图片详细版】
    Vue源码-手写mustache源码
    微信小程序支付实现流程
    Fiddler对安卓模拟器中的app抓包
    Niginx中Vue Router 历史(history)模式的配置
    ES6中Promise方法详解
  • 原文地址:https://www.cnblogs.com/phisy/p/3363274.html
Copyright © 2011-2022 走看看