張 斌, 鄔曉靜, 邵 想, 張 帥
(鄭州大學(xué) 軟件學(xué)院, 鄭州 450002)
基于Android的防走失系統(tǒng)是指通過移動(dòng)設(shè)備對(duì)人的位置坐標(biāo)進(jìn)行GPS定位,通過位置校驗(yàn)算法提取精確位置信息,并對(duì)實(shí)時(shí)上傳的數(shù)據(jù)進(jìn)行分析處理,達(dá)到實(shí)時(shí)監(jiān)控的目的。該技術(shù)在車載導(dǎo)航、測(cè)繪、軍事等領(lǐng)域已有廣泛應(yīng)用。老人兒童安全問題一直是一個(gè)社會(huì)熱點(diǎn)問題,艾瑞發(fā)布的《2019年中國(guó)親子陪伴質(zhì)量研究報(bào)告》中指出,2008年來中國(guó)宏觀經(jīng)濟(jì)增速放緩,已婚人群養(yǎng)老與撫養(yǎng)孩子的壓力更加明顯[1],陪伴老人與孩子的時(shí)間也越來越少。雖然市面上已有的防走失定位產(chǎn)品很多,但依賴于第三方設(shè)備的定位產(chǎn)品在續(xù)航時(shí)間、價(jià)格成本、快速升級(jí)等方面有明顯的局限性。在2017~2018年中,智能手機(jī)在所有年齡段的普及率、覆蓋率不斷增長(zhǎng)[2],超過九成的人不會(huì)在進(jìn)行家庭活動(dòng)時(shí)關(guān)閉自己的移動(dòng)設(shè)備[3]。智能手機(jī)具有系統(tǒng)升級(jí)快,價(jià)格低廉等優(yōu)點(diǎn),而且Android6.0可使設(shè)備續(xù)航時(shí)間提升30%。基于Android的防走失系統(tǒng)能夠精確定位、自動(dòng)報(bào)警、幫助用戶快速導(dǎo)航到老人兒童身邊,保障老人兒童出行安全,滿足人們需求,同時(shí)其在各個(gè)層面相互獨(dú)立便于后續(xù)開發(fā)與維護(hù)。
系統(tǒng)Android端使用IntelliJ IDEA 2019為開發(fā)工具,基于kotlin語言,結(jié)合MVP(Model-View-Presenter)設(shè)計(jì)模式,采用Nv-websocket-client+Okhttp+Gson框架,在使用Android SDK 27的基礎(chǔ)上,兼容Android6.0及以上版本,實(shí)現(xiàn)了實(shí)時(shí)定位、軌跡回放、強(qiáng)制錄音、電子圍欄等功能。
Android系統(tǒng)會(huì)為每個(gè)程序運(yùn)行時(shí)創(chuàng)建一個(gè)單例(singleton)模式的Application類,且其生命周期等于此程序生命周期,所以可以通過Application來進(jìn)行權(quán)限申請(qǐng)、數(shù)據(jù)共享、數(shù)據(jù)緩存等操作。程序首次運(yùn)行時(shí)申請(qǐng)如下權(quán)限。
(1)授予用于進(jìn)行網(wǎng)絡(luò)定位的權(quán)限。此時(shí)需用到設(shè)計(jì)代碼為:
android.permission.ACCESS_COARSE_LOCATION
(2)授予該程序向外部?jī)?chǔ)存器寫入數(shù)據(jù)的權(quán)限。此時(shí)需用到設(shè)計(jì)代碼為:
android.permission.WRITE_EXTERNAL_STORAGE
(3)授予該程序錄制聲音的權(quán)限。此時(shí)需用到設(shè)計(jì)代碼為:
android.permission.RECORD_AUDIO
(4)程序在手機(jī)屏幕關(guān)閉后,后臺(tái)進(jìn)程仍然運(yùn)行。此時(shí)需用到設(shè)計(jì)代碼為:
android.permission.ACCESS_FINE_LOCATION等。
在Application中建立2個(gè)HashMap用于Activity之間進(jìn)行數(shù)據(jù)傳遞和緩存用戶數(shù)據(jù),同時(shí)將緩存的數(shù)據(jù)經(jīng)過MD5算法進(jìn)行加密處理緩存到本地,既保證用戶數(shù)據(jù)安全性,也預(yù)防出現(xiàn)程序意外中斷導(dǎo)致數(shù)據(jù)丟失情況,避免用戶打開應(yīng)用重復(fù)登錄,提高人機(jī)交互友好性,實(shí)現(xiàn)后臺(tái)實(shí)時(shí)定位的功能。
在Application的onCreate()的方法中通過LogUtil.logoff=false,設(shè)置屏蔽打印;LogUtil.level=log.ERROE,指定把高于或等于Error的信息保存到sdcard日志文件中;LogUtil.saveDirName= "/ GuardianshipModify/log/"指定錯(cuò)誤信息日志目錄。LogUtil.trace(inttype, Stringtag, Stringmsg, booleanisContinueWrite)中 type:log的類型(ERROR,WARN等),tag:輸出標(biāo)志,msg:輸出日志,isContinueWrite:true(默認(rèn)),表示繼續(xù)在原有文件寫入,若為false則表示創(chuàng)建一個(gè)新的覆蓋原來的文件。如果原來并沒有創(chuàng)建過,則無論是false,還是true都會(huì)創(chuàng)建一個(gè)新文件。globalExceptionHandler.setUncatchExceptionListener()可以回調(diào)處理程序崩潰后自定義的用戶操作,如上傳錯(cuò)誤信息,保存數(shù)據(jù)信息等操作。
EventBus提供了PostThread(當(dāng)前線程)、MainThread(主線程)、BackgroundThread(后臺(tái)線程)和Async(異步線程)四種線程模式,是Android下高效的發(fā)布/訂閱事件的消息總線。因此,本系統(tǒng)采用此對(duì)象代替?zhèn)鹘y(tǒng)的Intent,Handler,Broadcast或接口函數(shù)在Fragment、Activity、Service和線程之間傳遞數(shù)據(jù)并執(zhí)行方法。EventBus有3個(gè)主要元素,分別是:Event(事件)、Subscriber(事件訂閱者,接受特定的事件)和Publisher(事件發(fā)布者,用于通知Subscriber有事件發(fā)生)。
1.2.1 客戶端發(fā)送請(qǐng)求設(shè)計(jì)
NetworkManager通信管理類是一個(gè)重量級(jí)類,采用單例模式,用于管理頻繁出現(xiàn)的網(wǎng)絡(luò)請(qǐng)求。該管理類把請(qǐng)求分發(fā)給目標(biāo)業(yè)務(wù)邏輯組件去處理,目標(biāo)業(yè)務(wù)邏輯組件根據(jù)相應(yīng)的請(qǐng)求調(diào)用相應(yīng)的方法去執(zhí)行,通過JSON接口和繼承的方式利用Gson框架將請(qǐng)求對(duì)象和返回對(duì)象設(shè)計(jì)為JSON對(duì)象。由于Socket通信[4]具有傳輸數(shù)據(jù)量小(費(fèi)用低)、傳輸時(shí)間短、性能高、適合于客戶端和服務(wù)器之間信息實(shí)時(shí)交互、可以加密、數(shù)據(jù)安全性強(qiáng)等優(yōu)點(diǎn),因此研究采用以Socket通信為主、Http通信[5]為輔的通信機(jī)制。請(qǐng)求過程如下:
Step 1準(zhǔn)備請(qǐng)求。在請(qǐng)求對(duì)象中加入seqId(實(shí)現(xiàn)當(dāng)服務(wù)器響應(yīng)長(zhǎng)連接請(qǐng)求時(shí)能夠找到對(duì)應(yīng)的回調(diào))和reqCount(記錄請(qǐng)求超時(shí)次數(shù))兩個(gè)參數(shù),同時(shí)添加超時(shí)任務(wù)并且將該請(qǐng)求的回調(diào)添加到回調(diào)集合。
Step 2開始請(qǐng)求。請(qǐng)求成功或者失敗都通過seqId找到對(duì)應(yīng)回調(diào)執(zhí)行并從回調(diào)集合中移除該回調(diào),再取消超時(shí)任務(wù)。如果超時(shí)則判斷當(dāng)前請(qǐng)求次數(shù),當(dāng)前請(qǐng)求次數(shù)小于或等于3次時(shí)則再次通過WebSocket發(fā)送請(qǐng)求;當(dāng)前請(qǐng)求次數(shù)大于3次時(shí)則走Http補(bǔ)償通道,并根據(jù)請(qǐng)求成功或失敗情況執(zhí)行對(duì)應(yīng)回調(diào)。客戶端發(fā)送請(qǐng)求過程圖如圖1所示。

圖1 客戶端發(fā)送請(qǐng)求過程圖
1.2.2 授權(quán)、心跳和重連循環(huán)設(shè)計(jì)
為實(shí)現(xiàn)服務(wù)器端向客戶端主動(dòng)發(fā)送通知,客戶端需要在用戶進(jìn)行登錄后嘗試建立連接,建立連接成功后進(jìn)行授權(quán),授權(quán)就是發(fā)送一個(gè)攜帶用戶信息的請(qǐng)求,而在服務(wù)器端通過這個(gè)請(qǐng)求后驗(yàn)證用戶信息,驗(yàn)證成功后服務(wù)器端就知道當(dāng)前長(zhǎng)連接屬于哪個(gè)用戶。授權(quán)成功后開始心跳。心跳是指每隔一段時(shí)間,服務(wù)器端發(fā)送請(qǐng)求,如果服務(wù)器端有響應(yīng),就認(rèn)為這條連接是穩(wěn)定的。心跳連接成功后進(jìn)行數(shù)據(jù)同步,如果心跳連續(xù)失敗三次或嘗試建立連接失敗則開始繼續(xù)嘗試重連。當(dāng)重連成功后會(huì)再次進(jìn)行授權(quán),然后再次開啟心跳,至此形成了一個(gè)循環(huán)。如果多次重連失敗后系統(tǒng)會(huì)向用戶發(fā)送通知,提醒用戶檢查當(dāng)前網(wǎng)絡(luò)狀態(tài)。授權(quán)、心跳和重連循環(huán)過程如圖2所示。

圖2 授權(quán)、心跳和重連循環(huán)過程圖
Fig. 2 Diagram of authorization, heartbeat, and reconnection cycles
Android端依托于百度地圖Android SDK,采用BD09坐標(biāo)系實(shí)現(xiàn)繪制定位。BD09坐標(biāo)系是在GCJ02坐標(biāo)系(國(guó)家測(cè)繪局)[6]基礎(chǔ)上再次加密形成的,具有高度的可靠性和安全性,可以更好地保護(hù)用戶個(gè)人隱私,防止位置信息泄露。百度地圖服務(wù)具有高精度、覆蓋廣、功耗低、支持電子圍欄和室內(nèi)定位等優(yōu)點(diǎn),并為開發(fā)者提供了簡(jiǎn)單易用且功能豐富的操作接口。
1.3.1 地圖繪制和數(shù)據(jù)處理
項(xiàng)目導(dǎo)入百度地圖jar包[7]并在Application類中初始化Android SDK[8]。SDK會(huì)產(chǎn)生mapView和baiduMap兩個(gè)對(duì)象,分別用于顯示和控制地圖元素。
被監(jiān)護(hù)用戶登錄App之后,系統(tǒng)會(huì)為其創(chuàng)建一個(gè)對(duì)象,并初始化運(yùn)動(dòng)軌跡。用戶使用系統(tǒng)期間,地圖會(huì)實(shí)時(shí)顯示當(dāng)前位置和正前方的方位。用戶產(chǎn)生的運(yùn)動(dòng)信息會(huì)被存儲(chǔ)到對(duì)象中,通過SecureData類進(jìn)行數(shù)據(jù)格式化,而后被系統(tǒng)存儲(chǔ)到本地的track.xml文件里。系統(tǒng)根據(jù)上傳機(jī)制將track.xml文件上傳到服務(wù)器。
監(jiān)護(hù)端可以查看被監(jiān)護(hù)端當(dāng)前位置和運(yùn)動(dòng)軌跡,位置信息由Download類從服務(wù)器上下載track.xml文件,經(jīng)過SecureData類解析為數(shù)據(jù)信息。系統(tǒng)通過mapView對(duì)象將解析后的數(shù)據(jù)繪制為被監(jiān)護(hù)端的位置點(diǎn)和運(yùn)動(dòng)軌跡。
1.3.2 運(yùn)動(dòng)軌跡監(jiān)測(cè)
系統(tǒng)調(diào)用百度地圖API接口時(shí)存在定位精度[9]的問題,可能會(huì)產(chǎn)生錯(cuò)誤的位置信息。為了防止錯(cuò)誤的位置信息被記錄到運(yùn)動(dòng)軌跡中,研究特別設(shè)計(jì)了位置校驗(yàn)算法。
當(dāng)設(shè)備信號(hào)不良時(shí),百度地圖定位時(shí)會(huì)出現(xiàn)跳躍現(xiàn)象,地圖定位會(huì)產(chǎn)生一定程度的偏差,這個(gè)錯(cuò)誤的定位點(diǎn)被稱為跳躍點(diǎn)。跳躍點(diǎn)的位置和實(shí)際位置相差約5~10 m(1 m相當(dāng)于0.000 01°經(jīng)緯度[10]),可根據(jù)經(jīng)緯度的瞬時(shí)變化檢測(cè)當(dāng)前定位點(diǎn)是否屬于跳躍點(diǎn)。當(dāng)被監(jiān)護(hù)端處于高速移動(dòng)時(shí),間隔定位點(diǎn)的距離可能會(huì)和跳躍點(diǎn)變化相似。但跳躍點(diǎn)是瞬時(shí)變化,高速移動(dòng)是持續(xù)性變化,據(jù)此可區(qū)分跳躍點(diǎn)和高速點(diǎn)。研發(fā)判斷是否為有效軌跡點(diǎn)代碼詳見如下。
varhighSpeedSign= 10,error= 0
valLatOffsetLimit= 0.000 1,LonOffsetLimit= 0.001
varoffsetList:MutableList
funsavePos(currentPos:LatLng,lastPos:LatLng){
//兒童未進(jìn)行移動(dòng)
if (currentPos==lastPos) return
varoffsetlati= Math.abs(currentPos.latitude-lastPos.latitude)
varoffsetlong= Math.abs(currentPos.longitude-lastPos.longitude)
valsavePos=offsetlati if (savePos) {//有效軌跡點(diǎn) if(error!= 0){ if (highSpeedSign for (iinoffsetList) motionList.add(i) error= 0 //清空錯(cuò)誤軌跡點(diǎn)信息 offsetList.clear()} emotionList.add(currentPos) }else{ //無效軌跡點(diǎn) error=error+ 1 offsetList.add(lastPos)}} Web服務(wù)器端基于Java語言,采用Spring Boot框架[11],使用百度地圖API接口,前端使用Bootstrap框架,數(shù)據(jù)庫使用MongoDB[12],來實(shí)現(xiàn)數(shù)據(jù)分析、信息管理、定位與錄音管理、地圖展示等功能。 Spring Boot框架簡(jiǎn)化新Spring應(yīng)用的初始搭建及開發(fā)過程,不再需要定義樣板化配置,也無需部署WAR文件,簡(jiǎn)化Maven配置提供生產(chǎn)就緒功能,為客戶端提供數(shù)據(jù)訪問接口和處理機(jī)制[13]。客戶端通過URL調(diào)用Spring Boot方法的過程如下: (1)指定Controller方法名,并添加@RequestMapping(兼容接受POST和GET請(qǐng)求)注解。 (2)通過@RequestParam 和@PathVariable設(shè)置參數(shù)。 (3)客戶端通過HttpGet或者HttpPost請(qǐng)求訪問服務(wù)端資源。 (4)服務(wù)端接受請(qǐng)求并通過@ControllerAdvice進(jìn)行全局錯(cuò)誤驗(yàn)證,并返回結(jié)果。 系統(tǒng)數(shù)據(jù)服務(wù)器采用Spring Boot內(nèi)置Tomcat,連接DataSource數(shù)據(jù)源[14]。使用MVC分層,各個(gè)層面單獨(dú)開發(fā)并提供訪問接口(TrackService、PositionDao等),便于后期開發(fā)和維護(hù)。具體分層如下: (1)View層。根據(jù)接收到的數(shù)據(jù)展示頁面給用戶。 (2)Controller層。響應(yīng)用戶請(qǐng)求(@RequestMapping(value ="/updatesetting")、@RequestMapping(value ="/modifyGuardian")等)。 (3)Service層。即為業(yè)務(wù)邏輯層,通過調(diào)用DAO層的底層數(shù)據(jù)操作完成用戶訪問所要求的業(yè)務(wù)邏輯。 (4)DAO層。把數(shù)據(jù)放到持久化的介質(zhì)中,提供增刪改查[15]操作。 (5)Module層。存放實(shí)體類,并與數(shù)據(jù)庫中的屬性值基本保持一致。 由于客戶端需要頻繁訪問服務(wù)端,采用Spring Boot線程池能夠顯著提升服務(wù)端的穩(wěn)定性。Spring Boot使用ThreadPoolExecutor線程池 + Queue隊(duì)列。設(shè)定線程最大數(shù)量和隊(duì)列大小,當(dāng)周期上傳的線程池滿,就進(jìn)入緩沖隊(duì)列,線程結(jié)束或超時(shí)之后,就從線程池中刪除線程,從緩沖隊(duì)列中按序調(diào)用新線程。Spring Boot線程池流程如圖3所示。 圖3 Spring Boot線程池流程圖 為實(shí)現(xiàn)對(duì)用戶多條定位信息、軌跡信息以及錄音信息的高效管理,系統(tǒng)設(shè)計(jì)采用非關(guān)系型數(shù)據(jù)庫MongoDB。MongoDB具有查詢速度快、高并發(fā)(可達(dá)2萬并發(fā))、高容量(支持10 TB以上數(shù)據(jù)量)的優(yōu)點(diǎn)。MongoDB能有效提高系統(tǒng)抗壓性。MongoDB在項(xiàng)目中使用過程如下: (1)在pom文件引入spring-boot-starter-data-mongodb相關(guān)依賴。 (2)在application.properties中添加配置: spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test。 (3)創(chuàng)建Track、Position等實(shí)體。 (4)實(shí)現(xiàn)TrackDao、PositionDao等的增刪改查操作(加入@Component注解)。 數(shù)據(jù)控制層提供的數(shù)據(jù)服務(wù)接口返回格式是application/json,數(shù)據(jù)接口通過方法注解提供訪問方式、查看軌跡方法@RequestMapping(value ="/trackplayback")和上傳定位錄音方法@RequestMapping("/upload")等。服務(wù)器數(shù)據(jù)管理如圖4所示。 圖4 服務(wù)器數(shù)據(jù)管理圖 通過HTML5+JavaScript+百度地圖API實(shí)現(xiàn)定位錄音信息管理和軌跡回放功能。 通過請(qǐng)求對(duì)象中的account和datetime參數(shù)查詢被監(jiān)護(hù)人的信息并加工為position對(duì)象返回給前端,View層將position對(duì)象轉(zhuǎn)化為JavaScript數(shù)組作為標(biāo)注,使用百度地圖API中BMap的Marker添加標(biāo)注,并通過BMap中InfoWindow為標(biāo)注添加信息,信息以標(biāo)注形式展示,點(diǎn)擊可查詢其對(duì)應(yīng)的地點(diǎn)名稱(精確到街道、門牌號(hào))和同步上傳的錄音,錄音文件通過MongoDB數(shù)據(jù)庫訪問服務(wù)器錄音文件下載播放。 軌跡回放則通過被監(jiān)護(hù)人id查詢數(shù)據(jù)并格式化為L(zhǎng)ist 防走失定位錄音系統(tǒng)旨在為用戶提供一個(gè)通過手機(jī)實(shí)現(xiàn)定位錄音的功能,利用手機(jī)方便攜帶,易于訪問網(wǎng)絡(luò)的特點(diǎn),為老人兒童的出行提供安全保障。客戶端分為監(jiān)護(hù)端與被監(jiān)護(hù)端,其中被監(jiān)護(hù)端賬號(hào)密碼由監(jiān)護(hù)端創(chuàng)建并自動(dòng)綁定,保障被監(jiān)護(hù)端的安全性。 Android客戶端設(shè)置了主動(dòng)上傳、強(qiáng)制上傳和周期上傳3種通信上傳方式實(shí)現(xiàn)對(duì)被監(jiān)護(hù)端的實(shí)時(shí)監(jiān)測(cè)。客戶端的功能劃分為6個(gè)基本模塊: (1)實(shí)時(shí)定位:監(jiān)護(hù)人可查看被監(jiān)護(hù)人實(shí)時(shí)位置,也可快速導(dǎo)航到被監(jiān)護(hù)人身邊。 (2)電子圍欄:監(jiān)護(hù)人可通過創(chuàng)建家、學(xué)校、社區(qū)等電子圍欄來將被監(jiān)護(hù)人設(shè)定在安全的圍欄內(nèi),防止被監(jiān)護(hù)人走失或發(fā)生其他意外等。 (3)軌跡回放:可以滿足監(jiān)護(hù)人及時(shí)了解被監(jiān)護(hù)人之前的活動(dòng)情況。 (4)強(qiáng)制錄音:突發(fā)意外時(shí),監(jiān)護(hù)人可以強(qiáng)制錄音以便聽取被監(jiān)護(hù)人現(xiàn)場(chǎng)聲音信息,進(jìn)行及時(shí)處理。 (5)多人監(jiān)控:該模塊主要滿足多個(gè)監(jiān)護(hù)人對(duì)同一個(gè)被監(jiān)護(hù)人或一個(gè)監(jiān)護(hù)人對(duì)多個(gè)被監(jiān)護(hù)人同時(shí)監(jiān)控的需求。 (6)模式設(shè)置:設(shè)置被監(jiān)護(hù)端上傳定位錄音的模式、周期與錄音時(shí)長(zhǎng)。 服務(wù)端的功能劃分為4個(gè)模塊: (1)網(wǎng)站分析:采用Chart.js插件統(tǒng)計(jì)用戶分布和定位數(shù)量。 (2)用戶信息管理:通過BootStrap框架展示用戶信息,并向管理員提供數(shù)據(jù)管理和備份功能。 (3)定位與錄音管理:將系統(tǒng)數(shù)據(jù)庫中的定位與錄音信息提取出來并展示,管理員可以對(duì)定位與錄音進(jìn)行管理。 (4)地圖展示:用于查詢某個(gè)用戶指定時(shí)間所處位置以及錄音內(nèi)容,同時(shí)提供用戶的軌跡回放。地圖展示如圖5所示。 圖5 地圖展示界面 通過對(duì)Android系統(tǒng)架構(gòu)的研究,應(yīng)用MVP設(shè)計(jì)模式,設(shè)計(jì)并實(shí)現(xiàn)一款基于Android的防走失系統(tǒng)。該系統(tǒng)能夠應(yīng)用在移動(dòng)設(shè)備上,并且充分利用硬件系統(tǒng)的性能,實(shí)用性高。基于Android的開發(fā)平臺(tái),能夠短時(shí)間內(nèi)升級(jí)新功能,并且該系統(tǒng)界面簡(jiǎn)潔,功能清晰,易于操作,為用戶提供一種便捷實(shí)用的監(jiān)控方式。2 Web服務(wù)器端架構(gòu)設(shè)計(jì)

2.1 數(shù)據(jù)訪問與服務(wù)設(shè)計(jì)

2.2 定位錄音與軌跡回放設(shè)計(jì)
3 防走失系統(tǒng)的實(shí)現(xiàn)
3.1 Android客戶端的實(shí)現(xiàn)
3.2 Web服務(wù)端的實(shí)現(xiàn)

4 結(jié)束語