;   //5秒刷新一次

  • private Handler refreshHandler = new Handler(){ //刷新界面的Handler
  • public void handleMessage(Message msg) {
  • switch (msg.what) {
  • case ConstantValues.REFRESH_UI:
  • if (isRefreshUI) {
  • LogUtil.info(DistanceComputeActivity.class, "refresh ui");
  • DistanceInfo mDistanceInfo = mDistanceInfoDao.getById(MyApplication.orderDealInfoId);
  • LogUtil.info(DistanceComputeActivity.class, "界面刷新---> "+mDistanceInfo);
  • if (mDistanceInfo != null) {
  • mTvDistance.setText(String.valueOf(Utils.getValueWith2Suffix(mDistanceInfo.getDistance())));
  • mLng_lat.setText("经:"+mDistanceInfo.getLongitude()+" 纬:"+mDistanceInfo.getLatitude());
  • mTvDistance.invalidate();
  • mLng_lat.invalidate();
  • }
  • }
  • break;
  • }
  • super.handleMessage(msg);
  • }
  • };
  • //定时器,每5秒刷新一次UI
  • private Timer refreshTimer = new Timer(true);
  • private TimerTask refreshTask = new TimerTask() {
  • @Override
  • public void run() {
  • if (isRefreshUI) {
  • Message msg = refreshHandler.obtainMessage();
  • msg.what = ConstantValues.REFRESH_UI;
  • refreshHandler.sendMessage(msg);
  • }
  • }
  • };
  • @Override
  • protected void onCreate(Bundle savedInstanceState) {
  • super.onCreate(savedInstanceState);
  • getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
  • WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);    //保持屏幕常亮
  • setContentView(R.layout.activity_expensecompute);
  • startService(new Intent(this,LocationService.class));   //启动定位服务
  • Toast.makeText(this,"已启动定位服务...", 1).show();
  • init();                                                 //初始化相应控件
  • }
  • private void init(){
  • mTvDistance = (TextView) findViewById(R.id.tv_drive_distance);
  • mDistanceInfoDao = new DistanceInfoDao(this);
  • refreshTimer.schedule(refreshTask, 0, REFRESH_TIME);
  • mButton = (Button)findViewById(R.id.btn_start_drive);
  • mLng_lat = (TextView)findViewById(R.id.longitude_Latitude);
  • }
  • @Override
  • public void onClick(View v) {
  • super.onClick(v);
  • switch (v.getId()) {
  • case R.id.btn_start_drive:      //计算距离button
  • if(isStart)
  • {
  • mButton.setBackgroundResource(R.drawable.btn_selected);
  • mButton.setText("结束计算");
  • isStart = false;
  • DistanceInfo mDistanceInfo = new DistanceInfo();
  • mDistanceInfo.setDistance(0f);                 //距离初始值
  • mDistanceInfo.setLongitude(MyApplication.lng); //经度初始值
  • mDistanceInfo.setLatitude(MyApplication.lat);  //纬度初始值
  • int id = mDistanceInfoDao.insertAndGet(mDistanceInfo);  //将值插入数据库,并获得数据库中最大的id
  • if (id != -1) {
  • MyApplication.orderDealInfoId = id;                 //将id赋值到程序全局变量中(注:该id来决定是否计算移动距离)
  • Toast.makeText(this,"已開始计算...", 0).show();
  • }else{
  • Toast.makeText(this,"id is -1,无法运行距离计算代码块", 0).show();
  • }
  • }else{
  • //自己定义提示框
  • ConfirmDialog dialog = new ConfirmDialog(this, R.style.dialogNoFrame){
  • @Override
  • public void setDialogContent(TextView content) {
  • content.setVisibility(View.GONE);
  • }
  • @Override
  • public void setDialogTitle(TextView title) {
  • title.setText("确认结束计算距离 ?");
  • }
  • @Override
  • public void startMission() {
  • mButton.setBackgroundResource(R.drawable.btn_noselect);
  • mButton.setText("開始计算");
  • isStart = true;
  • isRefreshUI = false;    //停止界面刷新
  • if (refreshTimer != null) {
  • refreshTimer.cancel();
  • refreshTimer = null;
  • }
  • mDistanceInfoDao.delete(MyApplication.orderDealInfoId); //删除id相应记录
  • MyApplication.orderDealInfoId = -1; //停止定位计算
  • Toast.makeText(DistanceComputeActivity.this,"已停止计算...", 0).show();
  • }
  • };
  • dialog.show();
  • }
  • break;
  • }
  • }
  • }
  • 下面是LocationService中的代码,即配置的百度定位sdk代码块,放在继承了service的类中  LocationService.java (方便程序在后台实时更新经纬度)

    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<String>{
    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中点击button时初始化数据库字段
    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. }

    ;                   //数据库版本

  • private static final String DB_NAME = "distance.db";    //数据库名
  • public DBOpenHelper(Context context){                   //创建数据库
  • super(context, DB_NAME, null, VERSION);
  • }
  • @Override
  • public void onCreate(SQLiteDatabase db) {               //创建数据表
  • db.execSQL("CREATE TABLE IF NOT EXISTS milestone(id INTEGER PRIMARY KEY AUTOINCREMENT, distance INTEGER,longitude DOUBLE, latitude DOUBLE )");
  • }
  • @Override
  • public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  //版本发生改变的时
  • db.execSQL("drop table milestone");
  • db.execSQL("CREATE TABLE IF NOT EXISTS milestone(id INTEGER PRIMARY KEY AUTOINCREMENT, distance INTEGER,longitude FLOAT, latitude FLOAT )");
  • }
  • }