前言
在地图的使用中,尤为在导航场景下,进行GPS轨迹录制是十分必要而且有用的,本文会对于安卓系统下的轨迹录制部分作一个分享。git
系统架构
对于一个GPSRecordSystem(GPS轨迹录制系统)主要分红3个部分:开始录制,录制GPS定位,结束录制并存储,如上图右方所示。在实际应用中,以导航系统为例:(1)在开始导航时(start navi),进行录制工做的相关配置;(2)收到安卓系统的onLocationChanged的callback进行GPSLocation的记录;(3)结束导航(stop navi)时,中止记录并存入文件。架构
相关代码展现
用到的相关变量app
private LocationManager mLocationManager; // 系统locationManager private LocationListener mLocationListener; // 系统locationListener private boolean mIsRecording = false; // 是否正在录制 private List<String> mGpsList; // 记录gps的list private String mRecordFileName; // gps文件名称
- 开始录制
开始录制通常是在整个系统工做之初,好比在导航场景下,当“开始导航”时,能够开始进行“startRecordLocation” 的配置工具
public void startRecordLocation(Context context, String fileName) { // 已经在录制中不进行录制 if (mIsRecording) { return; } Toast.makeText(context, "start record location...", Toast.LENGTH_SHORT).show(); // 初始化locationManager和locationListener mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); mLocationListener = new MyLocationListener(); try { // 添加listener mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener); } catch (SecurityException e) { Toast.makeText(context, "start record location error!!!", Toast.LENGTH_SHORT).show(); Log.e(TAG, "startRecordLocation Exception", e); e.printStackTrace(); } // 记录文件名称,笔者这里使用“realLocationRecord + routeID”形式进行记录 mRecordFileName = fileName; if (!mRecordFileName.endsWith(".gps")) { mRecordFileName += ".gps"; } mIsRecording = true; }
- 录制中记录轨迹 记录location通常是在获取安卓系统onLocationChanged回调时调用“recordGPSLocation”
public void recordGPSLocation(Location location) { if (mIsRecording && location != null) { // 记录location to list mGpsList.add(locationToString(location)); } }
locationToString工具方法测试
驱动导航工做的GPS轨迹点通常要包含如下几个要素,经度,纬度,精度,角度,速度,时间,海拔高度,因此在此记录下,为后期轨迹回放作准备。ui
private String locationToString(Location location) { StringBuilder sb = new StringBuilder(); long time = System.currentTimeMillis(); String timeStr = gpsDataFormatter.format(new Date(time)); sb.append(location.getLatitude()); sb.append(","); sb.append(location.getLongitude()); sb.append(","); sb.append(location.getAccuracy()); sb.append(","); sb.append(location.getBearing()); sb.append(","); sb.append(location.getSpeed()); sb.append(","); sb.append(timeStr); sb.append(","); sb.append(df.format((double) time / 1000.0)); // sb.append(df.format(System.currentTimeMillis()/1000.0)); // sb.append(df.format(location.getTime()/1000.0)); sb.append(","); sb.append(location.getAltitude()); sb.append("\n"); return sb.toString(); }
- 结束录制并保存gps文件
结束录制通常做用在整个系统的结尾,例如在导航场景下,“结束导航”时中止录制调用“stopRecordLocation”code
public void stopRecordLocation(Context context) { Toast.makeText(context, "stop record location, save to file...", Toast.LENGTH_SHORT).show(); // 移除listener mLocationManager.removeUpdates(mLocationListener); String storagePath = StorageUtil.getStoragePath(context); // 存储的路径 String filePath = storagePath + mRecordFileName; saveGPS(filePath); mIsRecording = false; }
GPS轨迹存储工具方法orm
private void saveGPS(String path) { OutputStreamWriter writer = null; try { File outFile = new File(path); File parent = outFile.getParentFile(); if (parent != null && !parent.exists()) { parent.mkdirs(); } OutputStream out = new FileOutputStream(outFile); writer = new OutputStreamWriter(out); for (String line : mGpsList) { writer.write(line); } } catch (Exception e) { Log.e(TAG, "saveGPS Exception", e); e.printStackTrace(); } finally { if (writer != null) { try { writer.flush(); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "Failed to flush output stream", e); } try { writer.close(); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "Failed to close output stream", e); } } } }
StorageUtil的getStoragePath工具方法blog
// 存储在跟路径下/TencentMapSDK/navigation private static final String NAVIGATION_PATH = "/tencentmapsdk/navigation"; // getStoragePath工具方法 public static String getStoragePath(Context context) { if (context == null) { return null; } String strFolder; boolean hasSdcard; try { hasSdcard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); } catch (Exception e) { Log.e(TAG, "getStoragePath Exception", e); e.printStackTrace(); hasSdcard = false; } if (!hasSdcard) { strFolder = context.getFilesDir().getPath() + NAVIGATION_PATH; File file = new File(strFolder); if (!file.exists()) { file.mkdirs(); } } else { strFolder = Environment.getExternalStorageDirectory().getPath() + NAVIGATION_PATH; File file = new File(strFolder); if (!file.exists()) { // 目录不存在,建立目录 if (!file.mkdirs()) { strFolder = context.getFilesDir().getPath() + NAVIGATION_PATH; file = new File(strFolder); if (!file.exists()) { file.mkdirs(); } } } else { // 目录存在,建立文件测试是否有权限 try { String newFile = strFolder + "/.test"; File tmpFile = new File(newFile); if (tmpFile.createNewFile()) { tmpFile.delete(); } } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "getStoragePath Exception", e); strFolder = context.getFilesDir().getPath() + NAVIGATION_PATH; file = new File(strFolder); if (!file.exists()) { file.mkdirs(); } } } } return strFolder; }
结果展现
最终存储在了手机目录下的navigation目录rem
后续工做
后续能够对于录制的gps文件讲解在导航场景下进行轨迹回放的分享