騰訊地圖GPS軌跡錄制

前言

在地圖的使用中朵栖,尤其在導(dǎo)航場(chǎng)景下,進(jìn)行GPS軌跡錄制是十分必要并且有用的朽色,本文會(huì)對(duì)于安卓系統(tǒng)下的軌跡錄制部分做一個(gè)分享酱酬。

系統(tǒng)架構(gòu)

16202923779379.jpg

對(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目錄

16202872001222.jpg

后續(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)注明出處栏尚。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末起愈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子译仗,更是在濱河造成了極大的恐慌抬虽,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纵菌,死亡現(xiàn)場(chǎng)離奇詭異阐污,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)咱圆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)疤剑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人闷堡,你說(shuō)我怎么就攤上這事∫晒剩” “怎么了杠览?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)纵势。 經(jīng)常有香客問(wèn)我踱阿,道長(zhǎng)管钳,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任软舌,我火速辦了婚禮才漆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘佛点。我一直安慰自己醇滥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布超营。 她就那樣靜靜地躺著鸳玩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪演闭。 梳的紋絲不亂的頭發(fā)上不跟,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天,我揣著相機(jī)與錄音米碰,去河邊找鬼窝革。 笑死,一個(gè)胖子當(dāng)著我的面吹牛吕座,可吹牛的內(nèi)容都是我干的虐译。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼米诉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼菱蔬!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起史侣,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拴泌,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后惊橱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蚪腐,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年税朴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了回季。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡正林,死狀恐怖泡一,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情觅廓,我是刑警寧澤鼻忠,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站杈绸,受9級(jí)特大地震影響帖蔓,放射性物質(zhì)發(fā)生泄漏矮瘟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一塑娇、第九天 我趴在偏房一處隱蔽的房頂上張望澈侠。 院中可真熱鬧,春花似錦埋酬、人聲如沸哨啃。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)棘催。三九已至,卻和暖如春耳标,著一層夾襖步出監(jiān)牢的瞬間醇坝,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工次坡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呼猪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓砸琅,卻偏偏與公主長(zhǎng)得像宋距,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子症脂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容