前言
在地圖的使用中朵栖,尤其在導(dǎo)航場(chǎng)景下,進(jìn)行GPS軌跡錄制是十分必要并且有用的朽色,本文會(huì)對(duì)于安卓系統(tǒng)下的軌跡錄制部分做一個(gè)分享酱酬。
系統(tǒng)架構(gòu)
對(duì)于一個(gè)GPSRecordSystem(GPS軌跡錄制系統(tǒng))主要分成3個(gè)部分:開(kāi)始錄制,錄制GPS定位仆救,結(jié)束錄制并存儲(chǔ)抒和,如上圖右方所示。在實(shí)際應(yīng)用中彤蔽,以導(dǎo)航系統(tǒng)為例:(1)在開(kāi)始導(dǎo)航時(shí)(start navi),進(jìn)行錄制工作的相關(guān)配置摧莽;(2)收到安卓系統(tǒng)的onLocationChanged的callback進(jìn)行GPSLocation的記錄;(3)結(jié)束導(dǎo)航(stop navi)時(shí)顿痪,停止記錄并存入文件镊辕。
相關(guān)代碼展示
用到的相關(guān)變量
private LocationManager mLocationManager; // 系統(tǒng)locationManager
private LocationListener mLocationListener; // 系統(tǒng)locationListener
private boolean mIsRecording = false; // 是否正在錄制
private List<String> mGpsList; // 記錄gps的list
private String mRecordFileName; // gps文件名稱(chēng)
- 開(kāi)始錄制
開(kāi)始錄制一般是在整個(gè)系統(tǒng)工作之初油够,比如在導(dǎo)航場(chǎng)景下,當(dāng)“開(kāi)始導(dǎo)航”時(shí)丑蛤,可以開(kāi)始進(jìn)行“startRecordLocation” 的配置
public void startRecordLocation(Context context, String fileName) {
// 已經(jīng)在錄制中不進(jìn)行錄制
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();
}
// 記錄文件名稱(chēng)叠聋,筆者這里使用“realLocationRecord + routeID”形式進(jìn)行記錄
mRecordFileName = fileName;
if (!mRecordFileName.endsWith(".gps")) {
mRecordFileName += ".gps";
}
mIsRecording = true;
}
- 錄制中記錄軌跡
記錄location一般是在獲取安卓系統(tǒng)onLocationChanged回調(diào)時(shí)調(diào)用“recordGPSLocation”
public void recordGPSLocation(Location location) {
if (mIsRecording && location != null) {
// 記錄location to list
mGpsList.add(locationToString(location));
}
}
locationToString工具方法
驅(qū)動(dòng)導(dǎo)航工作的GPS軌跡點(diǎn)一般要包含以下幾個(gè)要素,經(jīng)度受裹,緯度碌补,精度,角度棉饶,速度厦章,時(shí)間,海拔高度照藻,所以在此記錄下袜啃,為后期軌跡回放做準(zhǔn)備。
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();
}
- 結(jié)束錄制并保存gps文件
結(jié)束錄制一般作用在整個(gè)系統(tǒng)的結(jié)尾幸缕,例如在導(dǎo)航場(chǎng)景下群发,“結(jié)束導(dǎo)航”時(shí)停止錄制調(diào)用“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); // 存儲(chǔ)的路徑
String filePath = storagePath + mRecordFileName;
saveGPS(filePath);
mIsRecording = false;
}
GPS軌跡存儲(chǔ)工具方法
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工具方法
// 存儲(chǔ)在跟路徑下/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()) { // 目錄不存在,創(chuàng)建目錄
if (!file.mkdirs()) {
strFolder = context.getFilesDir().getPath() + NAVIGATION_PATH;
file = new File(strFolder);
if (!file.exists()) {
file.mkdirs();
}
}
} else { // 目錄存在发乔,創(chuàng)建文件測(cè)試是否有權(quán)限
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;
}
結(jié)果展示
最終存儲(chǔ)在了手機(jī)目錄下的navigation目錄
后續(xù)工作
后續(xù)可以對(duì)于錄制的gps文件講解在導(dǎo)航場(chǎng)景下進(jìn)行軌跡回放的分享
作者:騰訊位置服務(wù)
鏈接:https://my.oschina.net/u/4209404/blog/5048899
來(lái)源:開(kāi)源中國(guó)
著作權(quán)歸作者所有熟妓。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處栏尚。