![【旅游講解Android-APP的實(shí)現(xiàn)(論文)11000字】_第1頁(yè)](http://file4.renrendoc.com/view12/M0A/10/33/wKhkGWcZAeiAJINSAAJe528EZeU573.jpg)
![【旅游講解Android-APP的實(shí)現(xiàn)(論文)11000字】_第2頁(yè)](http://file4.renrendoc.com/view12/M0A/10/33/wKhkGWcZAeiAJINSAAJe528EZeU5732.jpg)
![【旅游講解Android-APP的實(shí)現(xiàn)(論文)11000字】_第3頁(yè)](http://file4.renrendoc.com/view12/M0A/10/33/wKhkGWcZAeiAJINSAAJe528EZeU5733.jpg)
![【旅游講解Android-APP的實(shí)現(xiàn)(論文)11000字】_第4頁(yè)](http://file4.renrendoc.com/view12/M0A/10/33/wKhkGWcZAeiAJINSAAJe528EZeU5734.jpg)
![【旅游講解Android-APP的實(shí)現(xiàn)(論文)11000字】_第5頁(yè)](http://file4.renrendoc.com/view12/M0A/10/33/wKhkGWcZAeiAJINSAAJe528EZeU5735.jpg)
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
-PAGEIV-旅游講解Android-APP的實(shí)現(xiàn)摘要近年來(lái),隨著移動(dòng)通信的發(fā)展和互聯(lián)網(wǎng)對(duì)移動(dòng)終端的普及,各種手機(jī)軟件產(chǎn)業(yè)層出不窮。因?yàn)楹芏嘤脩?hù)對(duì)景區(qū)不熟悉,造成不必要的人力、物力、財(cái)力浪費(fèi)。游戲的過(guò)程具有很大的不確定性和不可預(yù)測(cè)性。實(shí)時(shí)、現(xiàn)場(chǎng)、隨時(shí)隨地獲取信息是提高游戲體驗(yàn)質(zhì)量的重要途徑。本課題討論的大連風(fēng)景名勝區(qū)旅游解說(shuō)助手正是基于這樣的背景,其目的是讓用戶(hù)更全面、更方便地了解大連風(fēng)景名勝區(qū)的實(shí)時(shí)信息,得到該風(fēng)景名勝區(qū)旅游線(xiàn)路和重要瀏覽點(diǎn)的詳細(xì)解說(shuō),以及周邊其他相關(guān)景點(diǎn)的介紹,為游客提供更好的旅游體驗(yàn)。旅游講解助手應(yīng)用程序是基于AndroidStudio的移動(dòng)應(yīng)用軟件。在主要實(shí)現(xiàn)過(guò)程中,利用百度API提供的web服務(wù)獲取地圖信息。在Baidu-API請(qǐng)求中引入城市名稱(chēng)、目的地等數(shù)據(jù)參數(shù),查詢(xún)旅游目的地和景點(diǎn)信息。通過(guò)SAXParser對(duì)XML數(shù)據(jù)文件進(jìn)行解析,分析結(jié)果顯示在UI界面上。關(guān)鍵詞:Android;地圖;旅游目錄4404摘要 I42571緒論 1238671.1課題背景 1315681.2旅游系統(tǒng)的發(fā)展 1149311.3研究?jī)?nèi)容 26922系統(tǒng)關(guān)鍵技術(shù)簡(jiǎn)介 3260542.1Android系統(tǒng)簡(jiǎn)介 3252452.1.1Android特征 3107252.1.2Android系統(tǒng)架構(gòu) 4191562.1.3Android應(yīng)用組件 5130952.2MVP模式與MVC模式 6190673系統(tǒng)需求分析 7160063.1總體需求分析 7295723.2功能性需求分析 791203.2.1旅游講解助手APP端功能需求分析 7242483.2.2旅游講解助手PC端的功能需求分析 8248573.3系統(tǒng)環(huán)境需求 9156584系統(tǒng)概要設(shè)計(jì) 10176154.1系統(tǒng)結(jié)構(gòu)設(shè)計(jì) 10189504.2前端功能模塊的設(shè)計(jì) 11222354.3后端功能模塊的設(shè)計(jì) 11184634.4數(shù)據(jù)庫(kù)設(shè)計(jì) 1195925系統(tǒng)詳情設(shè)計(jì)與實(shí)現(xiàn) 13206525.1登錄與注冊(cè)界面設(shè)計(jì) 13167105.1.1用戶(hù)模塊 1394795.1.2管理員模塊 21298295.2景點(diǎn)信息模塊設(shè)計(jì) 228915.3附近景點(diǎn)與附近美食模塊設(shè)計(jì) 29218145.4用戶(hù)模塊設(shè)計(jì) 34162225.5景點(diǎn)添加模塊設(shè)計(jì) 354427結(jié)論 387940參考文獻(xiàn) 39PAGE2–PAGE15–1緒論隨著移動(dòng)互聯(lián)網(wǎng)技術(shù)的快速發(fā)展和移動(dòng)終端設(shè)備的普及,智能旅游迅速成為旅游業(yè)發(fā)展的重要途徑。旅游業(yè)與信息產(chǎn)業(yè)逐步融合。全球信息浪潮推動(dòng)了旅游業(yè)的信息化進(jìn)程,全社會(huì)的信息化水平逐步提高,這也促進(jìn)了旅游者信息手段的應(yīng)用能力,使智能化革命有了廣泛的用戶(hù)基礎(chǔ)。1.1課題背景旅游是人類(lèi)社會(huì)發(fā)展到一定階段后的一種社會(huì)活動(dòng)。人們?cè)跐M(mǎn)足休息、娛樂(lè)、文化等活動(dòng)的需要后,離開(kāi)定居地前往目的地,在那里停留一段時(shí)間。旅游業(yè)是在旅游活動(dòng)的基礎(chǔ)上發(fā)展起來(lái)的,以旅游者為服務(wù)對(duì)象和旅游者需求為中心的綜合性產(chǎn)業(yè),是資源密集型的新興產(chǎn)業(yè),綜合服務(wù)和發(fā)展支持。旅游業(yè)主要包括旅行社業(yè)、旅游運(yùn)輸業(yè)、住宿餐飲業(yè)、風(fēng)景名勝區(qū)業(yè)、購(gòu)物業(yè)、娛樂(lè)業(yè)等重點(diǎn)產(chǎn)業(yè),形成相對(duì)完整的產(chǎn)業(yè)鏈,為游客提供完善的服務(wù)。但現(xiàn)階段我國(guó)旅游業(yè)還存在著信息化水平低、旅游產(chǎn)品開(kāi)發(fā)水平低等問(wèn)題。例如,大多數(shù)導(dǎo)游系統(tǒng)仍然停留在依靠旗幟和揚(yáng)聲器的人工階段,絕大多數(shù)電子旅游系統(tǒng)集成度較低,只能提供音頻等應(yīng)用,但對(duì)于更豐富的服務(wù),如圖片、電子地圖等地理信息,位置和其他服務(wù)不可用。另一方面,隨著以谷歌Android系統(tǒng)和蘋(píng)果IOS系統(tǒng)為代表的移動(dòng)智能操作系統(tǒng)的應(yīng)用和發(fā)展日益增多,智能終端廣泛應(yīng)用于移動(dòng)終端、媒體播放器等領(lǐng)域。因此,在全球數(shù)字信息網(wǎng)絡(luò)快速發(fā)展的背景下,通過(guò)地理定位與地圖信息技術(shù)的結(jié)合,幫助游客更快地獲取旅游景點(diǎn)的相關(guān)信息,基于移動(dòng)設(shè)備的旅游相關(guān)應(yīng)用已經(jīng)成為實(shí)現(xiàn)智能旅游的重要載體因此,本文研究基于Android的旅游講解助手APP軟件的設(shè)計(jì)與實(shí)現(xiàn)具有重要的現(xiàn)實(shí)意義。1.2旅游系統(tǒng)的發(fā)展旅游信息化在發(fā)達(dá)國(guó)家經(jīng)歷了幾十年的發(fā)展,涉及旅游目的地信息、旅游政府監(jiān)管信息、旅游企業(yè)服務(wù)信息、旅游者個(gè)人信息和旅游產(chǎn)品信息五大類(lèi)。隨著理論和技術(shù)的不斷進(jìn)步,信息技術(shù)的應(yīng)用也發(fā)生了幾大變化。首先,上世紀(jì)50年代末,美國(guó)航空公司和IBM聯(lián)合開(kāi)發(fā)了世界上第一個(gè)計(jì)算機(jī)定位系統(tǒng)——SABRE,這是旅游信息化萌芽的標(biāo)志;第二,上世紀(jì)70年代末,美國(guó)出臺(tái)了《空中交通管制取消法》,增加了游客購(gòu)票的選擇,并將電腦訂票系統(tǒng)推廣到旅行社;第三,20世紀(jì)末,美國(guó)開(kāi)始出現(xiàn)一種新的“電子機(jī)票”模式。隨著信息技術(shù)的飛速發(fā)展,旅游系統(tǒng)也在飛速發(fā)展。谷歌2005年推出的谷歌地圖就是一個(gè)典型的例子。中國(guó)旅游業(yè)的信息化始于上世紀(jì)80年代初。起步較晚,基礎(chǔ)薄弱??傮w水平較低。進(jìn)入21世紀(jì)后,我國(guó)旅游信息化開(kāi)始高速發(fā)展,包括旅行社、旅游飯店、景區(qū)等的信息化建設(shè)。各大旅游信息網(wǎng)站紛紛涌現(xiàn)。不僅網(wǎng)易、騰訊、新浪、搜狐等門(mén)戶(hù)網(wǎng)站都有旅游板塊,還有攜程、去哪兒網(wǎng)等眾多旅游電子商務(wù)網(wǎng)站。旅游系統(tǒng)最初是在PC機(jī)上實(shí)現(xiàn)的,但用戶(hù)在旅游過(guò)程中需要隨時(shí)了解最新信息、發(fā)布最新信息和使用定位功能。鑒于移動(dòng)平臺(tái)的普及,利用移動(dòng)終端上的旅游系統(tǒng)資源更適合發(fā)展。1.3研究?jī)?nèi)容在分析旅游景點(diǎn)需求的同時(shí),合理美觀的界面設(shè)計(jì),使用戶(hù)體驗(yàn)效果良好。這個(gè)應(yīng)用一般是旅游團(tuán)用戶(hù)使用的,用戶(hù)可以提前查看相應(yīng)旅游景點(diǎn)的介紹和游玩路線(xiàn)。用戶(hù)在游覽景區(qū)時(shí),該應(yīng)用可以實(shí)時(shí)向游客介紹景區(qū)的特色,以語(yǔ)音廣播的形式播放,并推薦景區(qū)附近的其他景區(qū)和美食推薦。在本應(yīng)用程序的設(shè)計(jì)中,采用MVP架構(gòu)模式完成了整個(gè)代碼的架構(gòu),完成了接口和數(shù)據(jù)存儲(chǔ)的高效結(jié)合,使代碼得到優(yōu)化,應(yīng)用程序使用順暢,沒(méi)有卡死等內(nèi)存泄漏現(xiàn)象。主要功能及指標(biāo)要求如下:(1)賬號(hào)的注冊(cè)和登錄(2)旅游景點(diǎn)的瀏覽和簡(jiǎn)介(3)在游覽景點(diǎn)時(shí)的語(yǔ)音播放景點(diǎn)介紹相關(guān)內(nèi)容(4)在景點(diǎn)游覽過(guò)程中可以推薦附近美食和景點(diǎn)(5)App界面要設(shè)計(jì)合理美觀,用戶(hù)體驗(yàn)效果好
2系統(tǒng)關(guān)鍵技術(shù)簡(jiǎn)介2.1Android系統(tǒng)簡(jiǎn)介Android是谷歌(Google)公司發(fā)布的基于Linux的開(kāi)源手機(jī)平臺(tái),該平臺(tái)由操作系統(tǒng)、中間件和應(yīng)用軟件組成,是第一個(gè)可以完全定制、免費(fèi)、開(kāi)放的手機(jī)平臺(tái)。Android是一個(gè)完全免費(fèi)的手機(jī)平臺(tái),使用Android并不需要授權(quán)費(fèi),而且因?yàn)锳ndroid平臺(tái)有豐富的應(yīng)用程序,也大幅度降低了應(yīng)用程序的開(kāi)發(fā)費(fèi)用,可以節(jié)約15%~20%的手機(jī)制造成本。2.1.1Android特征Android底層使用開(kāi)源的Linux操作系統(tǒng),同時(shí)開(kāi)放了應(yīng)用程序開(kāi)發(fā)工具,使所有程序開(kāi)發(fā)人員都在統(tǒng)一、開(kāi)放的開(kāi)發(fā)平臺(tái)上進(jìn)行開(kāi)發(fā),保證了Android應(yīng)用程序的可移植性。Android系統(tǒng)提供了訪(fǎng)問(wèn)硬件API庫(kù)函數(shù),用來(lái)簡(jiǎn)化像攝像頭、GPS等硬件的訪(fǎng)問(wèn)過(guò)程。在內(nèi)存和進(jìn)程管理方面,Android具有自己的運(yùn)行時(shí)和虛擬機(jī)。與Java和.NET運(yùn)行時(shí)不同,Android運(yùn)行時(shí)還可以管理進(jìn)程的生命周期。Android為了保證高優(yōu)先級(jí)進(jìn)程運(yùn)行和正在與用戶(hù)交互進(jìn)程的響應(yīng)速度,允許停止或終止正在運(yùn)行的低優(yōu)先級(jí)進(jìn)程,已釋放被占用的系統(tǒng)資源。Android進(jìn)程的優(yōu)先級(jí)并不是固定的,而是根據(jù)進(jìn)程是否在前臺(tái)或是否與用戶(hù)交互而不斷變化的。在界面設(shè)計(jì)上,Android提供了豐富的界面控件供使用者調(diào)用,從而加快了用戶(hù)界面的開(kāi)發(fā)速度,也保證了Android平臺(tái)上的程序界面的一致性。Android將界面設(shè)計(jì)與程序邏輯分離,使用XML文件對(duì)界面布局進(jìn)行描述,有利于界面的修改和維護(hù)。Android提供輕量級(jí)的進(jìn)程間通信機(jī)制Intent,使跨進(jìn)程組件通信和發(fā)送系統(tǒng)級(jí)廣播成為可能。通過(guò)設(shè)置組件的Intent過(guò)濾器,組件通過(guò)匹配和篩選機(jī)制,可以準(zhǔn)確地獲取到可以處理的Intent。Android提供了Service作為無(wú)用戶(hù)界面、長(zhǎng)時(shí)間后臺(tái)運(yùn)行的組件。Android是多任務(wù)系統(tǒng),但受到屏幕尺寸的限制,同一時(shí)刻只允許一個(gè)應(yīng)用程序在前臺(tái)運(yùn)行。Service無(wú)須用戶(hù)干預(yù),可以長(zhǎng)時(shí)間、穩(wěn)定地運(yùn)行,可為應(yīng)用程序提供特定的后臺(tái)功能,還可以實(shí)現(xiàn)事件處理或數(shù)據(jù)更新等功能。Android支持高效、快速的數(shù)據(jù)儲(chǔ)存方式,應(yīng)用程序可以使用適合的方法保存和訪(fǎng)問(wèn)數(shù)據(jù)進(jìn)程。同時(shí),為了便于跨進(jìn)程共享數(shù)據(jù),Android提供了通用的共享數(shù)據(jù)接口ContentProvider,可以無(wú)須了解數(shù)據(jù)源、路徑的情況下,對(duì)共享數(shù)據(jù)進(jìn)行查詢(xún)、添加、刪除和更新等操作。2.1.2Android系統(tǒng)架構(gòu)Android系統(tǒng)架構(gòu)采用了分層的架構(gòu)。Android系統(tǒng)分為四層,從高層到低層分別是應(yīng)用程序?qū)?、?yīng)用程序框架層、系統(tǒng)運(yùn)行層和Linux內(nèi)核層。圖2.1Android系統(tǒng)架構(gòu)(1)應(yīng)用程序?qū)覣ndroid應(yīng)用程序?qū)影嗽S多應(yīng)用程序。例如,短信、聯(lián)系人、電話(huà)、電子郵件、瀏覽器等。同時(shí),開(kāi)發(fā)人員也可以利用Java語(yǔ)言設(shè)計(jì)和編寫(xiě)屬于自己的應(yīng)用程序。相比其他手機(jī)操作系統(tǒng),顯得更加靈活和個(gè)性化。(2)應(yīng)用程序框架層應(yīng)用程序框架層是Android開(kāi)發(fā)的基礎(chǔ),為應(yīng)用程序?qū)犹峁┝烁鞣N所能用到的API,很多核心程序也是通過(guò)這些API來(lái)實(shí)現(xiàn)的。由于其內(nèi)部的組件重用機(jī)制,開(kāi)發(fā)人員可以直接使用其提供的的組件來(lái)快速地進(jìn)行應(yīng)用程序的開(kāi)發(fā),也可以通過(guò)繼承來(lái)實(shí)現(xiàn)個(gè)性化的拓展。(3)系統(tǒng)運(yùn)行庫(kù)層系統(tǒng)運(yùn)行庫(kù)層包括系統(tǒng)庫(kù)和AndroidRuntime。系統(tǒng)庫(kù)是應(yīng)用程序框架的支撐,是連接應(yīng)用程序框架層與Linux內(nèi)核層的重要紐帶。程序在AndroidRuntime中執(zhí)行,其運(yùn)行時(shí)分為核心庫(kù)和Dalvik虛擬機(jī)兩部分。(4)Linux內(nèi)核層Android操作系統(tǒng)是基于Linux內(nèi)核,其核心系統(tǒng)服如安全性、內(nèi)存管理、進(jìn)程管理、網(wǎng)路協(xié)議以及驅(qū)動(dòng)模型都依賴(lài)于Linux內(nèi)核。LinuxKernel也作為硬件和軟件之間的抽象層,它隱藏了具體硬件細(xì)節(jié)并為上層提供統(tǒng)一的服務(wù)。2.1.3Android應(yīng)用組件Android開(kāi)發(fā)四大組件分別是:活動(dòng)(Activity),用于表現(xiàn)功能;服務(wù)(Service),用于后臺(tái)運(yùn)行服務(wù),不提供界面呈現(xiàn);廣播接收器(BroadcastReceiver),用于接收廣播;內(nèi)容提供商(ContentProvider),支持在多個(gè)應(yīng)用中存儲(chǔ)和讀取數(shù)據(jù),相當(dāng)于數(shù)據(jù)庫(kù)。(1)Activity一個(gè)Activity通常展現(xiàn)為一個(gè)可視化的用戶(hù)界面,它是Android程序與用戶(hù)交互的窗口,也是Android組件中最基本也是最復(fù)雜的一個(gè)組件。從視覺(jué)效果來(lái)看,一個(gè)Activity占據(jù)當(dāng)前的窗口,響應(yīng)所有窗口時(shí)間,其具備控件,菜單等界面元素。從內(nèi)部邏輯來(lái)看,Activity需要為了保持各個(gè)界面狀態(tài),做很多持久化的事情,還需要妥善管理生命周期和一些轉(zhuǎn)跳邏輯。對(duì)于開(kāi)發(fā)者而言,需要派生一個(gè)Activity的子類(lèi),進(jìn)而進(jìn)行編碼實(shí)現(xiàn)各種功能方法。一般一個(gè)Android應(yīng)用是由多個(gè)Activity組成的,Activity之間通過(guò)Intent進(jìn)行通信。在Intent的描述結(jié)構(gòu)中,有兩個(gè)最重要的部分:動(dòng)作和動(dòng)作對(duì)應(yīng)的數(shù)據(jù)。Android應(yīng)用中每一個(gè)Activity都必須要在AndroidManifest.xml配置文件中聲明,否則系統(tǒng)將不識(shí)別也不執(zhí)行該Activity。(2)Service一個(gè)Service是一段長(zhǎng)生命周期且沒(méi)有用戶(hù)界面的程序,只能后臺(tái)運(yùn)行,并且可以和其他組件進(jìn)行交互,它可以用來(lái)開(kāi)發(fā)如監(jiān)控類(lèi)程序。同Activity一樣,Service也必須要在AndroidManifest.xml配置文件中注冊(cè)。(3)BroadcastReceiver廣播是一種被廣泛運(yùn)用在應(yīng)用程序之間傳輸信息的機(jī)制,而B(niǎo)roadcastReceiver是對(duì)發(fā)送出來(lái)的廣播進(jìn)行過(guò)濾接收并響應(yīng)的一類(lèi)組件。廣播接收器沒(méi)有用戶(hù)界面,但它們可以啟動(dòng)一個(gè)activity或service來(lái)響應(yīng)它們收到的信息,或者用NotificationManager來(lái)通知用戶(hù)。通知可以用多種方式來(lái)吸引用戶(hù)的注意力——閃動(dòng)背燈、震動(dòng)、播放聲音等。一般來(lái)說(shuō)是在狀態(tài)欄放一個(gè)持久的圖標(biāo),用戶(hù)可以打開(kāi)它并獲取消息。BroadcastReceiver既可以在AndroidManifest.xml中注冊(cè),也可以在運(yùn)行時(shí)的代碼中使用registerReceiver()進(jìn)行注冊(cè)。(4)ContentProvider內(nèi)容提供者,作為應(yīng)用程序之間唯一的共享數(shù)據(jù)途徑,ContentProvider主要的功能就是存儲(chǔ)并檢索數(shù)據(jù)以及向其他應(yīng)用程序提供訪(fǎng)問(wèn)數(shù)據(jù)的接口。在Android中,對(duì)數(shù)據(jù)的保護(hù)是很?chē)?yán)密的,除了放在SD卡中的數(shù)據(jù),一個(gè)應(yīng)用所持有的數(shù)據(jù)庫(kù)、文件等內(nèi)容,都不允許其他應(yīng)用直接訪(fǎng)問(wèn)。但是可以通過(guò)ContentResolver類(lèi)從該內(nèi)容提供者中獲取或存入數(shù)據(jù)。ContentProvider使用URI來(lái)唯一標(biāo)識(shí)其數(shù)據(jù)集,這里的URI以content://作為前綴,表示該數(shù)據(jù)由ContentProvider來(lái)管理。ContentProvider使用時(shí)也必須要在AndroidManifest.xml配置文件中注冊(cè)。2.2MVP模式與MVC模式MVP(Model-View-Presenter)模式,它是由MVC(Model-View-Controller)模式演變而來(lái)的。它們的基本思想有想通的地方:Model負(fù)責(zé)提供數(shù)據(jù),View負(fù)責(zé)顯示,Controller/Presenter的內(nèi)部。而在MVC中,View可以直接從Model中讀取數(shù)據(jù)。圖2.2MVP與MVC對(duì)比圖(1)MVP架構(gòu)模式在Android開(kāi)發(fā)中采用MVP架構(gòu),分別為模型層(Model)、視圖層(View)和邏輯層(Presenter)。模型層用于提供數(shù)據(jù)源,負(fù)責(zé)對(duì)數(shù)據(jù)的存取操作,例如數(shù)據(jù)庫(kù)的讀寫(xiě)、網(wǎng)絡(luò)數(shù)據(jù)的請(qǐng)求等;視圖層負(fù)責(zé)UI處理,具體是一個(gè)View接口,由Activity或Fragment實(shí)現(xiàn);邏輯層,用于實(shí)現(xiàn)業(yè)務(wù)邏輯,既可以調(diào)用UI邏輯,也可以處理網(wǎng)絡(luò)請(qǐng)求邏輯,該層為純Java類(lèi),不涉及任何AndroidAPI。(2)MVC架構(gòu)模式MVC模式的三層架構(gòu),即視圖層(View)、控制層(Controller)、模型層(Model)。視圖層運(yùn)行在瀏覽器上面用于展示W(wǎng)eb應(yīng)用程序的頁(yè)面;控制層運(yùn)行在服務(wù)器端,主要控制頁(yè)面的切換和相關(guān)業(yè)務(wù)邏輯的調(diào)用;模型層主要封裝了Web應(yīng)用程序的業(yè)務(wù)邏輯,以及對(duì)數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)。Controller負(fù)責(zé)處理流入的請(qǐng)求,其通過(guò)View來(lái)接受用戶(hù)的輸入,之后利用Model來(lái)處理用戶(hù)的數(shù)據(jù),最后把結(jié)果返回給View。3系統(tǒng)需求分析需求分析是軟件開(kāi)發(fā)的基礎(chǔ)和前提,也是軟件開(kāi)發(fā)的關(guān)鍵因素之一。這個(gè)階段是分析什么需要“實(shí)施”,而不是如何“實(shí)施”。需求分析的目的是開(kāi)發(fā)人員對(duì)開(kāi)發(fā)系統(tǒng)的“需求”或“需求”進(jìn)行分析和梳理,確定系統(tǒng)需要實(shí)現(xiàn)哪些功能和任務(wù)。3.1總體需求分析要開(kāi)發(fā)一個(gè)旅游講解助手APP,首先需要做到旅游景點(diǎn)范圍的明確,利于游客瀏覽熱門(mén)景點(diǎn)的需求,確定大連市相應(yīng)景點(diǎn)的添加;游客可以通過(guò)此APP了解大連市的熱門(mén)景點(diǎn),可通過(guò)語(yǔ)音播報(bào)來(lái)熟知某個(gè)景點(diǎn);注冊(cè)的用戶(hù)需要填入準(zhǔn)確的信息,注冊(cè)之后才能登錄到APP,才能查看景點(diǎn)的具體信息,也可以查看所在定位下的附近景點(diǎn)和附近美食;用戶(hù)可以自主管理個(gè)人信息以及密碼的修改。管理員注冊(cè)和登錄之后可以添加景點(diǎn)的具體信息。該軟件通過(guò)Android移動(dòng)終端和PC終端實(shí)現(xiàn)。移動(dòng)終端主要供用戶(hù)查看大連市相關(guān)景點(diǎn),包括景點(diǎn)的具體信息以及到達(dá)景點(diǎn)后附近的景點(diǎn)和食物;有用戶(hù)登錄注冊(cè)、修改昵稱(chēng)、修改密碼、退出賬號(hào)登錄等功能。PC端是管理員添加大連風(fēng)景名勝區(qū)的具體信息;它還包括管理員登錄和注冊(cè)。3.2功能性需求分析3.2.1旅游講解助手APP端功能需求分析旅游講解助手APP端是面向游客用戶(hù)的,其目的是讓游客通過(guò)此APP來(lái)了解到大連市景點(diǎn)的具體信息,為旅游出行做好攻略等準(zhǔn)備。旅游講解助手APP端的功能需求的具體內(nèi)容如下:用戶(hù)登錄:用戶(hù)通過(guò)昵稱(chēng)(賬號(hào))和密碼的驗(yàn)證后可進(jìn)入APP。用戶(hù)注冊(cè):用戶(hù)若未注冊(cè),則通過(guò)昵稱(chēng)(賬號(hào))、郵箱、密碼進(jìn)行賬號(hào)的注冊(cè)。景點(diǎn)列表瀏覽:可瀏覽大連市熱門(mén)景點(diǎn)。景點(diǎn)詳情信息:可知道大連市某個(gè)景點(diǎn)的具體信息、簡(jiǎn)介等。景點(diǎn)導(dǎo)航:根據(jù)景點(diǎn)的坐標(biāo)通過(guò)百度API的請(qǐng)求中傳入城市名稱(chēng)、目的地等數(shù)據(jù)參數(shù)來(lái)查詢(xún)旅游地、景點(diǎn)等信息,進(jìn)行距離查詢(xún)或?qū)Ш降竭_(dá)。景點(diǎn)信息語(yǔ)音播報(bào):景點(diǎn)的相關(guān)信息可通過(guò)語(yǔ)音播報(bào)的形式表現(xiàn)。附近景點(diǎn):在游玩過(guò)程中可知道身處景點(diǎn)的附近景點(diǎn)。附近美食:在游玩過(guò)程中可知道身處景點(diǎn)的附近美食。用戶(hù)上傳頭像:用戶(hù)在登陸后可以上傳自己的頭像。用戶(hù)修改昵稱(chēng):用戶(hù)在登陸后可以修改用戶(hù)昵稱(chēng)。用戶(hù)修改密碼:用戶(hù)在登陸后可以修改用戶(hù)昵稱(chēng)。用戶(hù)退出登錄賬號(hào):用戶(hù)在退出登錄賬號(hào)后會(huì)自動(dòng)退出APP。旅游講解助手APP端的功能需求用例圖如下圖所示:圖3.1APP端的功能需求用例圖3.2.2旅游講解助手PC端的功能需求分析旅游講解助手PC端是管理員進(jìn)行添加景點(diǎn)等功能,其目的是通過(guò)管理員來(lái)添加大連市熱門(mén)的景點(diǎn)及其相關(guān)信息。旅游講解助手PC端的功能需求的具體內(nèi)容如下:管理員登錄:管理員通過(guò)郵箱、密碼驗(yàn)證后進(jìn)入景點(diǎn)添加界面。管理員注冊(cè):通過(guò)賬號(hào)、郵箱、密碼等完成管路員賬號(hào)的注冊(cè)。景點(diǎn)添加:添加景點(diǎn)的名稱(chēng)、坐標(biāo)、詳情介紹、景點(diǎn)圖片。3.3系統(tǒng)環(huán)境需求(1)開(kāi)發(fā)環(huán)境:硬件環(huán)境:臺(tái)式計(jì)算機(jī);Windows10。軟件環(huán)境:IntelliJIDEA2021.1x64;AndroidStudio;JDK;MySQL。(2)運(yùn)行環(huán)境:硬件環(huán)境:Android手機(jī);臺(tái)式計(jì)算機(jī);Windows10。軟件環(huán)境:Android操作系統(tǒng);GoogleChrome瀏覽器。
4系統(tǒng)概要設(shè)計(jì)系統(tǒng)概要設(shè)計(jì)是開(kāi)發(fā)者基于用戶(hù)交互過(guò)程和用戶(hù)需求形成交互框架和可視框架的過(guò)程,其結(jié)果通常是交互控制配置、以反映接口元件分組和接口整體板式的頁(yè)幀圖的形式呈現(xiàn)。
概要設(shè)計(jì)的主要任務(wù)是將需求分析得到的系統(tǒng)擴(kuò)展用例圖轉(zhuǎn)換成軟件結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu)。4.1系統(tǒng)結(jié)構(gòu)設(shè)計(jì)旅游講解助手APP軟件是以AndroidStudio為開(kāi)發(fā)平臺(tái)實(shí)現(xiàn)的移動(dòng)應(yīng)用軟件,實(shí)現(xiàn)過(guò)程中利用百度API提供的WebService獲取地圖信息,通過(guò)百度API的請(qǐng)求中傳入城市名稱(chēng)、目的地等數(shù)據(jù)參數(shù)來(lái)查詢(xún)旅游地、景點(diǎn)等信息,利用SAXParser對(duì)獲取到的XML數(shù)據(jù)文件進(jìn)行解析,并將解析結(jié)果在UI界面中展示。圖4.1系統(tǒng)功能結(jié)構(gòu)設(shè)計(jì)圖4.2前端功能模塊的設(shè)計(jì)前端功能模塊的設(shè)計(jì)分為Android用戶(hù)端和PC端。Android用戶(hù)終端大致分為用戶(hù)賬號(hào)注冊(cè)和注冊(cè)模塊、景點(diǎn)查詢(xún)模塊、景點(diǎn)相關(guān)信息模塊、景點(diǎn)介紹語(yǔ)音廣播模塊、景點(diǎn)導(dǎo)航模塊。通過(guò)與服務(wù)器的數(shù)據(jù)交互來(lái)實(shí)現(xiàn)該APP的使用。用戶(hù)登錄APP后,可以查詢(xún)大連市的觀光景點(diǎn)介紹和觀光路線(xiàn)等觀光景點(diǎn)信息。用戶(hù)在游覽某個(gè)景點(diǎn)時(shí)使用這個(gè)應(yīng)用程序,為游客實(shí)時(shí)介紹景點(diǎn)的特色,并通過(guò)聲音廣播進(jìn)行播放??梢钥吹接^光景點(diǎn)附近其他的觀光景點(diǎn)和美食介紹等目的。界面設(shè)計(jì)既合理又美麗又方便。PC端的實(shí)現(xiàn)主要是在于開(kāi)發(fā)一個(gè)Web工程,配置數(shù)據(jù)庫(kù)服務(wù)器和Web服務(wù)器,并在web工程中納入兩個(gè)服務(wù)器的驅(qū)動(dòng),以此通過(guò)Web工程實(shí)現(xiàn)用戶(hù)端HTTP請(qǐng)求的響應(yīng),并將最終結(jié)構(gòu)反饋給用戶(hù)端。4.3后端功能模塊的設(shè)計(jì)后端的服務(wù)器端主要實(shí)現(xiàn)PC端、數(shù)據(jù)庫(kù)和Android手持端的連接。第一是關(guān)于數(shù)據(jù)的存儲(chǔ)功能,這里主要體現(xiàn)在管理員賬號(hào)注冊(cè)、登錄的信息儲(chǔ)存,用戶(hù)賬號(hào)注冊(cè)、登錄的信息存儲(chǔ),景點(diǎn)相關(guān)信息的存儲(chǔ)。第二個(gè)功能是和手機(jī)端實(shí)現(xiàn)數(shù)據(jù)交互。在數(shù)據(jù)交互的過(guò)程中,用戶(hù)可以實(shí)現(xiàn)從服務(wù)器查詢(xún)景點(diǎn)位置信息、景點(diǎn)信息語(yǔ)音播報(bào)等功能。操作端對(duì)數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)和數(shù)據(jù)存儲(chǔ)。4.4數(shù)據(jù)庫(kù)設(shè)計(jì)本系統(tǒng)的數(shù)據(jù)庫(kù)使用的是MySQL,通過(guò)JDBC驅(qū)動(dòng)連接數(shù)據(jù)庫(kù)。實(shí)際上,本系統(tǒng)的數(shù)據(jù)庫(kù)十分簡(jiǎn)單,只有三個(gè)數(shù)據(jù)表,三者之間并沒(méi)有直接的關(guān)系,所以在這里就省略了數(shù)據(jù)庫(kù)的E-R圖。下面是三個(gè)數(shù)據(jù)表的結(jié)構(gòu)設(shè)計(jì):管理員數(shù)據(jù)表該表是用來(lái)記錄管理員的姓名、密碼以及郵箱。表4.1管理員數(shù)據(jù)表字段名字段類(lèi)型 寬度 索引標(biāo)題idINT10主索引管理員編號(hào)user_nameVARCHAR30管理員姓名passwordVARCHAR255管理員密碼emailVARCHAR255管理員郵箱用戶(hù)數(shù)據(jù)表該表是用來(lái)記錄用戶(hù)的昵稱(chēng)、密碼、郵箱以及頭像。表4.2用戶(hù)數(shù)據(jù)表字段名字段類(lèi)型 寬度 索引標(biāo)題idINT10主索引用戶(hù)編號(hào)user_nameVARCHAR30用戶(hù)昵稱(chēng)passwordVARCHAR255用戶(hù)密碼emailVARCHAR255用戶(hù)郵箱avatarVARCHAR255用戶(hù)上傳頭像景點(diǎn)信息數(shù)據(jù)表該表是用來(lái)記錄景點(diǎn)的名稱(chēng)、詳情、經(jīng)度、緯度以及景點(diǎn)圖片。表4.3景點(diǎn)信息數(shù)據(jù)表字段名字段類(lèi)型 寬度 索引標(biāo)題idINT11主索引景點(diǎn)編號(hào)nameVARCHAR20景點(diǎn)名稱(chēng)infoVARCHAR500景點(diǎn)詳情longitudeVARCHAR20景點(diǎn)經(jīng)度latitudeVARCHAR20景點(diǎn)緯度imageVARCHAR500景點(diǎn)圖片
5系統(tǒng)詳情設(shè)計(jì)與實(shí)現(xiàn)在本文上一章中概要地介紹了系統(tǒng)的結(jié)構(gòu)設(shè)計(jì)和數(shù)據(jù)設(shè)計(jì),本章則介紹旅游講解助手APP的詳情設(shè)計(jì)和實(shí)現(xiàn)情況。系統(tǒng)詳情階段將為每個(gè)模塊完成的功能進(jìn)行具體的描述,把功能描述變?yōu)榫_的過(guò)程描述。因?yàn)锳ndroid系統(tǒng)的開(kāi)發(fā)特點(diǎn),本章將首先進(jìn)行系統(tǒng)界面的介紹,即界面層的設(shè)計(jì),進(jìn)而介紹控制層和數(shù)據(jù)訪(fǎng)問(wèn)層的設(shè)計(jì)。5.1登錄與注冊(cè)界面設(shè)計(jì)登錄與注冊(cè)界面主要分為兩個(gè)模塊,分別是用戶(hù)模塊和管理員模塊。5.1.1用戶(hù)模塊用戶(hù)模塊是Android手機(jī)端的功能模塊,其中包括了用戶(hù)的登錄界面和用戶(hù)的注冊(cè)界面。點(diǎn)擊此APP會(huì)直接顯示歡迎頁(yè)面,如圖5.1所示。圖5.1歡迎頁(yè)面歡迎頁(yè)面經(jīng)過(guò)延時(shí)效果直接跳轉(zhuǎn)到登錄頁(yè)面,如圖5.2所示。登錄頁(yè)面輸入郵箱和密碼,經(jīng)驗(yàn)證與數(shù)據(jù)庫(kù)內(nèi)儲(chǔ)存一致則進(jìn)入APP首頁(yè)。圖5.2登錄頁(yè)面如若用戶(hù)沒(méi)有注冊(cè),則新用戶(hù)可以點(diǎn)擊注冊(cè)按鈕跳轉(zhuǎn)到注冊(cè)頁(yè)面,如圖5.3所示。目前注冊(cè)界面需要填寫(xiě)用戶(hù)名、郵箱、密碼,如若未填寫(xiě)則會(huì)有相應(yīng)提示,郵箱通過(guò)正則表達(dá)式來(lái)驗(yàn)證郵箱格式,密碼也通過(guò)正則表達(dá)式來(lái)檢驗(yàn)強(qiáng)弱,注冊(cè)成功后會(huì)給予提示注冊(cè)成功跳轉(zhuǎn)回登錄頁(yè)面。圖5.3注冊(cè)頁(yè)面主要實(shí)現(xiàn)代碼:歡迎頁(yè)面
publicclassWellComeActivityextendsAppCompatActivity{
Handlerhandler=newHandler()
{
@Override
publicvoidhandleMessage(@NonNullMessagemsg){
super.handleMessage(msg);
if(SharePrenUtils.getInstance(WellComeActivity.this).isLogin())
{
startActivity(newIntent(WellComeActivity.this,MainActivity.class));
}
else
{
startActivity(newIntent(WellComeActivity.this,LoginActivity.class));
}
finish();
}
}
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_well_come);
//2秒之后跳轉(zhuǎn)的登錄頁(yè)面
handler.sendEmptyMessageDelayed(0,2000);
}
}登錄頁(yè)面publicclassLoginActivityextendsBaseActivity{
ActivityLoginBindingbinding;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
binding=ActivityLoginBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.login.setOnClickListener(view->{
login();
});
binding.regis.setOnClickListener(view->{
startActivity(newIntent(this,RegisActivity.class));
});
}
privatevoidlogin(){
Stringname=.getText().toString();
if(TextUtils.isEmpty(name))
{
Toast.makeText(this,"用戶(hù)名不能為空",Toast.LENGTH_SHORT).show();
return;
}
Stringpass=binding.pass.getText().toString();
if(TextUtils.isEmpty(pass))
{
Toast.makeText(this,"密碼不能為空",Toast.LENGTH_SHORT).show();
return;
}
Stringurl=Contstans.host+"/user/login";
RequestParamsparams=newRequestParams(url);
params.setAsJsonContent(true);
LoginBeanbean=newLoginBean();
bean.setUsername(name);
bean.setPassword(pass);
params.setBodyContent(newGson().toJson(bean));
showDialog();
x.http().post(params,newCallback.CommonCallback<LoginResultBean>(){
@Override
publicvoidonSuccess(LoginResultBeanresult){
//返回為0代表登錄成功
if(result!=null)
{
showtoast("登錄成功");
//保存用戶(hù)名
SharePrenUtils.getInstance(LoginActivity.this)
.putUserInfo(result);
startActivity(newIntent(LoginActivity.this,MainActivity.class));
finish();
}else{
showtoast("用戶(hù)名或者密碼錯(cuò)誤");}
}
@Override
publicvoidonFinished(){
hideDialog();}});}
}注冊(cè)頁(yè)面publicclassRegisActivityextendsBaseActivity{
ActivityRegisBindingbinding;
privateintGRADE_SCORE;
@Override
protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);
binding=ActivityRegisBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.pass.addTextChangedListener(newTextWatcher(){
@Override
publicvoidafterTextChanged(Editableeditable){
Stringtext=binding.pass.getText().toString();
if(TextUtils.isEmpty(text))
return;
//判斷密碼的強(qiáng)度
PasswordStrengthstr=PasswordStrength.calculateStrength(text);
binding.tvQiangdu.setText("密碼強(qiáng)度:"+str.getText(RegisActivity.this));
gressBar.getProgressDrawable().setColorFilter(str.getColor(),android.graphics.PorterDuff.Mode.SRC_IN);
if(str.getText(RegisActivity.this).equals("低")){
gressBar.setProgress(33);
}elseif(str.getText(RegisActivity.this).equals("中")){
gressBar.setProgress(66);
}elseif(str.getText(RegisActivity.this).equals("高")){
gressBar.setProgress(100);
}else{
gressBar.setProgress(0);}
}});binding.regis.setOnClickListener(view->{
regis();
});}/**注冊(cè)按鈕*/privatevoidregis(){
Stringname=.getText().toString();
if(TextUtils.isEmpty(name))
{Toast.makeText(this,"用戶(hù)名不能為空",Toast.LENGTH_SHORT).show();
return;}
Stringpass=binding.pass.getText().toString();
if(TextUtils.isEmpty(pass))
{Toast.makeText(this,"密碼不能為空",Toast.LENGTH_SHORT).show();
return;}
Stringyouxiang=binding.youxaing.getText().toString();
if(TextUtils.isEmpty(youxiang))
{Toast.makeText(this,"郵箱不能為空",Toast.LENGTH_SHORT).show();
return;}
if(!isEmail(youxiang))
{Toast.makeText(this,"不是有效郵箱",Toast.LENGTH_SHORT).show();
return;}Stringurl=Contstans.host+"/user/regist";
RequestParamsparams=newRequestParams(url);
params.addBodyParameter("username",name);
params.addBodyParameter("email",youxiang);
params.addBodyParameter("password",pass);
showDialog();
x.http().post(params,newCallback.CommonCallback<String>(){@Override
publicvoidonSuccess(Stringresult){
if(result.equals("1"))
{
//保存用戶(hù)名
SharedPreferencessharedPreferences=getSharedPreferences(Contstans.use_info,MODE_PRIVATE);
sharedPreferences.edit().putString("name",name).commit();
sharedPreferences.edit().putString("email",name).commit();
Toast.makeText(RegisActivity.this,"注冊(cè)成功",Toast.LENGTH_SHORT).show();
finish();}else{showtoast("注冊(cè)失敗");}
}@Override
publicvoidonFinished(){hideDialog();}
});}/**判斷密碼強(qiáng)度@returnZ=字母S=數(shù)字T=特殊字符*/
privateStringpasswordStrong(StringpasswordStr){
if(TextUtils.equals("",passwordStr)){
return"出現(xiàn)故障";}
StringregexZ="\\d*";
StringregexS="[a-zA-Z]+";
StringregexT="\\W+$";
StringregexZT="\\D*";
StringregexST="[\\d\\W]*";
StringregexZS="\\w*";
StringregexZST="[\\w\\W]*";
if(passwordStr.matches(regexZ)){
GRADE_SCORE=20;
return"弱";}
if(passwordStr.matches(regexS)){
GRADE_SCORE=20;
return"弱";}
if(passwordStr.matches(regexT)){
GRADE_SCORE=20;
return"弱";}
if(passwordStr.matches(regexZT)){
GRADE_SCORE=60;
return"中";}
if(passwordStr.matches(regexST)){
GRADE_SCORE=60;
return"中";}
if(passwordStr.matches(regexZS)){
GRADE_SCORE=60;
return"中";}
if(passwordStr.matches(regexZST)){
GRADE_SCORE=90;
return"強(qiáng)";}
returnpasswordStr;}
/**設(shè)置progressBar值*@paramscore*/
privatevoidsetProgressBarColour(intscore){intcolor=0;
if(score<30){
color=getResources().getColor(android.R.color.holo_red_light);
}elseif(score<70){
color=getResources().getColor(android.R.color.holo_orange_light);
}else{
color=getResources().getColor(android.R.color.holo_green_light);
}
ClipDrawabled=newClipDrawable(newColorDrawable(color),Gravity.
LEFT,ClipDrawable.HORIZONTAL);
gressBar.setProgressDrawable(d);
gressBar.setProgress(score);
}
//判斷是否是郵箱
publicbooleanisEmail(Stringemail){
Stringstr="^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)"
+"|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
Patternp=Ppile(str);
Matcherm=p.matcher(email);
returnm.matches();
}
}5.1.2管理員模塊管理員模塊是通過(guò)該系統(tǒng)PC端來(lái)實(shí)現(xiàn)的,其包括了管理員登錄和管理員注冊(cè)兩個(gè)頁(yè)面,如下圖所示。管理員通過(guò)驗(yàn)證登錄后可進(jìn)入景點(diǎn)添加頁(yè)面。圖5.4管理員登錄頁(yè)面圖5.5管理員注冊(cè)頁(yè)面5.2景點(diǎn)信息模塊設(shè)計(jì)首頁(yè)頁(yè)面是由三個(gè)fragment架構(gòu)的,其分為景點(diǎn)、附近、我的三個(gè)fragment。景點(diǎn)頁(yè)面的景點(diǎn)是由后臺(tái)添加的,由PC端的頁(yè)面進(jìn)入景點(diǎn)管理頁(yè)面。管理者通過(guò)登錄進(jìn)入景點(diǎn)添加頁(yè)面,景點(diǎn)的相關(guān)數(shù)據(jù)也是通過(guò)接口傳入后臺(tái)并將相應(yīng)的數(shù)據(jù)存入數(shù)據(jù)庫(kù),APP的景點(diǎn)頁(yè)面即顯示相應(yīng)的景點(diǎn)。(1)景點(diǎn)頁(yè)面景點(diǎn)頁(yè)面的fragment用的是RecyclerView控件,通過(guò)自定義的適配器HomeAdapter來(lái)展示景點(diǎn)的相關(guān)內(nèi)容,其包括景點(diǎn)名稱(chēng)、景點(diǎn)詳情、景點(diǎn)圖片、景點(diǎn)的經(jīng)緯度。圖5.6景點(diǎn)頁(yè)面主要實(shí)現(xiàn)代碼:publicclassHomeFragmentextendsFragment{publicViewonCreateView(@NonNullLayoutInflaterinflater,
ViewGroupcontainer,BundlesavedInstanceState){
Viewroot=inflater.inflate(R.layout.fragment_home,container,false);
initViews(root);
initData();
returnroot;
}
privatevoidinitData(){
//后臺(tái)接口獲取景區(qū)列表
Stringurl=Contstans.host+"/scenic";
RequestParamsparams=newRequestParams(url);
x.http().get(params,newCallback.CommonCallback<List<PlaceBean>>(){
@Override
publicvoidonSuccess(List<PlaceBean>result){
if(result!=null){homeAdapter.setList(result);}else{//沒(méi)有數(shù)據(jù)}}});}
/**初始化布局*/
HomeAdapterhomeAdapter;
privateRecyclerViewrecyclerView;
privatevoidinitViews(Viewview){
recyclerView=view.findViewById(R.id.list);
recyclerView.setLayoutManager(newLinearLayoutManager(getContext()));
homeAdapter=newHomeAdapter(getContext());
recyclerView.setAdapter(homeAdapter);
homeAdapter.setListenr(bean->{
DeatilsActivity.start(getContext(),bean);
});}}publicclassHomeAdapterextendsRecyclerView.Adapter{
publicvoidsetListenr(OnClickListenrlistenr){
this.listenr=listenr;}
publicvoidsetLatLng(LatLnglatLng){
this.latLng=latLng;}
publicHomeAdapter(Contextcontext){
this.context=context;}
publicvoidsetList(List<PlaceBean>list){
if(list!=null){
this.list=list;
notifyDataSetChanged();
}
}
@NonNull
@Override
publicRecyclerView.ViewHolderonCreateViewHolder(@NonNullViewGroupparent,intviewType){
Viewview
=LayoutInflater.from(context)
.inflate(R.layout.item_home,parent,false);
returnnewHomeViewHolder(view);}
@Override
publicvoidonBindViewHolder(@NonNullRecyclerView.ViewHolderholder,intposition){
PlaceBeanplaceBean=list.get(position);
HomeViewHolderviewHolder=(HomeViewHolder)holder;
if(placeBean.getImages()!=null)
{Stringurl=null;
if(placeBean.getImages().contains(",")){
String[]urls=placeBean.getImages().split(",");
url=Contstans.host+urls[0].replaceAll("\\\\","/");
}else{
url=Contstans.host+placeBean.getImages().replaceAll("\\\\","/");
Glide.with(context)
.load(url)
.error(R.mipmap.ico_error_img)
.into(viewHolder.imageView);}
viewHolder.textView.setText(placeBean.getName());
viewHolder.textView1.setText(placeBean.getInfo());
viewHolder.itemView.setOnClickListener(view->{
if(listenr!=null){
listenr.onClick(placeBean);}});
//跳轉(zhuǎn)到百度地圖導(dǎo)航
viewHolder.textView2.setOnClickListener(view->{
//后臺(tái)填的是反的,所以這里也反一下
Stringlog=placeBean.getLatitude();
Stringlat=placeBean.getLongitude();
if(TextUtils.isEmpty(lat)||TextUtils.isEmpty(log))
return;
Utils.naVgationToBaiduMap(context,newLatLng(Double.parseDouble(lat),Double.parseDouble(log)));
});}
@Override
publicintgetItemCount(){
if(list==null)
return0;
else
returnlist.size();}classHomeViewHolderextendsRecyclerView.ViewHolder{
ImageViewimageView;
TextViewtextView;
TextViewtextView1;
TextViewtextView2;
publicHomeViewHolder(@NonNullViewitemView){
super(itemView);
imageView=itemView.findViewById(R.id.image);
textView=itemView.findViewById(R.id.title);
textView1=itemView.findViewById(R.id.content);
textView2=itemView.findViewById(R.id.distans);}}
publicinterfaceOnClickListenr{
voidonClick(PlaceBeanbean);}}/**跳轉(zhuǎn)百度導(dǎo)航*@paramcontext*@paramlatLng*/
publicstaticvoidnaVgationToBaiduMap(Contextcontext,LatLnglatLng){Intentintent=context.getPackageManager().getLaunchIntentForPackage("com.baidu.BaiduMap");
if(intent==null){
Toast.makeText(context,"手機(jī)未安裝百度地圖",Toast.LENGTH_SHORT).show();
return;}
IntentbdNav=newIntent();
//步行導(dǎo)航
bdNav.setData(Uri.parse("baidumap://map/walknavi?origin="+latLng.latitude+","+latLng.longitude+"&destination=43.81710,125.38332&coord_type=bd09ll&src=andr.baidu.openAPIdemo"));
//騎行導(dǎo)航
//bdNav.setData(Uri.parse("baidumap://map/bikenavi?origin="+bdGPS[0]+","+bdGPS[1]+"&destination=43.81710,125.38332&coord_type=bd09ll&src=andr.baidu.openAPIdemo"));//駕車(chē)導(dǎo)航//bdNav.setData(Uri.parse("baidumap://map/navi?query=解放大路與人民大街交匯&src=andr.baidu.openAPIdemo"));
context.startActivity(bdNav);
}(2)景點(diǎn)詳情頁(yè)面景點(diǎn)詳情頁(yè)面顯示景點(diǎn)名稱(chēng)、詳情介紹。其介紹可由語(yǔ)音進(jìn)行播報(bào),這里引用了訊飛開(kāi)放平臺(tái)的在線(xiàn)語(yǔ)音合成。語(yǔ)音合成,又稱(chēng)文語(yǔ)轉(zhuǎn)換(TexttoSpeech,TTS)技術(shù),解決的主要問(wèn)題是如何將文字信息轉(zhuǎn)化為可聽(tīng)的聲音信息(即音頻數(shù)據(jù))。圖5.7景點(diǎn)詳情頁(yè)面主要實(shí)現(xiàn)代碼:publicclassDeatilsActivityextendsAppCompatActivity{
privateStringTAG="DeatilsActivity";
publicstaticvoidstart(Contextcontext,PlaceBeanbean){
Intentstarter=newIntent(context,DeatilsActivity.class);
starter.putExtra("bean",bean);
context.startActivity(starter);}
ActivityDeatilsBindingbinding;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
binding=ActivityDeatilsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
mediaPlayer=newMediaPlayer();
initTst();
initData();}
//初始化訊飛的合成語(yǔ)音
//語(yǔ)音合成對(duì)象
//默認(rèn)發(fā)音人
privateStringvoicer="xiaoyan";
privateSpeechSynthesizermTts;
/**初始化監(jiān)聽(tīng)。*/
privateInitListenermTtsInitListener=newInitListener(){
@Override
publicvoidonInit(intcode){
Log.d(TAG,"InitListenerinit()code="+code);
if(code!=ErrorCode.SUCCESS){
showTip("初始化失敗,錯(cuò)誤碼:"+code+",請(qǐng)點(diǎn)擊網(wǎng)址/document/error-code查詢(xún)解決方案");}else{//初始化成功,之后可以調(diào)用startSpeaking方法//注:有的開(kāi)發(fā)者在onCreate方法中創(chuàng)建完合成對(duì)象之后馬上就調(diào)用startSpeaking進(jìn)行合成,//正確的做法是將onCreate中的startSpeaking調(diào)用移至這里}}};
privatevoidshowTip(finalStringstr){
Toast.makeText(this,str,Toast.LENGTH_SHORT).show();}
privatevoidinitTst(){//訊飛初始化
mTts=SpeechSynthesizer.createSynthesizer(this,mTtsInitListener);
binding.btYuyin.setOnClickListener(view->{
if(null==mTts){
//創(chuàng)建單例失敗,與21001錯(cuò)誤為同樣原因,參考/forum.php?mod=viewthread&tid=9688
this.showTip("創(chuàng)建對(duì)象失敗,請(qǐng)確認(rèn)libmsc.so放置正確,且有調(diào)用createUtility進(jìn)行初始化");
return;
}
Stringtext=binding.tvContent.getText().toString();
if(TextUtils.isEmpty(text))
return;
mTts.startSpeaking(text,newSynthesizerListener(){});
});}
@Override
protectedvoidonDestroy(){
super.onDestroy();
//釋放資源
if(mediaPlayer!=null){
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
}if(mTts!=null){
mTts.stopSpeaking();
mTts.destroy();}}MediaPlayermediaPlayer;
privatevoidinitData(){
PlaceBeanplaceBean=(PlaceBean)getIntent().getSerializableExtra("bean");
if(placeBean!=null)
{if(placeBean.getImages()!=null)
{Stringurl=null;
if(placeBean.getImages().contains(",")){
String[]urls=placeBean.getImages().split(",");
url=Contstans.host+urls[0].replaceAll("\\\\","/");
}else
url=Contstans.host+placeBean.getImages().replaceAll("\\\\","/");
Glide.with(this)
.load(url)
.error(R.mipmap.ico_error_img)
.into(binding.imgImg);}
binding.title.setText("景點(diǎn)名稱(chēng):"+placeBean.getName());
binding.tvContent.setText("文字介紹:"+placeBean.getInfo());}}privatevoidinitMediaPlayer(Stringurl){
try{
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
}catch(IOExceptione){
e.printStackTrace();
}
}
}5.3附近景點(diǎn)與附近美食模塊設(shè)計(jì)附近模塊直接引用了百度地圖開(kāi)放平臺(tái),用到的是地圖和定位的sdk。由附近景點(diǎn)和附近美食兩部分組成,地圖可以放大或縮小。圖5.8附近頁(yè)面主要實(shí)現(xiàn)代碼:publicclassDashboardFragmentextendsFragment{
publicViewonCreateView(@NonNullLayoutInflaterinflater,
ViewGroupcontainer,BundlesavedInstanceState){
Viewroot=inflater.inflate(R.layout.fragment_dashboard,container,false);
initviews(root);
initData();
returnroot;}
privateinttype=0;//0是附近的景點(diǎn)1是附近的美食
privatevoidinitviews(Viewroot){
textureMapView=root.findViewById(R.id.map);
button=root.findViewById(R.id.location);
buttonMeiShi=root.findViewById(R.id.location_meishi);
baiduMap=
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度辦公樓租賃合同全新版
- 2025年度體育場(chǎng)館清潔工勞動(dòng)合同范本(含設(shè)施清潔與保養(yǎng))
- 2025年度租賃型公寓退房協(xié)議
- 二零二五年度電商企業(yè)客服外包智能服務(wù)系統(tǒng)合作協(xié)議
- 交通監(jiān)控設(shè)施安裝合同書(shū)樣本
- 二手房交易合同定金協(xié)議范本
- 二手房按揭貸款購(gòu)房合同
- 二手車(chē)輛買(mǎi)賣(mài)合同范本
- 個(gè)人股權(quán)轉(zhuǎn)讓合同范本標(biāo)準(zhǔn)
- 交通事故賠償協(xié)議合同范本大全
- 骨科手術(shù)的術(shù)后飲食和營(yíng)養(yǎng)指導(dǎo)
- 旅游定制師入行培訓(xùn)方案
- 奧數(shù)培訓(xùn)班課件
- 2024年中國(guó)南方航空股份有限公司招聘筆試參考題庫(kù)含答案解析
- 六年級(jí)上冊(cè)數(shù)學(xué)應(yīng)用題100題
- 個(gè)人代賣(mài)協(xié)議
- 賞析小說(shuō)語(yǔ)言(二)
- 【立高食品公司的償債能力現(xiàn)狀及問(wèn)題分析(論文9000字)】
- 10.《運(yùn)動(dòng)技能學(xué)習(xí)與控制》李強(qiáng)
- 冀教版數(shù)學(xué)七年級(jí)下冊(cè)綜合訓(xùn)練100題含答案
- 農(nóng)電公司績(jī)效考核管理辦法
評(píng)論
0/150
提交評(píng)論