定位上传方案

前言

定位是社交APP 中能够实时定位社交圈中各个成员的位置 后台实时上传位置则是非常重要的一个技术点

需求

1. 如果用户的位置在持续变化 则隔一段时间上报一次;

2. 如果用户的移动速度很慢 则隔一段距离上报一次;

3. 如果用户的位置在到达某处后没有变化 则不继续上报;

4. 切换到后台也要能定位上报;

准备

先去百度官网下载集成相应的sdk

http://lbsyun.baidu.com/


集成完成后


ios 的 可以  直接戳这里  http://www.cocoachina.com/ios/20150724/12735.html

个人理解IOS与Android不同的是  ios减少耗流量是监听GPS来确定是否移动位置来请求定位;


anderoid 端的 因为没法强制用户一直打开GPS (开GPS 具体耗电量与耗流量参数 

http://lbsyun.baidu.com/index.php?title=android-yingyan/guide/consumption)


Android 用户在百度定位api上暂时没有返回速度(GPS未开启时)但是百度官网给我们提供了一个计算距离工具;

public class DistanceUtil {
public DistanceUtil() {
}
/**
*注释:此方法是百度地图计算工具类里面带的
*LatLng var0 第一次定位经纬度
*LatLng var1 最新定位经纬度
*return 两者之间的距离 单位(米)
*/
public static double getDistance(LatLng var0, LatLng var1) {
if(var0 != null && var1 != null) {
Point var2 = CoordUtil.ll2point(var0);
Point var3 = CoordUtil.ll2point(var1);
return var2 != null && var3 != null?CoordUtil.getDistance(var2, var3):-1.0D;
} else {
return -1.0D;
}
}
}


所以我暂时能想到的就是写一个定时器放在服务上并设置5秒获取一次定位(单次定位耗流量0.3K,大约216K/H)

这里怎么开启定时服务暂时就不黏贴代码了 我就介绍一下怎么实现静态不动时与移动时的逻辑:

首先先写一个Model用来保存上次上传到服务端的数据

public class MapModel implements Serializable {
/**
* 经度
*/
private double longitude;
/**
* 纬度
*/
private double latitude;
/**
* 位置
*/
private String address;

/**
* 本次时间
*/
private Date time;

//get set 自己生成下就好了




然后在定位数据请求成功时  去判断两次定位间的距离 并做相应的处理;

/**
* 定位监听函数
*/
public class MyLocationListenner implements BDLocationListener {
//接收异步返回的定位结果
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null) {
Log.i("location:", "获取位置失败");
} else {
Log.i("location:", "准备提交数据...");
Log.i("location:", "在时间范围内...");
latitude = location.getLatitude();
longitude = location.getLongitude();
address = location.getAddrStr();
/**
*这个地方就是把上传到服务端时 的位置保持到 SharedPreferences 在这里取出来调用
*/
MapModel mapModel = (MapModel) AndroidUtil.getValue(LApp.getContext(), "MapModel");
if (null == mapModel) {
Log.d("location:","刚打开程序上传一次");
saveMapInfo();
} else {
if (0.0 == mapModel.getLatitude() || 0.0 == mapModel.getLongitude()) {
Log.d("location:","信息错误上传一次");
saveMapInfo();
} else {
double distance = DistanceUtil.getDistance(
getLatLng(mapModel.getLatitude(), mapModel.getLongitude()), getLatLng(latitude, longitude));
if (distance > 100) {
Log.d("location:","大于100米上传一次");
saveMapInfo();
}else {
try {
//s 是时间差
String s = TimeUtil.hoursBetween(mapModel.getTime(), new Date());
int i = Integer.parseInt(s);
//当时间差大于1小时时上传一次位置 然后重置时间
if (i>0){
saveMapInfo();
}
} catch (ParseException e) {
Log.d("location:","小于100米不上传"+e);
e.printStackTrace();
}
Log.d("location:","小于100米不上传");
}
}
}
}
}

@Override
public void onConnectHotSpotMessage(String s, int i) {

}


//接收异步返回的POI查询结果
public void onReceivePoi(BDLocation poiLocation) {
if (poiLocation == null) {
return;
}
}
}


/**
     * 解析地图坐标
     *
     * @param latitude
     * @param longitude
     * @return
     */
    private LatLng getLatLng(double latitude, double longitude) {
        return new LatLng(latitude, longitude);
    }

    /**
     * 保存位置信息 并上传到服务端
     */
    private void saveMapInfo(){
        MapModel mapModelSave = new MapModel();
        mapModelSave.setLatitude(latitude);
        mapModelSave.setLongitude(longitude);
        mapModelSave.setAddress(address);
        mapModelSave.setTime(new Date());
        AndroidUtil.setValue(LApp.getContext(), "MapModel", mapModelSave);
        upLoadData();//上传数据
    }


 
 /**  
	     * 计算两个日期之间相差的小时数  
	     * @param smdate 较小的时间 
	     * @param bdate  较大的时间 
	     * @return 相差时间 
	     * @throws ParseException  
	     */    
	    public static String hoursBetween(Date smdate,Date bdate) throws ParseException{    
	        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");  
	        smdate=sdf.parse(sdf.format(smdate));  
	        bdate=sdf.parse(sdf.format(bdate));  
	        Calendar cal = Calendar.getInstance();    
	        cal.setTime(smdate);    
	        long time1 = cal.getTimeInMillis();                 
	        cal.setTime(bdate);    
	        long time2 = cal.getTimeInMillis();         
	        long between_days=(time2-time1)/(1000*3600);  
	       return String.valueOf(between_days);           
	    }

好了 上面就是Android端一个简单 的根据时间以及位置移动来上传位置的方案


方案不是很完美  希望大家多多指出不足之处

你可能感兴趣的:(android,Android定位方案)