共计 4633 个字符,预计需要花费 12 分钟才能阅读完成。
前言
在地图的应用中,尤其在导航场景下,进行 GPS 轨迹录制是十分必要并且有用的,本文会对于安卓零碎下的轨迹录制局部做一个分享。
零碎架构
对于一个 GPSRecordSystem(GPS 轨迹录制零碎)次要分成 3 个局部:开始录制,录制 GPS 定位,完结录制并存储,如上图右方所示。在理论利用中,以导航系统为例:(1)在开始导航时(start navi), 进行录制工作的相干配置;(2)收到安卓零碎的 onLocationChanged 的 callback 进行 GPSLocation 的记录;(3)完结导航(stop navi)时,进行记录并存入文件。
相干代码展现
用到的相干变量
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 轨迹点个别要蕴含以下几个因素,经度,纬度,精度,角度,速度,工夫,海拔高度,所以在此记录下,为前期轨迹回放做筹备。
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”
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 轨迹存储工具办法
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 工具办法
// 存储在跟门路下 /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 目录
后续工作
后续能够对于录制的 gps 文件解说在导航场景下进行轨迹回放的分享
正文完