使用方法:
LocationObserver observer = new LocationObserver(){
@Override
public void onReceiveLocation(BDLocation bdLocation) {
//做点啥
}
};
BDLocationUtil.rigister(getApplicationContext(),observer);
以下是BDLocationUtil类
import android.content.Context;
import android.support.annotation.NonNull;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Jack on 2016/4/16.
* 百度地图SDK工具类
*/
public class BDLocationUtil {
private static LocationClient client;
private static BDLocationListener listener;
private static Listobservers;
private static int observerCount = 0;
/**
* 关闭client,释放引用
*/
public static void close() {
client.stop();
observers = null;
listener = null;
client = null;
observerCount = 0;
}
/**
* 注册监听
*
* @param context
* @param observer
*/
public static void register(Context context, LocationObserver observer) {
if (observers == null) {
observers = new ArrayList<>();
}
if (client == null) {
client = new LocationClient(context);
client.setLocOption(getLocationOption());
}
if (listener == null) {
listener = new BDLocationListener() {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
//接收到location之后通知所有监听者
notifyObservers(bdLocation);
}
};
client.registerLocationListener(listener);
}
if (!observers.contains(observer)) {
observers.add(observer);
observerCount++;
if (observerCount == 1) {
client.start();
}
}
}
/**
* 注销监听
* @param observer
*/
public static void unRegister(LocationObserver observer) {
if (observers == null) {
return;
}
if (observers.contains(observer)) {
observers.remove(observer);
observerCount--;
if (observerCount == 0) {
client.stop();
}
}
}
/**
* 通知所有的监听者
* @param bdLocation
*/
private static void notifyObservers(BDLocation bdLocation) {
if (observers == null || observerCount < 1) {
return;
}
for (LocationObserver observer : observers) {
observer.onReceiveLocation(bdLocation);
}
}
/**
* 监听接口,实现此接口以接收location
*/
public interface LocationObserver {
void onReceiveLocation(BDLocation location);
}
/**
* @return 百度定位的Option
*/
@NonNull
private static LocationClientOption getLocationOption() {
LocationClientOption option = new LocationClientOption();
//扫描间隔,毫秒单位,0表示只扫描一次
option.setScanSpan(0);
//定位模式
//LocationClientOption.LocationMode.Battery_Saving; 省电模式
//LocationClientOption.LocationMode.Device_Sensors; 仅设备(GPS)
//LocationClientOption.LocationMode.Hight_Accuracy; 高精度模式
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
//是否需要地址
option.setIsNeedAddress(true);
//是否打开GPS
option.setOpenGps(true);
//是否需要位置描述
option.setIsNeedLocationDescribe(true);
//设置坐标类型
option.setCoorType("gcj02");
return option;
}
}
建议在Activity的onStop方法中注销监听,并在必要的地方调用BDLocationUtil的close方法。
注意最后Option中,option.setCoorType("gcj02")是中国的火星坐标系,需要转换成地球坐标系
转换坐标的工具类:
import java.util.HashMap;
import java.util.Map;
/**
* Created by Mory on 2016/4/15.
* 用于转换坐标
*/
public class CoorUtil {
private static double pi = 3.14159265358979324D;// 圆周率
private static double r = 6378245.0D;// WGS 长轴半径
private static double rate2 = 0.00669342162296594323D;// WGS 偏心率的平方
private static boolean outOfChina(double lat, double lon) {
return lon < 72.004 || lon > 137.8347 || lat < 0.8293 || lat > 55.8271;
}
private static double transformLat(double x, double y) {
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
private static double transformLon(double x, double y) {
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
private static Maptransform(double lon, double lat) {
HashMaplocalHashMap = new HashMap<>();
if (outOfChina(lat, lon)) {
localHashMap.put("lon", lon);
localHashMap.put("lat", lat);
return localHashMap;
}
double dLat = transformLat(lon - 105.0, lat - 35.0);
double dLon = transformLon(lon - 105.0, lat - 35.0);
double radLat = lat / 180.0 * pi;
double magic = Math.sin(radLat);
magic = 1 - rate2 * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((r * (1 - rate2)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (r / sqrtMagic * Math.cos(radLat) * pi);
double mgLat = lat + dLat;
double mgLon = lon + dLon;
localHashMap.put("lon", mgLon);
localHashMap.put("lat", mgLat);
return localHashMap;
}
// gcj02-84
public static Mapgcj2wgs(double lon, double lat) {
double longitude = lon - (transform(lon, lat).get("lon") - lon);
double latitude = lat - (transform(lon, lat).get("lat") - lat);
HashMapmap = new HashMap<>();
map.put("lat", latitude);
map.put("lon", longitude);
return map;
}
}