android使用百度地图、定位SDK实现地图和定位功能!(最新、可用+吐槽)

----------------------------以下是4.1的定位使用方法--------------------

主要代码!!!!!!!!!!!!!!


        //百度定位服务
    private LocationClient locationClient;   

        locationClient=new LocationClient(context);
        LocationClientOption option=new LocationClientOption();
        option.setOpenGps(true);
        option.setIsNeedAddress(true);//返回的定位结果包含地址信息
        option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02
        option.setScanSpan(10000);  //当不设此项,或者所设的整数值小于1000(ms)时,采用一次定位模式。
        locationClient.setLocOption(option);
        locationClient.registerLocationListener(locationListener);  //设置监听
        locationClient.start();


  //百度定位监听器(回调函数)
    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");
            }
            
               Log.e("定位结果:",sb.toString());
            }
        };

  • 设置AccessKey,在application标签中加入
  1. <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="key"/> //key:开发者申请的key
如:

<manifest>

   <application>

       //省略。。。。。。。。。。。。。。。。。。。。。

        <!-- 百度定位KEY -->
        <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="KEYXXXXX"/>
    </application>
</manifest>

-------------------------------以下是4.0版的定位和2.X的地图---------------------------------------

一、吐槽

在百度地图看了几个小时的教程,发现种种问题,很大部分是百度对于定位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、创建布局文件layout/activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

   <com.baidu.mapapi.map.MapView 
       android:id="@+id/bmapsView"  
       android:layout_width="fill_parent"  
       android:layout_height="fill_parent"  
       android:clickable="true" />  
</RelativeLayout>


3、编写代码 (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);
		//在setContentView之前必须先初始化百度地图!!切记
		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;
				 //如果客户端定位服务已经启动过了,则直接发起定位请求
				 if(mLocationClient!=null&&mLocationClient.isStarted())
				 {
				   mLocationClient.requestLocation();
				 }
				 else{
				   //启动定位服务,启动的时候会自动发起定位请求,默认为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();  
	    }  
}

4、在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定位的话,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵,呵呵。。。。


原文地址:https://www.cnblogs.com/xieyuan/p/3787352.html