Android百度地图使用之定位和地理、反地理编码

当然,似乎这个也没有什么新意,小编也只是将官网的示例稍作整合。

PS:百度地图定位在线API<-点击即可进入查询

PS:百度地图普通地图API<-这出现在这里,主要是因为这里使用的地理编码和反地理编码是从里面取材的

嘻嘻,那么我们开始吧

定位原理我就不扯了,就是GPS,WIFI,基站等定位方式.具体优劣大家百度吧。嘻嘻... ...

需求:实现定位,获取地理位置信息

准备工作:

打开百度地图->进入地图API->创建应用->申请Key->下载SDK

IOS调用百度地图V2.3.0 <---如果是iOS开发,请移步到这个地址,当然了,如果key申请有误,也请移步到这里,因为申请Key步骤都一样。

当然,如果还没有好,那么移步到:百度介绍Android申请Key.

直接上代码可好?这样记录得更详细

package com.napoleonbai.baidu_map;

import java.util.HashMap;
import java.util.Map;

import com.baidu.mapapi.SDKInitializer;
import com.napoleonbai.baidu_map.LocationUtils.OnResultMapListener;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

/**
 * 此类提供测试,没有其他作用
 * 
 * @author NapoleonBai
 *
 */
public class MainActivity extends Activity implements OnResultMapListener {

	private LocationUtils mLocationUtils;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 初始化地图SDK<最好放置在Application中>
		SDKInitializer.initialize(getApplicationContext());
		// 创建定位管理信息对象
		mLocationUtils = new LocationUtils(getApplicationContext());
		setContentView(R.layout.activity_main);
		// 开启定位
		mLocationUtils.startLocation();
		mLocationUtils.registerOnResult(this);

		mLocationUtils.getLocation("广安", "邓小平故居");
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	// 存储地址信息
	private Map resultMap = new HashMap();

	@Override
	public void onReverseGeoCodeResult(Map map) {
		resultMap = map;
		Log.i("data", "result====>" + resultMap.toString());
	}

	@Override
	public void onGeoCodeResult(Map map) {
		Log.i("data", "result====>" + map.toString());
	}
}
这个类其实也没有什么作用,只是模拟的一个界面,值得注意的是这个

	// 初始化地图SDK<最好放置在Application中>
	SDKInitializer.initialize(getApplicationContext());

开发的时候只要把这句加载在Application中就可以了,就不用担心没有初始化了,在这里,主要是为了使用地理编码和反地理编码才使用的这个。

然后,就是LocationUtils这个类是小编封装的专门用来定位和地理编码以及反地理编码的类,具体操作如下

package com.napoleonbai.baidu_map;

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.text.TextUtils;

import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.geocode.GeoCodeOption;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.napoleonbai.baidu_map.MyLocationListener.OnLocationResultListener;

/**
 * 处理定位信息实体类
 * 
 * @author NapoleonBai
 *
 */
public class LocationUtils implements OnLocationResultListener {

	// 客户端定位对象
	private LocationClient mLocationClient;
	// 地址位置监听对象
	private MyLocationListener myListener = new MyLocationListener();
	// 用来存储获取的定位信息
	private Map map = new HashMap();
	// 获取反地理编码对象
	private GeoCoder mGeoCoder = GeoCoder.newInstance();

	public LocationUtils(Context context) {
		mLocationClient = new LocationClient(context); // 声明LocationClient类
		mLocationClient.registerLocationListener(myListener); // 注册监听函数
		setLocationOptions();
	};

	/**
	 * 设置定位参数
	 */
	private void setLocationOptions() {
		LocationClientOption option = new LocationClientOption();
		// 设置定位模式为高精度
		option.setLocationMode(LocationMode.Hight_Accuracy);
		// 返回的定位结果是百度经纬度,默认值gcj02
		option.setCoorType("bd09ll");
		// 设置发起定位请求的间隔时间为5000ms
		option.setScanSpan(5000);
		// 返回的定位结果包含地址信息
		option.setIsNeedAddress(true);
		// 返回的定位结果包含手机机头的方向
		option.setNeedDeviceDirect(true);
		// 打开GPS
		option.setOpenGps(true);
		mLocationClient.setLocOption(option);
		// 注册信息监听对象
		myListener.registerOnLocationResultListener(this);
	}

	/**
	 * 开始定位
	 */
	public void startLocation() {
		mLocationClient.start();
	}

	/**
	 * 停止定位
	 */
	public void stopLocation() {
		mLocationClient.stop();
	}

	@Override
	public void onResultData(Map map) {
		// 如果返回了结果呢,就停止定位了
		stopLocation();
		this.map = map;
		// 如果没有获取到
		if (!map.keySet().contains("address")) {
			// 传入经纬度
			getAddress(Double.parseDouble(map.get("latitude").toString()),
					Double.parseDouble(map.get("lontitude").toString()));
		} else {
			if (mOnResultMapListener != null) {
				mOnResultMapListener.onGeoCodeResult(map);
			}
		}
	}

	/**
	 * 进行反地理编码
	 * 
	 * @param latitude
	 *            纬度信息
	 * @param lontitude
	 *            经度信息
	 */
	public void getAddress(double latitude, double lontitude) {
		LatLng mLatLng = new LatLng(latitude, lontitude);
		// 反地理编码请求参数对象
		ReverseGeoCodeOption mReverseGeoCodeOption = new ReverseGeoCodeOption();
		// 设置请求参数
		mReverseGeoCodeOption.location(mLatLng);
		// 发起反地理编码请求(经纬度->地址信息)
		mGeoCoder.reverseGeoCode(mReverseGeoCodeOption);

		// 设置查询结果监听者
		mGeoCoder.setOnGetGeoCodeResultListener(mOnGetGeoCoderResultListener);
	}

	/**
	 * 根据城市,地址信息进行地理编码
	 * 
	 * @param city
	 *            城市,不能为null
	 * @param address
	 *            详细地址,不为null
	 */
	public void getLocation(String city, String address) {
		if (TextUtils.isEmpty(city) || TextUtils.isEmpty(address)) {
			return;
		}
		GeoCodeOption mGeoCodeOption = new GeoCodeOption();
		mGeoCodeOption.address(address);
		mGeoCodeOption.city(city);
		mGeoCoder.geocode(mGeoCodeOption);
		// 设置查询结果监听者
		mGeoCoder.setOnGetGeoCodeResultListener(mOnGetGeoCoderResultListener);
	}

	/**
	 * 编码查询结果监听者
	 */
	private OnGetGeoCoderResultListener mOnGetGeoCoderResultListener = new OnGetGeoCoderResultListener() {

		@Override
		public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
			// 反地理编码查询结果回调函数
			// 将地理位置信息载入到集合中
			map.put("address", result.getAddress());
			if (mOnResultMapListener != null) {
				mOnResultMapListener.onReverseGeoCodeResult(map);
			}
		}

		@Override
		public void onGetGeoCodeResult(GeoCodeResult result) {
			// 地理编码查询结果回调函数
			Map map = new HashMap();
			map.put("latitude", result.getLocation().latitude);
			map.put("longitude", result.getLocation().longitude);
			map.put("address", result.getAddress());
			if (mOnResultMapListener != null) {
				mOnResultMapListener.onGeoCodeResult(map);
			}
		}
	};

	/**
	 * 释放资源
	 */
	public void onDestory() {
		// 释放该地理编码查询对象
		mGeoCoder.destroy();
	}

	/**
	 * 注册结果监听回调
	 * 
	 * @param mOnResultMapListener
	 */
	public void registerOnResult(OnResultMapListener mOnResultMapListener) {
		this.mOnResultMapListener = mOnResultMapListener;
	}

	private OnResultMapListener mOnResultMapListener;

	/**
	 * 数据结果回传
	 * 
	 * @author NapoleonBai
	 *
	 */
	public interface OnResultMapListener {
		/**
		 * 反地理编码执行回传
		 * 
		 * @param map
		 */
		public void onReverseGeoCodeResult(Map map);

		/**
		 * 地理编码执行回传
		 * 
		 * @param map
		 */
		public void onGeoCodeResult(Map map);
	}
}

这个类基本上就形成了定位,地理编码和反地理编码的一体。注意的是,地理编码的时候,必须提供一个城市和详细地理信息,才能得到对于的经纬度坐标,否则不予

请求。

这里提供的接口就是MainActivity中使用的回传结果接口,当然了,本来还实现了一个接口,这个接口是什么呢?

我们现在就来看看:

package com.napoleonbai.baidu_map;

import java.util.HashMap;
import java.util.Map;

import android.util.Log;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;

/**
 * 实现BDLocationListener,获取地理位置信息
 * 
 * @author NapoleonBai
 *
 */
public class MyLocationListener implements BDLocationListener {
	@Override
	public void onReceiveLocation(BDLocation location) {
		if (location == null) {
			return;
		}
		// 存储地理位置信息
		Map map = new HashMap();
		map.put("time", location.getTime());// 定位时间
		map.put("loc_type", location.getLocType());// 定位方式
		map.put("latitude", location.getLatitude());// 纬度
		map.put("lontitude", location.getLongitude());// 经度
		map.put("radius", location.getRadius());// 定位精度
		map.put("city", location.getCity());// 获取城市
		map.put("street", location.getStreet());// 获取街道信息
		// 如果是GPS定位
		if (location.getLocType() == BDLocation.TypeGpsLocation) {
			// 定位速度
			map.put("speed", location.getSpeed());
			// 获取锁定的卫星数
			map.put("satellite", location.getSatelliteNumber());
		} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
			// 如果是网络定位
			// 获取地址信息
			map.put("address", location.getAddrStr());
		}
		Log.i("data", map.toString());
		if (mOnLocationResultListener != null) {
			mOnLocationResultListener.onResultData(map);
		}
	}

	// 委托接口
	private OnLocationResultListener mOnLocationResultListener;

	/**
	 * 注册委托接口事件
	 * 
	 * @param mOnLocationResultListener
	 */
	public void registerOnLocationResultListener(
			OnLocationResultListener mOnLocationResultListener) {
		this.mOnLocationResultListener = mOnLocationResultListener;
	}

	/**
	 * 获取地址信息接口
	 * 
	 * @author NapoleonBai
	 *
	 */
	public interface OnLocationResultListener {
		public void onResultData(Map map);
	}
}

这是获取地理位置的专用类,如果没有信息,将不执行回传。

当然,这里的接口是回传给LocationUtils调用的接口,里面的参数就是地理位置信息参数。

基本上到这里就结束了

由于小编使用的是手机,所以定位信息就把小编暴露了,所以,就只上一张地理编码的图哈。

哦,对了,忘记了上主配置文件




    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
         
        
            
                

                
            
        

        
        
    


注意:

 

这个name不变,是人家固定的,value则是自己申请的拿个了,由于小编这个没啥用,就做个示范。

当然了,还有一个需要注意:

这个权限一定要加上去,这是修改删除launcher.db内容的权限,这是因为SDKInitializer.initialize(getApplicationContext());初始化的需要

当然了,如果使用地理、反地理编码不初始化SDKInitializer.initialize(getApplicationContext());这个,会出现什么呢?

Android百度地图使用之定位和地理、反地理编码_第1张图片

12-04 16:29:10.671: E/AndroidRuntime(28791): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.napoleonbai.baidu_map/com.napoleonbai.baidu_map.MainActivity}: java.lang.IllegalStateException: you have not supplyed the global app context info from SDKInitializer.initialize(Context) function.

没错,就是这个提醒,所以,遇到了不要惊慌。当然,没有加权限也会提醒的。嘻嘻。。。

最后附上小编下载的和项目中的结构

Android百度地图使用之定位和地理、反地理编码_第2张图片

Android百度地图使用之定位和地理、反地理编码_第3张图片

当然,开发包我没有下载完,只是选择了定位SDK和基础地图,检索功能,因为小编后续要用到这些。

所以,根据需求下载就没有问题滴。本来之前用过百度地图开发,那要回溯到几个月前了,现在的地图更改了一下东东,所以就

留下这篇blog,大家一起研究研究。


你可能感兴趣的:(Android扩展)