通过工厂模式随时切换百度地图和高德地图

来源:互联网 发布:小河淌水 知乎 编辑:程序博客网 时间:2024/04/30 03:10

工作中可能会碰到这样的问题,开始已经确定了用百度地图,但是可能因为某一功能的实现需要改用高德地图。但我们没法确定后期会不会再改用百度,这就需要我们再时集成百度地图和高德地图,如果需要改动大量的代码,那就得不偿失了。工厂模式就能很好的解决这个问题。

既然是工厂模式,我们会根据传入的参数来实例化不同的对象:

public class LocationFactory implements Observer {

public static Location location;

private static LocationFactory locationFactory = new LocationFactory();

public static LocationFactory getInstance() {
return locationFactory;
}

public Location getILocation() {
return location;
}

public void init(Context context, String type) {
if ("baidu".equals(type)) {
location = new BaiduLocateManager(context,);
} else if ("amap".equals(type)) {
location = new AMapLocateManager(context,);
}
location.registerObserever(locationFactory);
}


@Override
public void update(Observable observable, Object data) {
location.update(observable, data);
}
}


既然返回的是同一个location对象,我们还需要定义一个接口,BaiduLocateManager和AMapLocateManager中同时实现这个接口。

public interface Location {

/**
* 开始定位
*/
void startLocation(boolean force);

/**
* 结束定位
*/
void stopLocation();

/**
* 注册观察者
*/
void registerObserever(Observer observer);

/**
* 注销观察者
*/
void unRegisterObserever(Observer observer);

/**
* 是否正在定位
*/
boolean isLocating();

/**
* 是否定位成功
*/
boolean isLocatingSuccess();

void update(Observable observable, Object data);
}

这里是自定义一些要用到的方法。


BaiduLocateManager和AMapLocateManager中的方法类似,这里贴个自己项目中的代码,大家作为参考:

public class AMapLocateManager extends Observable implements Location {
private static final String TAG = AMapLocateManager.class.getSimpleName();

//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new MyLocationListener();

//声明mLocationOption对象
public AMapLocationClientOption mLocationOption = null;

/**
* 一次定位使用时间
*/
private long mStartTime;

/**
* 一次定位使用时间
*/
private long mLocatingTime;

/**
* 定位成功的标志
*/
private boolean mIsSuccess;


public AMapLocateManager(Context context) {
init(context.getApplicationContext());
}

private void init(Context context) {
//初始化定位
mLocationClient = new AMapLocationClient(context);
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);

//初始化定位参数
mLocationOption = new AMapLocationClientOption();
//设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置是否返回地址信息(默认返回地址信息)
mLocationOption.setNeedAddress(true);
//设置是否只定位一次,默认为false
mLocationOption.setOnceLocation(false);
//设置是否强制刷新WIFI,默认为强制刷新
mLocationOption.setWifiActiveScan(true);
//设置是否允许模拟位置,默认为false,不允许模拟位置
mLocationOption.setMockEnable(false);
//设置定位间隔,单位毫秒,默认为2000ms
mLocationOption.setInterval(1000 * 60);
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
}

@Override
public void startLocation(boolean force) {
//启动定位
mLocationClient.startLocation();
}

@Override
public void stopLocation() {
mLocationClient.stopLocation();//停止定位
}


@Override
public void registerObserever(Observer observer) {
if (observer != null) {
addObserver(observer);
}
}

@Override
public void unRegisterObserever(Observer observer) {
if (observer != null) {
deleteObserver(observer);
}
}

@Override
public boolean isLocating() {
return mLocationClient.isStarted();
}

@Override
public boolean isLocatingSuccess() {
return mIsSuccess;
}

@Override
public void update(Observable observable, Object data) {
XAddress address = null;
if (data instanceof XAddress) {
mIsSuccess = true;
address = (XAddress) data;
address.setTimeStamp(System.currentTimeMillis());

Log.d(TAG, "----------->>> save address success! mAddress= " + address);
} else {
mIsSuccess = false;
Log.d(TAG, "-------------->>>定位失败");
}

DebugLog.d(TAG, "----------Locat finish time=" + (System.currentTimeMillis() - mLocatingTime));

EventBus.getDefault().post(address);
}

/**
* 销毁定位客户端:
* 销毁定位客户端之后,若要重新开启定位请重新New一个AMapLocationClient对象。
*/
private void destoryLocation() {
mLocationClient.onDestroy();//销毁定位客户端。
}

class MyLocationListener implements AMapLocationListener {

@Override
public void onLocationChanged(AMapLocation amapLocation) {

if (amapLocation != null) {
if (amapLocation.getErrorCode() == 0) {
//定位成功回调信息,设置相关消息
amapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表

final XAddress address = new XAddress();

double latitude = amapLocation.getLatitude();//获取纬度
if (0 != latitude) {
address.setLatitude("" + latitude);

}

double longitude = amapLocation.getLongitude();//获取经度
if (0 != longitude) {
address.setLongtitude("" + longitude);
}

amapLocation.getAccuracy();//获取精度信息
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(amapLocation.getTime());
df.format(date);//定位时间
String addressName= amapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果
amapLocation.getCountry();//国家信息
amapLocation.getProvince();//省信息
amapLocation.getCity();//城市信息
amapLocation.getDistrict();//城区信息
amapLocation.getRoad();//街道信息
amapLocation.getCityCode();//城市编码
amapLocation.getAdCode();//地区编码

if ((0 != latitude) && (0 != longitude) && (null != addressName && !"".equals(addressName.trim()))) {
 updateObserver(address);
} else {
return;
}
} else {
//显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
Log.e("AmapError", "location Error, ErrCode:"
+ amapLocation.getErrorCode() + ", errInfo:"
+ amapLocation.getErrorInfo());
}
}
}
}
/**
* 更新结果,通知给观察者
*/
public void updateObserver(Object data) {
setChanged();
notifyObservers(data);
}
}

这里同时还用到了观察者模式,这里是每隔一分钟会定位一次位置,然后调用  updateObserver的方法,通知给LocationFactory(它是观察者,实现了Observer接口),LocationFactory中的update方法去调用location.update(observable, data)。那AMapLocateManager中的update方法做了什么呢?是取到了地址信息,然后通过Eventbus发送出去,这样在需要接收的地方就可以接收到了。

在程序入口处,一般是application中调用:

//初始化位置定位的实例 amap为高德 baidu为百度地图
LocationFactory.getInstance().init(this, "amap");

这样切换就方便了,只需要改个参数就可以。


同时不要忘了在需要的地方开启定位:

Location location = LocationFactory.getInstance().getILocation();
if (location != null) {
location.startLocation(true);
}




1 0
原创粉丝点击