Android开发实现距离位置变化

来源:互联网 发布:java布尔类型的程序 编辑:程序博客网 时间:2024/04/25 07:14

Android开发实现距离位置变化(类似滴滴打车附件的车辆)


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


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

    以下是MainActivity中的代码,通过注释可以理解思路流程.
    [java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
    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?在CODE上查看代码片派生到我的代码片
    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?在CODE上查看代码片派生到我的代码片
    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?在CODE上查看代码片派生到我的代码片
    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?在CODE上查看代码片派生到我的代码片
    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?在CODE上查看代码片派生到我的代码片
    1. package app.model;  
    2. public class GpsLocation {  
    3.     public double lat;//纬度  
    4.     public double lng;//经度  
    5. }  
    将从百度定位中获得的经纬度转换为精准的GPS数据 BDLocation2GpsUtil.java
    [java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
    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

    项目中目前尚有部分不健全的地方,如:
    1.在行驶等待时间较长后,使用TimerTask 、Handler刷新界面是偶尔会出现卡住的现象,车仍在行驶,
    但是数据不动了,通过改善目前测试近7次未出现此问题。
    2.较大的消耗电量,因为定位服务本身就是个消耗电量的玩意
  •  前段时间因为项目需求,通过百度定位adk写了一个实时更新距离的程序(类似大家坐的士时,车上的里程表),遇到很多技术点,总结了一下发表出来和大家相互学习。直接要求定位具体的位置应该是不难的,只需要引入百度定位adk,并配置相关参数就可以完成,显示百度地图也类似,但是如果需要不断的实时显示移动距离,GPS定位从一个点,到第二个点,从第二个点,到第三个点,从第三个点......,移动距离是多少呢?不得不说,要实现这种需求的确存在一定的难度。
  • 目标:使用百度定位sdk开发实时移动距离计算功能,根据经纬度的定位,计算行驶公里数并实时刷新界面显示。
  • 大家都知道定位有三种方式:GPS 、Wifi 、 基站 .
  • 误差方面的话,使用GPS误差在10左右,Wifi则在20 - 300左右 ,而使用基站则误差在100 - 300左右的样子,因为在室内GPS是定位不到的,必须在室外,
  • 而我们项目的需求正好需要使用GPS定位,所以我们这里设置GPS优先。车,不可能在室内跑吧。
0 0
原创粉丝点击