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

1.百度定位sdk

2.sqlite数据库(用于保存经纬度和实时更新的距离)

3.通过经纬度计算距离的算法方式

4.TimerTask 、Handler

大概思路:

1)创建项目,上传应用到百度定位sdk获得应用对应key,并配置定位服务成功。

2)将配置的定位代码块放入service中,使程序在后台不断更新经纬度

3)为应用创建数据库和相应的数据表,编写 增删改查 业务逻辑方法

4)编写界面,通过点击按钮控制是否开始计算距离,并引用数据库,初始化表数据,实时刷新界面

5)在service的定位代码块中计算距离,并将距离和经纬度实时的保存在数据库(注:只要经纬度发生改变,计算出来的距离就要进行保存)

6)界面的刷新显示

文章后附源码下载链接

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

[java]  view plain copy print ? 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  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. public class MainActivity extends Activity {

  23. private TextView mTvDistance;                   //控件

  24. private Button mButton;

  25. private TextView mLng_lat;

  26. private boolean isStart = true;                 //是否开始计算移动距离

  27. private DistanceInfoDao mDistanceInfoDao;       //数据库

  28. private volatile boolean isRefreshUI = true;    //是否暂停刷新UI的标识

  29. private static final int REFRESH_TIME = 5000;   //5秒刷新一次

  30. private Handler refreshHandler = new Handler(){ //刷新界面的Handler

  31. public void handleMessage(Message msg) {

  32. switch (msg.what) {

  33. case ConstantValues.REFRESH_UI:

  34. if (isRefreshUI) {

  35. LogUtil.info(DistanceComputeActivity.class, “refresh ui”);

  36. DistanceInfo mDistanceInfo = mDistanceInfoDao.getById(MyApplication.orderDealInfoId);

  37. LogUtil.info(DistanceComputeActivity.class, "界面刷新—> "+mDistanceInfo);

  38. if (mDistanceInfo != null) {

  39. mTvDistance.setText(String.valueOf(Utils.getValueWith2Suffix(mDistanceInfo.getDistance())));

  40. mLng_lat.setText(“经:”+mDistanceInfo.getLongitude()+" 纬:"+mDistanceInfo.getLatitude());

  41. mTvDistance.invalidate();

  42. mLng_lat.invalidate();

  43. }

  44. }

  45. break;

  46. }

  47. super.handleMessage(msg);

  48. }

  49. };

  50. //定时器,每5秒刷新一次UI

  51. private Timer refreshTimer = new Timer(true);

  52. private TimerTask refreshTask = new TimerTask() {

  53. @Override

  54. public void run() {

  55. if (isRefreshUI) {

  56. Message msg = refreshHandler.obtainMessage();

  57. msg.what = ConstantValues.REFRESH_UI;

  58. refreshHandler.sendMessage(msg);

  59. }

  60. }

  61. };

  62. @Override

  63. protected void onCreate(Bundle savedInstanceState) {

  64. super.onCreate(savedInstanceState);

  65. getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,

  66. WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);    //保持屏幕常亮

  67. setContentView(R.layout.activity_expensecompute);

  68. startService(new Intent(this,LocationService.class));   //启动定位服务

  69. Toast.makeText(this,“已启动定位服务…”, 1).show();

  70. init();                                                 //初始化相应控件

  71. }

  72. private void init(){

  73. mTvDistance = (TextView) findViewById(R.id.tv_drive_distance);

  74. mDistanceInfoDao = new DistanceInfoDao(this);

  75. refreshTimer.schedule(refreshTask, 0, REFRESH_TIME);

  76. mButton = (Button)findViewById(R.id.btn_start_drive);

  77. mLng_lat = (TextView)findViewById(R.id.longitude_Latitude);

  78. }

  79. @Override

  80. public void onClick(View v) {

  81. super.onClick(v);

  82. switch (v.getId()) {

  83. case R.id.btn_start_drive:      //计算距离按钮

  84. if(isStart)

  85. {

  86. mButton.setBackgroundResource(R.drawable.btn_selected);

  87. mButton.setText(“结束计算”);

  88. isStart = false;

  89. DistanceInfo mDistanceInfo = new DistanceInfo();

  90. mDistanceInfo.setDistance(0f);                 //距离初始值

  91. mDistanceInfo.setLongitude(MyApplication.lng); //经度初始值

  92. mDistanceInfo.setLatitude(MyApplication.lat);  //纬度初始值

  93. int id = mDistanceInfoDao.insertAndGet(mDistanceInfo);  //将值插入数据库,并获得数据库中最大的id

  94. if (id != -1) {

  95. MyApplication.orderDealInfoId = id;                 //将id赋值到程序全局变量中(注:该id来决定是否计算移动距离)

  96. Toast.makeText(this,“已开始计算…”, 0).show();

  97. }else{

  98. Toast.makeText(this,“id is -1,无法执行距离计算代码块”, 0).show();

  99. }

  100. }else{

  101. //自定义提示框

  102. ConfirmDialog dialog = new ConfirmDialog(this, R.style.dialogNoFrame){

  103. @Override

  104. public void setDialogContent(TextView content) {

  105. content.setVisibility(View.GONE);

  106. }

  107. @Override

  108. public void setDialogTitle(TextView title) {

  109. title.setText(“确认结束计算距离 ?”);

  110. }

  111. @Override

  112. public void startMission() {

  113. mButton.setBackgroundResource(R.drawable.btn_noselect);

  114. mButton.setText(“开始计算”);

  115. isStart = true;

  116. isRefreshUI = false;    //停止界面刷新

  117. if (refreshTimer != null) {

  118. refreshTimer.cancel();

  119. refreshTimer = null;

  120. }

  121. mDistanceInfoDao.delete(MyApplication.orderDealInfoId); //删除id对应记录

  122. MyApplication.orderDealInfoId = -1; //停止定位计算

  123. Toast.makeText(DistanceComputeActivity.this,“已停止计算…”, 0).show();

  124. }

  125. };

  126. dialog.show();

  127. }

  128. break;

  129. }

  130. }

  131. }

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

[java]  view plain copy print ? 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  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. public class LocationService extends Service {

  22. public static final String FILE_NAME = “log.txt”;                       //日志

  23. LocationClient mLocClient;

  24. private Object lock = new Object();

  25. private volatile GpsLocation prevGpsLocation = new GpsLocation();       //定位数据

  26. private volatile GpsLocation currentGpsLocation = new GpsLocation();

  27. private MyLocationListenner myListener = new MyLocationListenner();

  28. private volatile int discard = 1;   //Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。

  29. private DistanceInfoDao mDistanceInfoDao;

  30. private ExecutorService executor = Executors.newSingleThreadExecutor();

  31. @Override

  32. public IBinder onBind(Intent intent) {

  33. return null;

  34. }

  35. @Override

  36. public void onCreate() {

  37. super.onCreate();

  38. mDistanceInfoDao = new DistanceInfoDao(this);   //初始化数据库

  39. //LogUtil.info(LocationService.class, “Thread id ----------->:” + Thread.currentThread().getId());

  40. mLocClient = new LocationClient(this);

  41. mLocClient.registerLocationListener(myListener);

  42. //定位参数设置

  43. LocationClientOption option = new LocationClientOption();

  44. option.setCoorType(“bd09ll”); //返回的定位结果是百度经纬度,默认值gcj02

  45. option.setAddrType(“all”);    //返回的定位结果包含地址信息

  46. option.setScanSpan(5000);     //设置发起定位请求的间隔时间为5000ms

  47. option.disableCache(true);    //禁止启用缓存定位

  48. option.setProdName(“app.ui.activity”);

  49. option.setOpenGps(true);

  50. option.setPriority(LocationClientOption.GpsFirst);  //设置GPS优先

  51. mLocClient.setLocOption(option);

  52. mLocClient.start();

  53. mLocClient.requestLocation();

  54. }

  55. @Override

  56. @Deprecated

  57. public void onStart(Intent intent, int startId) {

  58. super.onStart(intent, startId);

  59. }

  60. @Override

  61. public void onDestroy() {

  62. super.onDestroy();

  63. if (null != mLocClient) {

  64. mLocClient.stop();

  65. }

  66. startService(new Intent(this, LocationService.class));

  67. }

  68. private class Task implements Callable{

  69. private BDLocation location;

  70. public Task(BDLocation location){

  71. this.location = location;

  72. }

  73. /**

  74. * 检测是否在原地不动

  75. *

  76. * @param distance

  77. * @return

  78. */

  79. private boolean noMove(float distance){

  80. if (distance < 0.01) {

  81. return true;

  82. }

  83. return false;

  84. }

  85. /**

  86. * 检测是否在正确的移动

  87. *

  88. * @param distance

  89. * @return

  90. */

  91. private boolean checkProperMove(float distance){

  92. if(distance <= 0.1 * discard){

  93. return true;

  94. }else{

  95. return false;

  96. }

  97. }

  98. /**

  99. * 检测获取的数据是否是正常的

  100. *

  101. * @param location

  102. * @return

  103. */

  104. private boolean checkProperLocation(BDLocation location){

  105. if (location != null && location.getLatitude() != 0 && location.getLongitude() != 0){

  106. return true;

  107. }

  108. return false;

  109. }

  110. @Override

  111. public String call() throws Exception {

  112. synchronized (lock) {

  113. if (!checkProperLocation(location)){

  114. LogUtil.info(LocationService.class, “location data is null”);

  115. discard++;

  116. return null;

  117. }

  118. if (MyApplication.orderDealInfoId != -1) {

  119. DistanceInfo mDistanceInfo = mDistanceInfoDao.getById(MyApplication.orderDealInfoId);   //根据MainActivity中赋值的全局id查询数据库的值

  120. if(mDistanceInfo != null)       //不为空则说明车已经开始行使,并可以获得经纬度,计算移动距离

  121. {

  122. LogUtil.info(LocationService.class, “行驶中…”);

  123. GpsLocation tempGpsLocation = BDLocation2GpsUtil.convertWithBaiduAPI(location);     //位置转换

  124. if (tempGpsLocation != null) {

  125. currentGpsLocation = tempGpsLocation;

  126. }else{

  127. discard ++;

  128. }

  129. //日志

  130. String logMsg = “(plat:—>” + prevGpsLocation.lat + "  plgt:—>" + prevGpsLocation.lng +“)\n” +

  131. “(clat:—>” + currentGpsLocation.lat + "  clgt:—>" + currentGpsLocation.lng + “)”;

  132. LogUtil.info(LocationService.class, logMsg);

  133. /** 计算距离  */

  134. float distance = 0.0f;

  135. DistanceComputeInterface distanceComputeInterface = DistanceComputeImpl.getInstance();  //计算距离类对象

  136. distance = (float) distanceComputeInterface.getLongDistance(prevGpsLocation.lat,prevGpsLocation.lng,

  137. currentGpsLocation.lat,currentGpsLocation.lng);     //移动距离计算

  138. if (!noMove(distance)) {                //是否在移动

  139. if (checkProperMove(distance)) {    //合理的移动

  140. float drivedDistance = mDistanceInfo.getDistance();

  141. mDistanceInfo.setDistance(distance + drivedDistance); //拿到数据库原始距离值, 加上当前值

  142. mDistanceInfo.setLongitude(currentGpsLocation.lng);   //经度

  143. mDistanceInfo.setLatitude(currentGpsLocation.lat);    //纬度

  144. //日志记录

  145. FileUtils.saveToSDCard(FILE_NAME,“移动距离—>:”+distance+drivedDistance+“\n”+“数据库中保存的距离”+mDistanceInfo.getDistance());

  146. mDistanceInfoDao.updateDistance(mDistanceInfo);

  147. discard = 1;

  148. }

  149. }

  150. prevGpsLocation = currentGpsLocation;

  151. }

  152. }

  153. return null;

  154. }

  155. }

  156. }

  157. /**

  158. * 定位SDK监听函数

  159. */

  160. public class MyLocationListenner implements BDLocationListener {

  161. @Override

  162. public void onReceiveLocation(BDLocation location) {

  163. executor.submit(new Task(location));

  164. LogUtil.info(LocationService.class, “经度:”+location.getLongitude());

  165. LogUtil.info(LocationService.class, “纬度:”+location.getLatitude());

  166. //将经纬度保存于全局变量,在MainActivity中点击按钮时初始化数据库字段

  167. if(MyApplication.lng <=0 && MyApplication.lat <= 0)

  168. {

  169. MyApplication.lng = location.getLongitude();

  170. MyApplication.lat = location.getLatitude();

  171. }

  172. }

  173. public void onReceivePoi(BDLocation poiLocation) {

  174. if (poiLocation == null){

  175. return ;

  176. }

  177. }

  178. }

  179. }

以下是应用中需要使用的DBOpenHelper数据库类 DBOpenHelper.java

[java]  view plain copy print ? 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. package app.db;

  2. import android.content.Context;

  3. import android.database.sqlite.SQLiteDatabase;

  4. import android.database.sqlite.SQLiteOpenHelper;

  5. public class DBOpenHelper extends SQLiteOpenHelper{

  6. private static final int VERSION = 1;                   //数据库版本号

  7. private static final String DB_NAME = “distance.db”;    //数据库名

  8. public DBOpenHelper(Context context){                   //创建数据库

  9. super(context, DB_NAME, null, VERSION);

  10. }

  11. @Override

  12. public void onCreate(SQLiteDatabase db) {               //创建数据表

  13. db.execSQL(“CREATE TABLE IF NOT EXISTS milestone(id INTEGER PRIMARY KEY AUTOINCREMENT, distance INTEGER,longitude DOUBLE, latitude DOUBLE )”);

  14. }

  15. @Override

  16. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  //版本号发生改变的时

  17. db.execSQL(“drop table milestone”);

  18. db.execSQL(“CREATE TABLE IF NOT EXISTS milestone(id INTEGER PRIMARY KEY AUTOINCREMENT, distance INTEGER,longitude FLOAT, latitude FLOAT )”);

  19. }

  20. }

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

[java]  view plain copy print ? 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  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. public class DistanceInfoDao {

  8. private DBOpenHelper helper;

  9. private SQLiteDatabase db;

  10. public DistanceInfoDao(Context context) {

  11. helper = new DBOpenHelper(context);

  12. }

  13. public void insert(DistanceInfo mDistanceInfo) {

  14. if (mDistanceInfo == null) {

  15. return;

  16. }

  17. db = helper.getWritableDatabase();

  18. String sql = “INSERT INTO milestone(distance,longitude,latitude) VALUES('”+ mDistanceInfo.getDistance() + “‘,’”+ mDistanceInfo.getLongitude() + “‘,’”+ mDistanceInfo.getLatitude() + “')”;

  19. LogUtil.info(DistanceInfoDao.class, sql);

  20. db.execSQL(sql);

  21. db.close();

  22. }

  23. public int getMaxI
    d() {

  24. db = helper.getReadableDatabase();

  25. Cursor cursor = db.rawQuery(“SELECT MAX(id) as id from milestone”,null);

  26. if (cursor.moveToFirst()) {

  27. return cursor.getInt(cursor.getColumnIndex(“id”));

  28. }

  29. return -1;

  30. }

  31. /**

  32. * 添加数据

  33. * @param orderDealInfo

  34. * @return

  35. */

  36. public synchronized int insertAndGet(DistanceInfo mDistanceInfo) {

  37. int result = -1;

  38. insert(mDistanceInfo);

  39. result = getMaxId();

  40. return result;

  41. }

  42. /**

  43. * 根据id获取

  44. * @param id

  45. * @return

  46. */

  47. public DistanceInfo getById(int id) {

  48. db = helper.getReadableDatabase();

  49. Cursor cursor = db.rawQuery(“SELECT * from milestone WHERE id = ?”,new String[] { String.valueOf(id) });

  50. DistanceInfo mDistanceInfo = null;

  51. if (cursor.moveToFirst()) {

  52. mDistanceInfo = new DistanceInfo();

  53. mDistanceInfo.setId(cursor.getInt(cursor.getColumnIndex(“id”)));

  54. mDistanceInfo.setDistance(cursor.getFloat(cursor.getColumnIndex(“distance”)));

  55. mDistanceInfo.setLongitude(cursor.getFloat(cursor.getColumnIndex(“longitude”)));

  56. mDistanceInfo.setLatitude(cursor.getFloat(cursor.getColumnIndex(“latitude”)));

* 根据id获取

  1. * @param id

  2. * @return

  3. */

  4. public DistanceInfo getById(int id) {

  5. db = helper.getReadableDatabase();

  6. Cursor cursor = db.rawQuery(“SELECT * from milestone WHERE id = ?”,new String[] { String.valueOf(id) });

  7. DistanceInfo mDistanceInfo = null;

  8. if (cursor.moveToFirst()) {

  9. mDistanceInfo = new DistanceInfo();

  10. mDistanceInfo.setId(cursor.getInt(cursor.getColumnIndex(“id”)));

  11. mDistanceInfo.setDistance(cursor.getFloat(cursor.getColumnIndex(“distance”)));

  12. mDistanceInfo.setLongitude(cursor.getFloat(cursor.getColumnIndex(“longitude”)));

  13. mDistanceInfo.setLatitude(cursor.getFloat(cursor.getColumnIndex(“latitude”)));

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值