当然,似乎这个也没有什么新意,小编也只是将官网的示例稍作整合。
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());这个,会出现什么呢?
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.
最后附上小编下载的和项目中的结构
当然,开发包我没有下载完,只是选择了定位SDK和基础地图,检索功能,因为小编后续要用到这些。
所以,根据需求下载就没有问题滴。本来之前用过百度地图开发,那要回溯到几个月前了,现在的地图更改了一下东东,所以就
留下这篇blog,大家一起研究研究。