android中使用百度定位sdk实时的计算移动距离
; //5秒刷新一次
下面是LocationService中的代码,即配置的百度定位sdk代码块,放在继承了service的类中 LocationService.java (方便程序在后台实时更新经纬度)
- package app.service;
- import java.util.concurrent.Callable;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import app.db.DistanceInfoDao;
- import app.model.GpsLocation;
- import app.model.DistanceInfo;
- import app.ui.MyApplication;
- import app.utils.BDLocation2GpsUtil;
- import app.utils.FileUtils;
- import app.utils.LogUtil;
- import com.baidu.location.BDLocation;
- import com.baidu.location.BDLocationListener;
- import com.baidu.location.LocationClient;
- import com.baidu.location.LocationClientOption;
- import com.computedistance.DistanceComputeInterface;
- import com.computedistance.impl.DistanceComputeImpl;
- public class LocationService extends Service {
- public static final String FILE_NAME = "log.txt"; //日志
- LocationClient mLocClient;
- private Object lock = new Object();
- private volatile GpsLocation prevGpsLocation = new GpsLocation(); //定位数据
- private volatile GpsLocation currentGpsLocation = new GpsLocation();
- private MyLocationListenner myListener = new MyLocationListenner();
- private volatile int discard = 1; //Volatile修饰的成员变量在每次被线程訪问时,都强迫从共享内存中重读该成员变量的值。
- private DistanceInfoDao mDistanceInfoDao;
- private ExecutorService executor = Executors.newSingleThreadExecutor();
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- mDistanceInfoDao = new DistanceInfoDao(this); //初始化数据库
- //LogUtil.info(LocationService.class, "Thread id ----------->:" + Thread.currentThread().getId());
- mLocClient = new LocationClient(this);
- mLocClient.registerLocationListener(myListener);
- //定位參数设置
- LocationClientOption option = new LocationClientOption();
- option.setCoorType("bd09ll"); //返回的定位结果是百度经纬度,默认值gcj02
- option.setAddrType("all"); //返回的定位结果包括地址信息
- option.setScanSpan(5000); //设置发起定位请求的间隔时间为5000ms
- option.disableCache(true); //禁止启用缓存定位
- option.setProdName("app.ui.activity");
- option.setOpenGps(true);
- option.setPriority(LocationClientOption.GpsFirst); //设置GPS优先
- mLocClient.setLocOption(option);
- mLocClient.start();
- mLocClient.requestLocation();
- }
- @Override
- @Deprecated
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (null != mLocClient) {
- mLocClient.stop();
- }
- startService(new Intent(this, LocationService.class));
- }
- private class Task implements Callable<String>{
- private BDLocation location;
- public Task(BDLocation location){
- this.location = location;
- }
- /**
- * 检測是否在原地不动
- *
- * @param distance
- * @return
- */
- private boolean noMove(float distance){
- if (distance < 0.01) {
- return true;
- }
- return false;
- }
- /**
- * 检測是否在正确的移动
- *
- * @param distance
- * @return
- */
- private boolean checkProperMove(float distance){
- if(distance <= 0.1 * discard){
- return true;
- }else{
- return false;
- }
- }
- /**
- * 检測获取的数据是否是正常的
- *
- * @param location
- * @return
- */
- private boolean checkProperLocation(BDLocation location){
- if (location != null && location.getLatitude() != 0 && location.getLongitude() != 0){
- return true;
- }
- return false;
- }
- @Override
- public String call() throws Exception {
- synchronized (lock) {
- if (!checkProperLocation(location)){
- LogUtil.info(LocationService.class, "location data is null");
- discard++;
- return null;
- }
- if (MyApplication.orderDealInfoId != -1) {
- DistanceInfo mDistanceInfo = mDistanceInfoDao.getById(MyApplication.orderDealInfoId); //依据MainActivity中赋值的全局id查询数据库的值
- if(mDistanceInfo != null) //不为空则说明车已经開始行使,并能够获得经纬度。计算移动距离
- {
- LogUtil.info(LocationService.class, "行驶中......");
- GpsLocation tempGpsLocation = BDLocation2GpsUtil.convertWithBaiduAPI(location); //位置转换
- if (tempGpsLocation != null) {
- currentGpsLocation = tempGpsLocation;
- }else{
- discard ++;
- }
- //日志
- String logMsg = "(plat:--->" + prevGpsLocation.lat + " plgt:--->" + prevGpsLocation.lng +")\n" +
- "(clat:--->" + currentGpsLocation.lat + " clgt:--->" + currentGpsLocation.lng + ")";
- LogUtil.info(LocationService.class, logMsg);
- /** 计算距离 */
- float distance = 0.0f;
- DistanceComputeInterface distanceComputeInterface = DistanceComputeImpl.getInstance(); //计算距离类对象
- distance = (float) distanceComputeInterface.getLongDistance(prevGpsLocation.lat,prevGpsLocation.lng,
- currentGpsLocation.lat,currentGpsLocation.lng); //移动距离计算
- if (!noMove(distance)) { //是否在移动
- if (checkProperMove(distance)) { //合理的移动
- float drivedDistance = mDistanceInfo.getDistance();
- mDistanceInfo.setDistance(distance + drivedDistance); //拿到数据库原始距离值, 加上当前值
- mDistanceInfo.setLongitude(currentGpsLocation.lng); //经度
- mDistanceInfo.setLatitude(currentGpsLocation.lat); //纬度
- //日志记录
- FileUtils.saveToSDCard(FILE_NAME,"移动距离--->:"+distance+drivedDistance+"\n"+"数据库中保存的距离"+mDistanceInfo.getDistance());
- mDistanceInfoDao.updateDistance(mDistanceInfo);
- discard = 1;
- }
- }
- prevGpsLocation = currentGpsLocation;
- }
- }
- return null;
- }
- }
- }
- /**
- * 定位SDK监听函数
- */
- public class MyLocationListenner implements BDLocationListener {
- @Override
- public void onReceiveLocation(BDLocation location) {
- executor.submit(new Task(location));
- LogUtil.info(LocationService.class, "经度:"+location.getLongitude());
- LogUtil.info(LocationService.class, "纬度:"+location.getLatitude());
- //将经纬度保存于全局变量,在MainActivity中点击button时初始化数据库字段
- if(MyApplication.lng <=0 && MyApplication.lat <= 0)
- {
- MyApplication.lng = location.getLongitude();
- MyApplication.lat = location.getLatitude();
- }
- }
- public void onReceivePoi(BDLocation poiLocation) {
- if (poiLocation == null){
- return ;
- }
- }
- }
- }
; //数据库版本
下面是应用中须要使用的数据库业务逻辑封装类 DistanceInfoDao.java
- package app.db;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import app.model.DistanceInfo;
- import app.utils.LogUtil;
- public class DistanceInfoDao {
- private DBOpenHelper helper;
- private SQLiteDatabase db;
- public DistanceInfoDao(Context context) {
- helper = new DBOpenHelper(context);
- }
- public void insert(DistanceInfo mDistanceInfo) {
- if (mDistanceInfo == null) {
- return;
- }
- db = helper.getWritableDatabase();
- String sql = "INSERT INTO milestone(distance,longitude,latitude) VALUES('"+ mDistanceInfo.getDistance() + "','"+ mDistanceInfo.getLongitude() + "','"+ mDistanceInfo.getLatitude() + "')";
- LogUtil.info(DistanceInfoDao.class, sql);
- db.execSQL(sql);
- db.close();
- }
- public int getMaxId() {
- db = helper.getReadableDatabase();
- Cursor cursor = db.rawQuery("SELECT MAX(id) as id from milestone",null);
- if (cursor.moveToFirst()) {
- return cursor.getInt(cursor.getColumnIndex("id"));
- }
- return -1;
- }
- /**
- * 加入数据
- * @param orderDealInfo
- * @return
- */
- public synchronized int insertAndGet(DistanceInfo mDistanceInfo) {
- int result = -1;
- insert(mDistanceInfo);
- result = getMaxId();
- return result;
- }
- /**
- * 依据id获取
- * @param id
- * @return
- */
- public DistanceInfo getById(int id) {
- db = helper.getReadableDatabase();
- Cursor cursor = db.rawQuery("SELECT * from milestone WHERE id = ?",new String[] { String.valueOf(id) });
- DistanceInfo mDistanceInfo = null;
- if (cursor.moveToFirst()) {
- mDistanceInfo = new DistanceInfo();
- mDistanceInfo.setId(cursor.getInt(cursor.getColumnIndex("id")));
- mDistanceInfo.setDistance(cursor.getFloat(cursor.getColumnIndex("distance")));
- mDistanceInfo.setLongitude(cursor.getFloat(cursor.getColumnIndex("longitude")));
- mDistanceInfo.setLatitude(cursor.getFloat(cursor.getColumnIndex("latitude")));
- }
- cursor.close();
- db.close();
- return mDistanceInfo;
- }
- /**
- * 更新距离
- * @param orderDealInfo
- */
- public void updateDistance(DistanceInfo mDistanceInfo) {
- if (mDistanceInfo == null) {
- return;
- }
- db = helper.getWritableDatabase();
- String sql = "update milestone set distance="+ mDistanceInfo.getDistance() +",longitude="+mDistanceInfo.getLongitude()+",latitude="+mDistanceInfo.getLatitude()+" where id = "+ mDistanceInfo.getId();
- LogUtil.info(DistanceInfoDao.class, sql);
- db.execSQL(sql);
- db.close();
- }
- }
下面是须要使用到的实体类 DistanceInfo.java (set数据到相应变量,以实体类作为參数更新数据库)
- package app.model;
- public class DistanceInfo {
- private int id;
- private float distance;
- private double longitude;
- private double latitude;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public float getDistance() {
- return distance;
- }
- public void setDistance(float distance) {
- this.distance = distance;
- }
- public double getLongitude() {
- return longitude;
- }
- public void setLongitude(double longitude) {
- this.longitude = longitude;
- }
- public double getLatitude() {
- return latitude;
- }
- public void setLatitude(double latitude) {
- this.latitude = latitude;
- }
- @Override
- public String toString() {
- return "DistanceInfo [id=" + id + ", distance=" + distance
- + ", longitude=" + longitude + ", latitude=" + latitude + "]";
- }
- }
* lBdLocation.getLongitude() - lng;
须要声明相关权限,且项目中所用到的jar有:
android-support-v4.jar
commons-codec.jar
commons-lang3-3.0-beta.jar
javabase64-1.3.1.jar
locSDK_3.1.jar
项目中眼下尚有部分不健全的地方。如:
1.在行驶等待时间较长后。使用TimerTask 、Handler刷新界面是偶尔会出现卡住的现象,车仍在行驶。
可是数据不动了,通过改善眼下測试近7次未出现此问题。
2.较快的消耗电量
【转载注明gao_chun的Blog:http://blog.csdn.net/gao_chun/article/details/38229339】