android中使用百度定位sdk实时的计算挪动距离

android中使用百度定位sdk实时的计算移动距离
前段时间因为项目需求,通过百度定位adk写了一个实时更新距离的程序(类似大家坐的士时,车上的里程表),遇到很多技术点,总结了一下发表出来和大家相互学习。直接要求定位具体的位置应该是不难的,只需要引入百度定位adk,并配置相关参数就可以完成,显示百度地图也类似,但是如果需要不断的实时显示移动距离,GPS定位从一个点,到第二个点,从第二个点,到第三个点,从第三个点......,移动距离是多少呢?不得不说,要实现这种需求的确存在一定的难度。

目标:使用百度定位sdk开发实时移动距离计算功能,根据经纬度的定位,计算行驶公里数并实时刷新界面显示。
大家都知道定位有三种方式:GPS 、Wifi 、 基站 .
误差方面的话,使用GPS误差在10左右,Wifi则在20 - 300左右 ,而使用基站则误差在100 - 300左右的样子,因为在室内GPS是定位不到的,必须在室外,
而我们项目的需求正好需要使用GPS定位,所以我们这里设置GPS优先。车,不可能在室内跑吧。


使用技术点:
1.百度定位sdk
2.sqlite数据库(用于保存经纬度和实时更新的距离)
3.通过经纬度计算距离的算法方式
4.TimerTask 、Handler


大概思路:
1)创建项目,上传应用到百度定位sdk获得应用对应key,并配置定位服务成功。
2)将配置的定位代码块放入service中,使程序在后台不断更新经纬度
3)为应用创建数据库和相应的数据表,编写 增删改查 业务逻辑方法
4)编写界面,通过点击按钮控制是否开始计算距离,并引用数据库,初始化表数据,实时刷新界面
5)在service的定位代码块中计算距离,并将距离和经纬度实时的保存在数据库(注:只要经纬度发生改变,计算出来的距离就要进行保存)

6)界面的刷新显示

文章后附源码下载链接

以下是MainActivity中的代码,通过注释可以理解思路流程.

[java] view plaincopyprint?android中使用百度定位sdk实时的计算挪动距离android中使用百度定位sdk实时的计算挪动距离
  1. package app.ui.activity;  
  2.     import java.util.Timer;  
  3.     import java.util.TimerTask;  
  4.     import android.content.Intent;  
  5.     import android.os.Bundle;  
  6.     import android.os.Handler;  
  7.     import android.os.Message;  
  8.     import android.view.View;  
  9.     import android.view.WindowManager;  
  10.     import android.widget.Button;  
  11.     import android.widget.TextView;  
  12.     import android.widget.Toast;  
  13.     import app.db.DistanceInfoDao;  
  14.     import app.model.DistanceInfo;  
  15.     import app.service.LocationService;  
  16.     import app.ui.ConfirmDialog;  
  17.     import app.ui.MyApplication;  
  18.     import app.ui.R;  
  19.     import app.utils.ConstantValues;  
  20.     import app.utils.LogUtil;  
  21.     import app.utils.Utils;  
  22.   
  23.     public class MainActivity extends Activity {  
  24.           
  25.         private TextView mTvDistance;                   //控件  
  26.         private Button mButton;  
  27.         private TextView mLng_lat;  
  28.         private boolean isStart = true;                 //是否开始计算移动距离  
  29.   
  30.         private DistanceInfoDao mDistanceInfoDao;       //数据库  
  31.         private volatile boolean isRefreshUI = true;    //是否暂停刷新UI的标识  
  32.         private static final int REFRESH_TIME = 5000;   //5秒刷新一次  
  33.   
  34.         private Handler refreshHandler = new Handler(){ //刷新界面的Handler  
  35.             public void handleMessage(Message msg) {  
  36.                 switch (msg.what) {  
  37.                     case ConstantValues.REFRESH_UI:  
  38.                         if (isRefreshUI) {  
  39.                             LogUtil.info(DistanceComputeActivity.class"refresh ui");  
  40.                             DistanceInfo mDistanceInfo = mDistanceInfoDao.getById(MyApplication.orderDealInfoId);  
  41.                             LogUtil.info(DistanceComputeActivity.class"界面刷新---> "+mDistanceInfo);  
  42.                             if (mDistanceInfo != null) {  
  43.                                 mTvDistance.setText(String.valueOf(Utils.getValueWith2Suffix(mDistanceInfo.getDistance())));  
  44.                                 mLng_lat.setText("经:"+mDistanceInfo.getLongitude()+" 纬:"+mDistanceInfo.getLatitude());  
  45.                                 mTvDistance.invalidate();  
  46.                                 mLng_lat.invalidate();  
  47.                             }  
  48.                         }  
  49.                         break;  
  50.                 }  
  51.                 super.handleMessage(msg);  
  52.             }  
  53.         };  
  54.   
  55.         //定时器,每5秒刷新一次UI  
  56.         private Timer refreshTimer = new Timer(true);  
  57.         private TimerTask refreshTask = new TimerTask() {  
  58.             @Override  
  59.             public void run() {  
  60.                 if (isRefreshUI) {  
  61.                     Message msg = refreshHandler.obtainMessage();  
  62.                     msg.what = ConstantValues.REFRESH_UI;  
  63.                     refreshHandler.sendMessage(msg);  
  64.                 }  
  65.             }  
  66.         };  
  67.   
  68.         @Override  
  69.         protected void onCreate(Bundle savedInstanceState) {  
  70.             super.onCreate(savedInstanceState);  
  71.             getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,   
  72.                 WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);    //保持屏幕常亮  
  73.             setContentView(R.layout.activity_expensecompute);  
  74.   
  75.             startService(new Intent(this,LocationService.class));   //启动定位服务  
  76.             Toast.makeText(this,"已启动定位服务..."1).show();  
  77.             init();                                                 //初始化相应控件  
  78.         }  
  79.   
  80.         private void init(){  
  81.             mTvDistance = (TextView) findViewById(R.id.tv_drive_distance);  
  82.             mDistanceInfoDao = new DistanceInfoDao(this);  
  83.             refreshTimer.schedule(refreshTask, 0, REFRESH_TIME);  
  84.             mButton = (Button)findViewById(R.id.btn_start_drive);  
  85.             mLng_lat = (TextView)findViewById(R.id.longitude_Latitude);  
  86.         }  
  87.   
  88.   
  89.         @Override  
  90.         public void onClick(View v) {  
  91.             super.onClick(v);  
  92.             switch (v.getId()) {  
  93.                 case R.id.btn_start_drive:      //计算距离按钮  
  94.                     if(isStart)  
  95.                     {  
  96.                         mButton.setBackgroundResource(R.drawable.btn_selected);  
  97.                         mButton.setText("结束计算");  
  98.                         isStart = false;  
  99.                         DistanceInfo mDistanceInfo = new DistanceInfo();  
  100.                         mDistanceInfo.setDistance(0f);                 //距离初始值  
  101.                         mDistanceInfo.setLongitude(MyApplication.lng); //经度初始值  
  102.                         mDistanceInfo.setLatitude(MyApplication.lat);  //纬度初始值  
  103.                         int id = mDistanceInfoDao.insertAndGet(mDistanceInfo);  //将值插入数据库,并获得数据库中最大的id  
  104.                         if (id != -1) {  
  105.                             MyApplication.orderDealInfoId = id;                 //将id赋值到程序全局变量中(注:该id来决定是否计算移动距离)  
  106.                             Toast.makeText(this,"已开始计算..."0).show();  
  107.                         }else{  
  108.                             Toast.makeText(this,"id is -1,无法执行距离计算代码块"0).show();  
  109.                         }  
  110.                     }else{  
  111.                         //自定义提示框  
  112.                         ConfirmDialog dialog = new ConfirmDialog(this, R.style.dialogNoFrame){  
  113.                             @Override  
  114.                             public void setDialogContent(TextView content) {  
  115.                                 content.setVisibility(View.GONE);  
  116.                             }  
  117.                             @Override  
  118.                             public void setDialogTitle(TextView title) {  
  119.                                 title.setText("确认结束计算距离 ?");  
  120.                             }  
  121.                             @Override  
  122.                             public void startMission() {  
  123.                                 mButton.setBackgroundResource(R.drawable.btn_noselect);  
  124.                                 mButton.setText("开始计算");  
  125.                                 isStart = true;  
  126.                                 isRefreshUI = false;    //停止界面刷新  
  127.                                 if (refreshTimer != null) {  
  128.                                     refreshTimer.cancel();  
  129.                                     refreshTimer = null;  
  130.                                 }  
  131.                                 mDistanceInfoDao.delete(MyApplication.orderDealInfoId); //删除id对应记录  
  132.                                 MyApplication.orderDealInfoId = -1//停止定位计算  
  133.                                 Toast.makeText(DistanceComputeActivity.this,"已停止计算..."0).show();  
  134.                             }  
  135.                         };  
  136.                         dialog.show();  
  137.                     }  
  138.                     break;  
  139.             }  
  140.         }  
  141.     }  

以下是LocationService中的代码,即配置的百度定位sdk代码块,放在继承了service的类中  LocationService.java (方便程序在后台实时更新经纬度)

[java] view plaincopyprint?android中使用百度定位sdk实时的计算挪动距离android中使用百度定位sdk实时的计算挪动距离
  1. package app.service;  
  2.     import java.util.concurrent.Callable;  
  3.     import java.util.concurrent.ExecutorService;  
  4.     import java.util.concurrent.Executors;  
  5.     import android.app.Service;  
  6.     import android.content.Intent;  
  7.     import android.os.IBinder;  
  8.     import app.db.DistanceInfoDao;  
  9.     import app.model.GpsLocation;  
  10.     import app.model.DistanceInfo;  
  11.     import app.ui.MyApplication;  
  12.     import app.utils.BDLocation2GpsUtil;  
  13.     import app.utils.FileUtils;  
  14.     import app.utils.LogUtil;  
  15.     import com.baidu.location.BDLocation;  
  16.     import com.baidu.location.BDLocationListener;  
  17.     import com.baidu.location.LocationClient;  
  18.     import com.baidu.location.LocationClientOption;  
  19.     import com.computedistance.DistanceComputeInterface;  
  20.     import com.computedistance.impl.DistanceComputeImpl;  
  21.   
  22.     public class LocationService extends Service {  
  23.   
  24.         public static final String FILE_NAME = "log.txt";                       //日志  
  25.         LocationClient mLocClient;  
  26.         private Object lock = new Object();  
  27.         private volatile GpsLocation prevGpsLocation = new GpsLocation();       //定位数据  
  28.         private volatile GpsLocation currentGpsLocation = new GpsLocation();  
  29.         private MyLocationListenner myListener = new MyLocationListenner();  
  30.         private volatile int discard = 1;   //Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。  
  31.         private DistanceInfoDao mDistanceInfoDao;  
  32.         private ExecutorService executor = Executors.newSingleThreadExecutor();  
  33.   
  34.         @Override  
  35.         public IBinder onBind(Intent intent) {  
  36.             return null;  
  37.         }  
  38.   
  39.         @Override  
  40.         public void onCreate() {  
  41.             super.onCreate();  
  42.             mDistanceInfoDao = new DistanceInfoDao(this);   //初始化数据库  
  43.             //LogUtil.info(LocationService.class, "Thread id ----------->:" + Thread.currentThread().getId());  
  44.             mLocClient = new LocationClient(this);  
  45.             mLocClient.registerLocationListener(myListener);  
  46.             //定位参数设置  
  47.             LocationClientOption option = new LocationClientOption();  
  48.             option.setCoorType("bd09ll"); //返回的定位结果是百度经纬度,默认值gcj02  
  49.             option.setAddrType("all");    //返回的定位结果包含地址信息  
  50.             option.setScanSpan(5000);     //设置发起定位请求的间隔时间为5000ms  
  51.             option.disableCache(true);    //禁止启用缓存定位  
  52.             option.setProdName("app.ui.activity");  
  53.             option.setOpenGps(true);  
  54.             option.setPriority(LocationClientOption.GpsFirst);  //设置GPS优先  
  55.             mLocClient.setLocOption(option);  
  56.             mLocClient.start();  
  57.             mLocClient.requestLocation();  
  58.   
  59.         }  
  60.   
  61.         @Override  
  62.         @Deprecated  
  63.         public void onStart(Intent intent, int startId) {  
  64.             super.onStart(intent, startId);  
  65.         }  
  66.   
  67.         @Override  
  68.         public void onDestroy() {  
  69.             super.onDestroy();  
  70.             if (null != mLocClient) {  
  71.                 mLocClient.stop();  
  72.             }  
  73.             startService(new Intent(this, LocationService.class));  
  74.         }  
  75.   
  76.         private class Task implements Callable<String>{  
  77.             private BDLocation location;  
  78.             public Task(BDLocation location){  
  79.                 this.location = location;  
  80.             }  
  81.   
  82.             /** 
  83.              * 检测是否在原地不动 
  84.              * 
  85.              * @param distance 
  86.              * @return 
  87.              */  
  88.             private boolean noMove(float distance){  
  89.                 if (distance < 0.01) {  
  90.                     return true;  
  91.                 }  
  92.                 return false;  
  93.             }  
  94.   
  95.             /** 
  96.              * 检测是否在正确的移动 
  97.              * 
  98.              * @param distance 
  99.              * @return 
  100.              */  
  101.             private boolean checkProperMove(float distance){  
  102.                 if(distance <= 0.1 * discard){  
  103.                     return true;  
  104.                 }else{  
  105.                     return false;  
  106.                 }  
  107.             }  
  108.   
  109.             /** 
  110.              * 检测获取的数据是否是正常的 
  111.              * 
  112.              * @param location 
  113.              * @return 
  114.              */  
  115.             private boolean checkProperLocation(BDLocation location){  
  116.                 if (location != null && location.getLatitude() != 0 && location.getLongitude() != 0){  
  117.                     return true;  
  118.                 }  
  119.                 return false;  
  120.             }  
  121.   
  122.             @Override  
  123.             public String call() throws Exception {  
  124.                 synchronized (lock) {  
  125.                     if (!checkProperLocation(location)){  
  126.                         LogUtil.info(LocationService.class"location data is null");  
  127.                         discard++;  
  128.                         return null;  
  129.                     }  
  130.   
  131.                     if (MyApplication.orderDealInfoId != -1) {  
  132.                         DistanceInfo mDistanceInfo = mDistanceInfoDao.getById(MyApplication.orderDealInfoId);   //根据MainActivity中赋值的全局id查询数据库的值  
  133.                         if(mDistanceInfo != null)       //不为空则说明车已经开始行使,并可以获得经纬度,计算移动距离  
  134.                         {  
  135.                             LogUtil.info(LocationService.class"行驶中......");  
  136.                             GpsLocation tempGpsLocation = BDLocation2GpsUtil.convertWithBaiduAPI(location);     //位置转换  
  137.                             if (tempGpsLocation != null) {  
  138.                                 currentGpsLocation = tempGpsLocation;  
  139.                             }else{  
  140.                                 discard ++;  
  141.                             }  
  142.                             //日志  
  143.                             String logMsg = "(plat:--->" + prevGpsLocation.lat + "  plgt:--->" + prevGpsLocation.lng +")\n" +  
  144.                                             "(clat:--->" + currentGpsLocation.lat + "  clgt:--->" + currentGpsLocation.lng + ")";  
  145.                             LogUtil.info(LocationService.class, logMsg);  
  146.   
  147.                             /** 计算距离  */  
  148.                             float distance = 0.0f;  
  149.                             DistanceComputeInterface distanceComputeInterface = DistanceComputeImpl.getInstance();  //计算距离类对象  
  150.                             distance = (float) distanceComputeInterface.getLongDistance(prevGpsLocation.lat,prevGpsLocation.lng,  
  151.                             currentGpsLocation.lat,currentGpsLocation.lng);     //移动距离计算  
  152.                             if (!noMove(distance)) {                //是否在移动  
  153.                                 if (checkProperMove(distance)) {    //合理的移动  
  154.                                     float drivedDistance = mDistanceInfo.getDistance();  
  155.                                     mDistanceInfo.setDistance(distance + drivedDistance); //拿到数据库原始距离值, 加上当前值  
  156.                                     mDistanceInfo.setLongitude(currentGpsLocation.lng);   //经度  
  157.                                     mDistanceInfo.setLatitude(currentGpsLocation.lat);    //纬度  
  158.   
  159.                                     //日志记录  
  160.                                     FileUtils.saveToSDCard(FILE_NAME,"移动距离--->:"+distance+drivedDistance+"\n"+"数据库中保存的距离"+mDistanceInfo.getDistance());  
  161.                                     mDistanceInfoDao.updateDistance(mDistanceInfo);  
  162.                                     discard = 1;  
  163.                                 }  
  164.                             }  
  165.                             prevGpsLocation = currentGpsLocation;  
  166.                         }  
  167.                     }  
  168.                     return null;  
  169.                 }  
  170.             }  
  171.         }  
  172.   
  173.         /** 
  174.          * 定位SDK监听函数 
  175.          */  
  176.         public class MyLocationListenner implements BDLocationListener {  
  177.             @Override  
  178.             public void onReceiveLocation(BDLocation location) {  
  179.                 executor.submit(new Task(location));  
  180.   
  181.                 LogUtil.info(LocationService.class"经度:"+location.getLongitude());  
  182.                 LogUtil.info(LocationService.class"纬度:"+location.getLatitude());  
  183.                 //将经纬度保存于全局变量,在MainActivity中点击按钮时初始化数据库字段  
  184.                 if(MyApplication.lng <=0 && MyApplication.lat <= 0)  
  185.                 {  
  186.                     MyApplication.lng = location.getLongitude();  
  187.                     MyApplication.lat = location.getLatitude();  
  188.                 }  
  189.             }  
  190.   
  191.             public void onReceivePoi(BDLocation poiLocation) {  
  192.                 if (poiLocation == null){  
  193.                     return ;  
  194.                 }  
  195.             }  
  196.         }  
  197.     }  
以下是应用中需要使用的DBOpenHelper数据库类 DBOpenHelper.java

[java] view plaincopyprint?android中使用百度定位sdk实时的计算挪动距离android中使用百度定位sdk实时的计算挪动距离
  1. package app.db;  
  2. import android.content.Context;  
  3. import android.database.sqlite.SQLiteDatabase;  
  4. import android.database.sqlite.SQLiteOpenHelper;  
  5.   
  6. public class DBOpenHelper extends SQLiteOpenHelper{  
  7.     private static final int VERSION = 1;                   //数据库版本号  
  8.     private static final String DB_NAME = "distance.db";    //数据库名  
  9.   
  10.     public DBOpenHelper(Context context){                   //创建数据库  
  11.         super(context, DB_NAME, null, VERSION);  
  12.     }  
  13.   
  14.     @Override  
  15.     public void onCreate(SQLiteDatabase db) {               //创建数据表  
  16.         db.execSQL("CREATE TABLE IF NOT EXISTS milestone(id INTEGER PRIMARY KEY AUTOINCREMENT, distance INTEGER,longitude DOUBLE, latitude DOUBLE )");  
  17.     }  
  18.   
  19.     @Override  
  20.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  //版本号发生改变的时  
  21.         db.execSQL("drop table milestone");  
  22.         db.execSQL("CREATE TABLE IF NOT EXISTS milestone(id INTEGER PRIMARY KEY AUTOINCREMENT, distance INTEGER,longitude FLOAT, latitude FLOAT )");  
  23.     }  
  24.   
  25. }  

以下是应用中需要使用的数据库业务逻辑封装类 DistanceInfoDao.java

[java] view plaincopyprint?android中使用百度定位sdk实时的计算挪动距离android中使用百度定位sdk实时的计算挪动距离
  1. package app.db;  
  2.     import android.content.Context;  
  3.     import android.database.Cursor;  
  4.     import android.database.sqlite.SQLiteDatabase;  
  5.     import app.model.DistanceInfo;  
  6.     import app.utils.LogUtil;  
  7.   
  8.     public class DistanceInfoDao {  
  9.         private DBOpenHelper helper;  
  10.         private SQLiteDatabase db;  
  11.   
  12.         public DistanceInfoDao(Context context) {  
  13.             helper = new DBOpenHelper(context);  
  14.         }  
  15.   
  16.         public void insert(DistanceInfo mDistanceInfo) {  
  17.             if (mDistanceInfo == null) {  
  18.                 return;  
  19.             }  
  20.             db = helper.getWritableDatabase();  
  21.             String sql = "INSERT INTO milestone(distance,longitude,latitude) VALUES('"+ mDistanceInfo.getDistance() + "','"+ mDistanceInfo.getLongitude() + "','"+ mDistanceInfo.getLatitude() + "')";  
  22.             LogUtil.info(DistanceInfoDao.class, sql);  
  23.             db.execSQL(sql);  
  24.             db.close();  
  25.         }  
  26.   
  27.         public int getMaxId() {  
  28.             db = helper.getReadableDatabase();  
  29.             Cursor cursor = db.rawQuery("SELECT MAX(id) as id from milestone",null);  
  30.             if (cursor.moveToFirst()) {  
  31.                 return cursor.getInt(cursor.getColumnIndex("id"));  
  32.             }  
  33.             return -1;  
  34.         }  
  35.   
  36.         /** 
  37.          * 添加数据 
  38.          * @param orderDealInfo 
  39.          * @return 
  40.          */  
  41.         public synchronized int insertAndGet(DistanceInfo mDistanceInfo) {  
  42.             int result = -1;  
  43.             insert(mDistanceInfo);  
  44.             result = getMaxId();  
  45.             return result;  
  46.         }  
  47.   
  48.         /** 
  49.          * 根据id获取 
  50.          * @param id 
  51.          * @return 
  52.          */  
  53.         public DistanceInfo getById(int id) {  
  54.             db = helper.getReadableDatabase();  
  55.             Cursor cursor = db.rawQuery("SELECT * from milestone WHERE id = ?",new String[] { String.valueOf(id) });  
  56.             DistanceInfo mDistanceInfo = null;  
  57.             if (cursor.moveToFirst()) {  
  58.                 mDistanceInfo = new DistanceInfo();  
  59.                 mDistanceInfo.setId(cursor.getInt(cursor.getColumnIndex("id")));  
  60.                 mDistanceInfo.setDistance(cursor.getFloat(cursor.getColumnIndex("distance")));  
  61.                 mDistanceInfo.setLongitude(cursor.getFloat(cursor.getColumnIndex("longitude")));  
  62.                 mDistanceInfo.setLatitude(cursor.getFloat(cursor.getColumnIndex("latitude")));  
  63.             }  
  64.             cursor.close();  
  65.             db.close();  
  66.             return mDistanceInfo;  
  67.         }  
  68.   
  69.         /** 
  70.          * 更新距离 
  71.          * @param orderDealInfo 
  72.          */  
  73.         public void updateDistance(DistanceInfo mDistanceInfo) {  
  74.             if (mDistanceInfo == null) {  
  75.                 return;  
  76.             }  
  77.             db = helper.getWritableDatabase();  
  78.             String sql = "update milestone set distance="+ mDistanceInfo.getDistance() +",longitude="+mDistanceInfo.getLongitude()+",latitude="+mDistanceInfo.getLatitude()+" where id = "+ mDistanceInfo.getId();  
  79.             LogUtil.info(DistanceInfoDao.class, sql);  
  80.             db.execSQL(sql);  
  81.             db.close();  
  82.         }  
  83.     }  

以下是需要使用到的实体类 DistanceInfo.java (set数据到对应变量,以实体类作为参数更新数据库)

[java] view plaincopyprint?android中使用百度定位sdk实时的计算挪动距离android中使用百度定位sdk实时的计算挪动距离
  1. package app.model;  
  2. public class DistanceInfo {  
  3.     private int id;  
  4.     private float distance;  
  5.     private double longitude;  
  6.     private double latitude;  
  7.   
  8.     public int getId() {  
  9.         return id;  
  10.     }  
  11.     public void setId(int id) {  
  12.         this.id = id;  
  13.     }  
  14.     public float getDistance() {  
  15.         return distance;  
  16.     }  
  17.     public void setDistance(float distance) {  
  18.         this.distance = distance;  
  19.     }  
  20.     public double getLongitude() {  
  21.   
  22.         return longitude;  
  23.     }  
  24.     public void setLongitude(double longitude) {  
  25.   
  26.         this.longitude = longitude;  
  27.     }  
  28.     public double getLatitude() {  
  29.   
  30.         return latitude;  
  31.     }  
  32.     public void setLatitude(double latitude) {  
  33.   
  34.         this.latitude = latitude;  
  35.     }  
  36.     @Override  
  37.     public String toString() {  
  38.   
  39.         return "DistanceInfo [id=" + id + ", distance=" + distance  
  40.                 + ", longitude=" + longitude + ", latitude=" + latitude + "]";  
  41.     }  
  42. }  

保存经纬度信息的类 GpsLocation

[java] view plaincopyprint?android中使用百度定位sdk实时的计算挪动距离android中使用百度定位sdk实时的计算挪动距离
  1. package app.model;  
  2. public class GpsLocation {  
  3.     public double lat;//纬度  
  4.     public double lng;//经度  
  5. }  
将从百度定位中获得的经纬度转换为精准的GPS数据 BDLocation2GpsUtil.java

[java] view plaincopyprint?android中使用百度定位sdk实时的计算挪动距离android中使用百度定位sdk实时的计算挪动距离
  1. package app.utils;  
  2. import it.sauronsoftware.base64.Base64;  
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.net.HttpURLConnection;  
  7. import java.net.URL;  
  8. import org.json.JSONObject;  
  9. import app.model.GpsLocation;  
  10. import com.baidu.location.BDLocation;  
  11. public class BDLocation2GpsUtil {  
  12.     static BDLocation tempBDLocation = new BDLocation();     // 临时变量,百度位置  
  13.     static GpsLocation tempGPSLocation = new GpsLocation();  // 临时变量,gps位置  
  14.     public static enum Method{  
  15.         origin, correct;  
  16.     }  
  17.     private static final Method method = Method.correct;  
  18.     /** 
  19.      * 位置转换 
  20.      * 
  21.      * @param lBdLocation 百度位置 
  22.      * @return GPS位置 
  23.      */  
  24.     public static GpsLocation convertWithBaiduAPI(BDLocation lBdLocation) {  
  25.         switch (method) {  
  26.         case origin:    //原点  
  27.             GpsLocation location = new GpsLocation();  
  28.             location.lat = lBdLocation.getLatitude();  
  29.             location.lng = lBdLocation.getLongitude();  
  30.             return location;  
  31.         case correct:   //纠偏  
  32.             //同一个地址不多次转换  
  33.             if (tempBDLocation.getLatitude() == lBdLocation.getLatitude() && tempBDLocation.getLongitude() == lBdLocation.getLongitude()) {  
  34.                 return tempGPSLocation;  
  35.             }  
  36.             String url = "http://api.map.baidu.com/ag/coord/convert?from=0&to=4&"  
  37.                     + "x=" + lBdLocation.getLongitude() + "&y="  
  38.                     + lBdLocation.getLatitude();  
  39.             String result = executeHttpGet(url);  
  40.             LogUtil.info(BDLocation2GpsUtil.class"result:" + result);  
  41.             if (result != null) {  
  42.                 GpsLocation gpsLocation = new GpsLocation();  
  43.                 try {  
  44.                     JSONObject jsonObj = new JSONObject(result);  
  45.                     String lngString = jsonObj.getString("x");  
  46.                     String latString = jsonObj.getString("y");  
  47.                     // 解码  
  48.                     double lng = Double.parseDouble(new String(Base64.decode(lngString)));  
  49.                     double lat = Double.parseDouble(new String(Base64.decode(latString)));  
  50.                     // 换算  
  51.                     gpsLocation.lng = 2 * lBdLocation.getLongitude() - lng;  
  52.                     gpsLocation.lat = 2 * lBdLocation.getLatitude() - lat;  
  53.                     tempGPSLocation = gpsLocation;  
  54.                     LogUtil.info(BDLocation2GpsUtil.class"result:" + gpsLocation.lat + "||" + gpsLocation.lng);  
  55.                 } catch (Exception e) {  
  56.                     e.printStackTrace();  
  57.                     return null;  
  58.                 }  
  59.                 tempBDLocation = lBdLocation;  
  60.                 return gpsLocation;  
  61.             }else{  
  62.                 LogUtil.info(BDLocation2GpsUtil.class"百度API执行出错,url is:" + url);  
  63.                 return null;  
  64.             }  
  65.         }  
  66.     }  
  67. }  

需要声明相关权限,且项目中所用到的jar有:
android-support-v4.jar
commons-codec.jar
commons-lang3-3.0-beta.jar
javabase64-1.3.1.jar
locSDK_3.1.jar


Android中计算地图上两点距离的算法


项目中目前尚有部分不健全的地方,如:
1.在行驶等待时间较长后,使用TimerTask 、Handler刷新界面是偶尔会出现卡住的现象,车仍在行驶,
但是数据不动了,通过改善目前测试近7次未出现此问题。

2.较快的消耗电量

源码下载地址