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

  1. import app.utils.BDLocation2GpsUtil;

  2. import app.utils.FileUtils;

  3. import app.utils.LogUtil;

  4. import com.baidu.location.BDLocation;

  5. import com.baidu.location.BDLocationListener;

  6. import com.baidu.location.LocationClient;

  7. import com.baidu.location.LocationClientOption;

  8. import com.computedistance.DistanceComputeInterface;

  9. import com.computedistance.impl.DistanceComputeImpl;

  10. public class LocationService extends Service {

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

  12. LocationClient mLocClient;

  13. private Object lock = new Object();

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

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

  16. private MyLocationListenner myListener = new MyLocationListenner();

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

  18. private DistanceInfoDao mDistanceInfoDao;

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

  20. @Override

  21. public IBinder onBind(Intent intent) {

  22. return null;

  23. }

  24. @Override

  25. public void onCreate() {

  26. super.onCreate();

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

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

  29. mLocClient = new LocationClient(this);

  30. mLocClient.registerLocationListener(myListener);

  31. //定位参数设置

  32. LocationClientOption option = new LocationClientOption();

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

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

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

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

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

  38. option.setOpenGps(true);

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

  40. mLocClient.setLocOption(option);

  41. mLocClient.start();

  42. mLocClient.requestLocation();

  43. }

  44. @Override

  45. @Deprecated

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

  47. super.onStart(intent, startId);

  48. }

  49. @Override

  50. public void onDestroy() {

  51. super.onDestroy();

  52. if (null != mLocClient) {

  53. mLocClient.stop();

  54. }

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

  56. }

  57. private class Task implements Callable{

  58. private BDLocation location;

  59. public Task(BDLocation location){

  60. this.location = location;

  61. }

  62. /**

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

  64. *

  65. * @param distance

  66. * @return

  67. */

  68. private boolean noMove(float distance){

  69. if (distance < 0.01) {

  70. return true;

  71. }

  72. return false;

  73. }

  74. /**

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

  76. *

  77. * @param distance

  78. * @return

  79. */

  80. private boolean checkProperMove(float distance){

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

  82. return true;

  83. }else{

  84. return false;

  85. }

  86. }

  87. /**

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

  89. *

  90. * @param location

  91. * @return

  92. */

  93. private boolean checkProperLocation(BDLocation location){

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

  95. return true;

  96. }

  97. return false;

  98. }

  99. @Override

  100. public String call() throws Exception {

  101. synchronized (lock) {

  102. if (!checkProperLocation(location)){

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

  104. discard++;

  105. return null;

  106. }

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

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

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

  110. {

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

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

  113. if (tempGpsLocation != null) {

  114. currentGpsLocation = tempGpsLocation;

  115. }else{

  116. discard ++;

  117. }

  118. //日志

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

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

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

  122. /** 计算距离  */

  123. float distance = 0.0f;

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

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

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

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

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

  129. float drivedDistance = mDistanceInfo.getDistance();

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

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

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

  133. //日志记录

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

  135. mDistanceInfoDao.updateDistance(mDistanceInfo);

  136. discard = 1;

  137. }

  138. }

  139. prevGpsLocation = currentGpsLocation;

  140. }

  141. }

  142. return null;

  143. }

  144. }

  145. }

  146. /**

  147. * 定位SDK监听函数

  148. */

  149. public class MyLocationListenner implements BDLocationListener {

  150. @Override

  151. public void onReceiveLocation(BDLocation location) {

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

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

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

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

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

  157. {

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

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

  160. }

  161. }

  162. public void onReceivePoi(BDLocation poiLocation) {

  163. if (poiLocation == null){

  164. return ;

  165. }

  166. }

  167. }

  168. }

以下是应用中需要使用的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 getMaxId() {

  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”)));

  57. }

  58. cursor.close();

  59. db.close();

  60. return mDistanceInfo;

  61. }

  62. /**

  63. * 更新距离

  64. * @param orderDealInfo

  65. */

  66. public void updateDistance(DistanceInfo mDistanceInfo) {

  67. if (mDistanceInfo == null) {

  68. return;

  69. }

  70. db = helper.getWritableDatabase();

  71. String sql = “update milestone set distance=”+ mDistanceInfo.getDistance() +“,longitude=”+mDistanceInfo.getLongitude()+“,latitude=”+mDistanceInfo.getLatitude()+" where id = "+ mDistanceInfo.getId();

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

  73. db.execSQL(sql);

  74. db.close();

  75. }

  76. }

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

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

  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. public int getId() {

  8. return id;

  9. }

  10. public void setId(int id) {

  11. this.id = id;

  12. }

  13. public float getDistance() {

  14. return distance;

  15. }

  16. public void setDistance(float distance) {

  17. this.distance = distance;

  18. }

  19. public double getLongitude() {

  20. return longitude;

  21. }

  22. public void setLongitude(double longitude) {

  23. this.longitude = longitude;

  24. }

  25. public double getLatitude() {

  26. return latitude;

  27. }

  28. public void setLatitude(double latitude) {

  29. this.latitude = latitude;

  30. }

  31. @Override

  32. public String toString() {

  33. return “DistanceInfo [id=” + id + “, distance=” + distance

  34. + “, longitude=” + longitude + “, latitude=” + latitude + “]”;

  35. }

  36. }

保存经纬度信息的类 GpsLocation

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

  1. package app.model;

  2. public class GpsLocation {

  3. public double lat;//纬度

  4. public double lng;//经度

  5. }

将从百度定位中获得的经纬度转换为精准的GPS数据 BDLocation2GpsUtil.java

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

  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{  
    自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

结语

网上高级工程师面试相关文章鱼龙混杂,要么一堆内容,要么内容质量太浅, 鉴于此我整理了上述安卓开发高级工程师面试题以及答案。希望帮助大家顺利进阶为高级工程师。
目前我就职于某大厂安卓高级工程师职位,在当下大环境下也想为安卓工程师出一份力,通过我的技术经验整理了面试经常问的题,答案部分是一篇文章或者几篇文章,都是我认真看过并且觉得不错才整理出来。

大家知道高级工程师不会像刚入门那样被问的问题一句话两句话就能表述清楚,所以我通过过滤好文章来帮助大家理解。

1307页字节跳动Android面试真题解析火爆全网,完整版开放下载

现在都说互联网寒冬,其实只要自身技术能力够强,咱们就不怕!我这边专门针对Android开发工程师整理了一套【Android进阶学习视频】、【全套Android面试秘籍】、【Android知识点PDF】。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

[外链图片转存中…(img-ZdzfVM4M-1712209347180)]

[外链图片转存中…(img-rTVaLwz3-1712209347180)]

[外链图片转存中…(img-4EdclFX2-1712209347180)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

结语

网上高级工程师面试相关文章鱼龙混杂,要么一堆内容,要么内容质量太浅, 鉴于此我整理了上述安卓开发高级工程师面试题以及答案。希望帮助大家顺利进阶为高级工程师。
目前我就职于某大厂安卓高级工程师职位,在当下大环境下也想为安卓工程师出一份力,通过我的技术经验整理了面试经常问的题,答案部分是一篇文章或者几篇文章,都是我认真看过并且觉得不错才整理出来。

大家知道高级工程师不会像刚入门那样被问的问题一句话两句话就能表述清楚,所以我通过过滤好文章来帮助大家理解。

[外链图片转存中…(img-t45ui81r-1712209347180)]

现在都说互联网寒冬,其实只要自身技术能力够强,咱们就不怕!我这边专门针对Android开发工程师整理了一套【Android进阶学习视频】、【全套Android面试秘籍】、【Android知识点PDF】。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 23
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值