前言

在地图的应用中,尤其在导航场景下,进行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文件解说在导航场景下进行轨迹回放的分享