专栏首页腾讯位置服务腾讯位置服务GPS轨迹录制-安卓篇
原创

腾讯位置服务GPS轨迹录制-安卓篇

前言

在地图的使用中,尤其在导航场景下,进行GPS轨迹录制是十分必要并且有用的,本文会对于安卓系统下的轨迹录制部分做一个分享。

系统架构

16202923779379.jpg

对于一个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目录

16202872001222.jpg

后续工作

后续可以对于录制的gps文件讲解在导航场景下进行轨迹回放的分享

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 腾讯位置服务GPS轨迹回放-安卓篇

    当我们使用地图进行开发时,利用已经录制好的轨迹进行轨迹回放来检查导航的准确性是十分常用的手段,并且上一篇已经讲完了关于地图使用时GPS轨迹文件的录制,现在对于安...

    腾讯位置服务
  • 腾讯位置服务实现轨迹回放

    在地图接入使用中,很多开发者咨询我们腾讯位置服务是否支持轨迹回放功能,所以今天特意将我们JavaScript API GL的轨迹回放&小车移动示例放到我们本篇文...

    腾讯位置服务
  • 基于腾讯位置服务定位实现物业巡检防作弊场景

    在物业管理中,小区内人员巡检还是非常常见的工作之一,为了降低物业的投入,设计了采用扫描二维码的形式辅助系统检测每个员工巡检的位置,以便进行常规的物业巡检工作。虽...

    腾讯位置服务
  • 车载gps模拟器的使用方法

    GPS模拟器能够模拟出GPS卫星信号运动轨迹,可以模拟GPS卫星导航系统的导航信号,同时也可以仿真任意时间地点和任意姿态的导航终端运动状态,也可以在静态、低动态...

    时频专家
  • 车载gps模拟器的使用方法

    GPS模拟器能够模拟出GPS卫星信号运动轨迹,可以模拟GPS卫星导航系统的导航信号,同时也可以仿真任意时间地点和任意姿态的导航终端运动状态,也可以在静态、低动态...

    时频专家
  • 地图SDK示例中心全新上线,还有一大波功能升级…

    ? “想实现一个微信发送位置这个看似简单的场景,开发起来好像还挺复杂?” “之前没用过地图SDK,但是上线时间紧迫,如何快速搞定地图功能?” “对地图能力不...

    腾讯位置服务
  • gps信号发生器在某汽车公司的应用方案

    GPS信号发生器在某汽车公司成功投运,为该gps信号发生器提供进行选配惯导仿真组件,可同时模拟GPS定位导航授时信号,用于组合导航接收的研发、生成、检定。同时也...

    时频专家
  • GPS信号模拟器应用于共享市场

    我公司生产的GPS信号模拟器投入于共享汽车市场厂家的测试,并成功投入于大量测试应用场景中。本文主要讲了GPS信号模拟器在共享汽车市场的应用的功能体现,对GPS信...

    时频专家
  • gps信号发生器在某汽车公司的应用方案

    GPS信号发生器在某汽车公司成功投运,为该gps信号发生器提供进行选配惯导仿真组件,可同时模拟GPS定位导航授时信号,用于组合导航接收的研发、生成、检定。同时也...

    时频专家

扫码关注云+社区

领取腾讯云代金券