版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
PAGE8一個(gè)基于安卓平臺(tái)的血壓監(jiān)測(cè)與分析系統(tǒng)設(shè)計(jì)摘要在不斷發(fā)展的當(dāng)今時(shí)代,血壓疾病一直是困擾人類(lèi)的一大疾病種類(lèi)。它不像其他疾病一樣有著獨(dú)特的癥狀,很多人都在不知不覺(jué)中患有血壓疾病。這就導(dǎo)致了我國(guó)國(guó)內(nèi)有著數(shù)量眾多的血壓疾病患者,他們都需要每天按時(shí)服用各種藥物。這些藥物有著不同的服藥時(shí)間和劑量,一些患者經(jīng)常記不住自己應(yīng)該服用的藥物。本文的主要工作是實(shí)現(xiàn)一個(gè)基于安卓平臺(tái)的血壓監(jiān)測(cè)與分析app,該app的主要功能有定時(shí)鬧鐘提醒、血壓數(shù)據(jù)錄入與折線圖顯示、服藥歷史記錄記錄與顯示。軟件使用了java語(yǔ)言在androidstudio平臺(tái)開(kāi)發(fā),通過(guò)sql數(shù)據(jù)庫(kù)來(lái)儲(chǔ)存數(shù)據(jù)。主要采用了toast、AlertDialog、MyDatabaseHelper等技術(shù)來(lái)進(jìn)行開(kāi)發(fā)。在本文中,第一章介紹了該app的研究背景,簡(jiǎn)要闡述了開(kāi)發(fā)使用的java語(yǔ)言和使用java語(yǔ)言開(kāi)發(fā)軟件的必要性。第二章則介紹了用戶(hù)對(duì)于這個(gè)app的需求以及app預(yù)計(jì)實(shí)現(xiàn)的功能。第三章介紹了該app對(duì)于每一模塊的底層邏輯設(shè)計(jì),為之后的開(kāi)發(fā)打下基礎(chǔ)。第四章描述了軟件各個(gè)頁(yè)面和模塊的代碼實(shí)現(xiàn)方式。第五章記錄了對(duì)app進(jìn)行各項(xiàng)測(cè)試后的結(jié)果。最后,第六章對(duì)整個(gè)論文進(jìn)行了一個(gè)總結(jié)。關(guān)鍵字:安卓,血壓監(jiān)測(cè)與分析目錄第1章緒論 61.1研究背景 61.2java語(yǔ)言與androidapp開(kāi)發(fā) 61.2.1java語(yǔ)言 61.2.2androidapp開(kāi)發(fā) 7 第2章個(gè)人血壓檢測(cè)與分析app需求與分析 102.1app對(duì)象人群 102.2app預(yù)計(jì)實(shí)現(xiàn)功能 102.3個(gè)人血壓檢測(cè)與分析app用例規(guī)格說(shuō)明 10第3章個(gè)人血壓檢測(cè)與分析app設(shè)計(jì) 123.1數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì) 123.1.1用戶(hù)數(shù)據(jù) 123.1.2服藥數(shù)據(jù) 123.1.3血壓數(shù)據(jù) 133.2登錄模塊邏輯設(shè)計(jì) 133.3服藥模塊邏輯設(shè)計(jì) 143.4血壓模塊邏輯設(shè)計(jì) 143.5個(gè)人模塊邏輯設(shè)計(jì) 15第4章個(gè)人血壓檢測(cè)與分析app實(shí)現(xiàn)與實(shí)現(xiàn) 164.1頁(yè)面布局及切換的實(shí)現(xiàn) 164.1.1登錄頁(yè)面 164.1.2注冊(cè)頁(yè)面 164.1.3服藥計(jì)劃顯示頁(yè)面 174.1.4添加服藥計(jì)劃頁(yè)面 184.1.5查看血壓頁(yè)面 184.1.6輸入血壓頁(yè)面 194.1.7個(gè)人信息頁(yè)面 204.1.8服藥歷史記錄查看頁(yè)面 204.1.9頁(yè)面切換的實(shí)現(xiàn) 214.2登錄與注冊(cè)的實(shí)現(xiàn) 244.3服藥計(jì)劃編輯及鬧鈴設(shè)置的實(shí)現(xiàn) 274.4血壓折線及時(shí)間段切換的實(shí)現(xiàn) 324.5過(guò)往服藥數(shù)據(jù)讀取的實(shí)現(xiàn) 354.6個(gè)人血壓檢測(cè)與分析app測(cè)試 364.6.1登陸及注冊(cè)測(cè)試 364.6.2服藥數(shù)據(jù)測(cè)試 364.6.3血壓數(shù)據(jù)測(cè)試 37第5章總結(jié)與展望 38參考文獻(xiàn) 39第1章緒論1.1研究背景隨著時(shí)間的不斷發(fā)展,智能手機(jī)已經(jīng)成為當(dāng)今人們手中不可或缺的一部分,智能手機(jī)的系統(tǒng)主要分為兩大類(lèi):ios和安卓。其中只有蘋(píng)果手機(jī)使用ios系統(tǒng),其余大部分手機(jī)均使用安卓操作系統(tǒng)。這導(dǎo)致了安卓系統(tǒng)的軟件開(kāi)發(fā)占據(jù)了移動(dòng)端軟件開(kāi)發(fā)的一大部分。高血壓等血壓疾病已經(jīng)成為了一大普遍疾病。它的定義是平均收縮壓≥140mmHg,平均舒張壓≥90mmHg[1]。我國(guó)高血壓患病率仍然處于較高水平,高血壓的危險(xiǎn)因素為男性、高齡、居住在城市、慢性病數(shù)量>1種、飲酒、血脂異常和糖尿病[2]。2013年中國(guó)有250萬(wàn)人死于高血壓,占全部死因的27.5%,傷殘調(diào)整壽命年的14.28%。2015年中國(guó)>18歲人群有2.445億高血壓患者。2017年,中國(guó)有254萬(wàn)(95%UI226萬(wàn)~282萬(wàn))人死于高收縮壓,其中95.7%(95.6%~96.4%)死于心血管病[3]。但是許多人對(duì)此并不重視。由此可知,我國(guó)社會(huì)上有相當(dāng)多一部分人有著對(duì)自己血壓進(jìn)行監(jiān)測(cè)記錄的需要,一旦發(fā)現(xiàn)血壓異?;蚩赡墚惓?,那么這些用戶(hù)就有了服藥的前提。有的人因?yàn)槟承┰蛉绶泵Φ娜粘H蝿?wù)或個(gè)人記憶力較差等原因經(jīng)常忘記服藥。這時(shí)就需要有一個(gè)軟件來(lái)提醒這些用戶(hù)該在何時(shí)服藥并記錄這些用戶(hù)的血壓情況以反饋身體狀況。本課題致力于基于安卓系統(tǒng)開(kāi)發(fā)一款個(gè)人血壓監(jiān)測(cè)與分析app,旨在為需要的用戶(hù)提供可視化的血壓變化監(jiān)測(cè)以及及時(shí)的服藥提醒服務(wù),能讓用戶(hù)直觀地了解自己的血壓變化。1.2java語(yǔ)言與androidapp開(kāi)發(fā)1.2.1java語(yǔ)言Java編程語(yǔ)言是一種面向?qū)ο蟮挠?jì)算機(jī)軟件項(xiàng)目開(kāi)發(fā)語(yǔ)言,是目前計(jì)算機(jī)領(lǐng)域最受歡迎的計(jì)算機(jī)編程語(yǔ)言之一。它是一種跨平臺(tái)語(yǔ)言,具備較高的安全性、平穩(wěn)性以及具有可移植性。此外,Java編程語(yǔ)言具有較多的開(kāi)發(fā)工具、軟件架構(gòu)模式和軟件包。能夠讓用戶(hù)在最短的時(shí)間內(nèi)搭建出一個(gè)安全可靠的屬于自己的應(yīng)用軟件平臺(tái)。Java語(yǔ)言的有效利用,不僅能讓整個(gè)開(kāi)發(fā)工作變得簡(jiǎn)單便捷,且該語(yǔ)言功能強(qiáng)大,能夠滿(mǎn)足用戶(hù)對(duì)軟件功能所提出的絕大部分要求[4]。java語(yǔ)言有著相當(dāng)大的前景和未來(lái)趨勢(shì),簡(jiǎn)要的概括一下可以總結(jié)為以下幾方面:集成化發(fā)展、Java手機(jī)市場(chǎng)龐大、Java將開(kāi)發(fā)桌面應(yīng)用系統(tǒng)、Java多線程機(jī)制較大發(fā)展空間[5]。java編程語(yǔ)言在安卓等平臺(tái)的應(yīng)用上更為普遍,對(duì)于安卓類(lèi)軟件開(kāi)發(fā),需要具備交互性操作,這也是開(kāi)發(fā)軟件時(shí)具備的重要特征。在實(shí)際開(kāi)發(fā)過(guò)程中,交互性得到充分的體現(xiàn),才能推動(dòng)智能化未來(lái)有更好的發(fā)展?;贘AVA的推動(dòng),編程設(shè)計(jì)更具針對(duì)性,含有的功能也在不斷的完善,種類(lèi)之間可以實(shí)現(xiàn)有效的交互,并且包含選擇性的特點(diǎn)。另外,java編程語(yǔ)言在軟件開(kāi)發(fā)中的應(yīng)用,可以有效將硬件與軟件區(qū)分開(kāi),建立更加完整的系統(tǒng),確保電子產(chǎn)品中軟件功能的獨(dú)立性,并且編程技術(shù)具有可移植性,可以在不同的電子產(chǎn)品中使用,實(shí)現(xiàn)java的交互[6]。在傳統(tǒng)的各種編程語(yǔ)言中,其大部分都存在一個(gè)顯著的缺陷,那就是只能在其使用的一體化計(jì)算機(jī)中使用,一旦脫離其計(jì)算機(jī)那么該語(yǔ)言編程就無(wú)法運(yùn)轉(zhuǎn),這也給系統(tǒng)開(kāi)發(fā)的發(fā)展帶來(lái)了極大的阻礙,因此,JAVA語(yǔ)言就很好的解決了這一問(wèn)題,JAVA語(yǔ)言的運(yùn)行與計(jì)算機(jī)的結(jié)構(gòu)是沒(méi)有直接關(guān)系的,也就是說(shuō)其語(yǔ)言的編寫(xiě)不只是局限于單個(gè)計(jì)算機(jī)之中,能夠在其他各種系統(tǒng)中進(jìn)行運(yùn)作,這也是JAVA語(yǔ)言的核心優(yōu)勢(shì)之一,相對(duì)于其他編程語(yǔ)言而言較為獨(dú)立,不會(huì)因在不同的計(jì)算機(jī)中而發(fā)生變化,在不同的結(jié)構(gòu)計(jì)算機(jī)中所顯示的數(shù)據(jù)相同,不因計(jì)算機(jī)系統(tǒng)的差異影響[7]。1.2.2安卓程序開(kāi)發(fā)安卓系統(tǒng)作為一個(gè)開(kāi)源的系統(tǒng),其有著相當(dāng)多的語(yǔ)言可以用于開(kāi)發(fā)對(duì)應(yīng)的app如C/C++/java/C#/python/ruby/go/javaScript+html等等。這些語(yǔ)言各有優(yōu)劣,java/C++/C#/go/C注重運(yùn)行效率,而其余語(yǔ)言則注重開(kāi)發(fā)效率。這些語(yǔ)言中主流的語(yǔ)言有java、C++和python三種。簡(jiǎn)單分析一下三種語(yǔ)言,C++重運(yùn)行效率。但是跨平臺(tái)性較弱。開(kāi)發(fā)難度較高。庫(kù)多,用的人多。Python,重開(kāi)發(fā)效率??缙脚_(tái)性高。開(kāi)發(fā)難度低,庫(kù)多,用的人多。Java。重開(kāi)發(fā)效率。不及python,重運(yùn)行效率,不及C++。開(kāi)發(fā)難度低。庫(kù)多。用的人多。對(duì)于開(kāi)發(fā)者來(lái)說(shuō),python在圖形處理方面效率不及另外兩門(mén)語(yǔ)言,而智能手機(jī)app開(kāi)發(fā)都要用到大量的圖形界面與處理,加之其沒(méi)有龐大的社區(qū)和庫(kù)可以使用,這使得他在安卓開(kāi)發(fā)中相對(duì)弱勢(shì)。C++這門(mén)語(yǔ)言依賴(lài)本地的C++庫(kù)進(jìn)行編譯,但不同框架中的編譯環(huán)境不盡相同,這就導(dǎo)致了使用C++的安卓程序在不同的手機(jī)上可能會(huì)表現(xiàn)出不同的結(jié)果,甚至導(dǎo)致出現(xiàn)各種Bug。這就代表著使用C++開(kāi)發(fā)安卓app時(shí)調(diào)試會(huì)更加困難與復(fù)雜,需要更多的糾錯(cuò)成本。同時(shí)C++程序的工程化也是一件十分麻煩的事情。java則有效地解決了上述問(wèn)題。雖然java的運(yùn)行效率不及C++,但手機(jī)端對(duì)效率的要求并不嚴(yán)格。java還可以通過(guò)虛擬機(jī)開(kāi)發(fā)來(lái)解決不同機(jī)器上的環(huán)境差異,只要在編寫(xiě)程序后將程序打包成運(yùn)行碼而非機(jī)器碼即可保持程序在不同環(huán)境中按同樣的方法運(yùn)行。java程序的開(kāi)發(fā)效率雖然比不上python等輕語(yǔ)言,但卻比c++高上許多。在選擇開(kāi)發(fā)語(yǔ)言時(shí),我們有很多的因素需要考慮,其中最主要的是環(huán)境考量、平臺(tái)適應(yīng)性、程序編寫(xiě)需求、語(yǔ)言編程熟練性和開(kāi)發(fā)成本這些因素[8]。Java語(yǔ)言的優(yōu)勢(shì)正在于能夠進(jìn)行圖像處理與描述,這兩方面的優(yōu)勢(shì)讓Java語(yǔ)言有了自己的一席之地。在實(shí)際編程的過(guò)程中,Java語(yǔ)言的好處就在于能夠進(jìn)行詳細(xì)的交互,從而讓用戶(hù)與軟件之間實(shí)現(xiàn)深入的互動(dòng),未來(lái)使用Java語(yǔ)言將能夠更好地進(jìn)行可視化編程[9]。在計(jì)算機(jī)軟件開(kāi)發(fā)中,為了滿(mǎn)足用戶(hù)觀看各種圖片、視頻的需求,可以使用JAVA編程語(yǔ)言進(jìn)行針對(duì)性功能開(kāi)發(fā)。通過(guò)JAVA編程語(yǔ)言,可以使軟件根據(jù)用戶(hù)的訪問(wèn)需求,調(diào)取各類(lèi)圖像、圖形。如果沒(méi)有JAVA編程語(yǔ)言的應(yīng)用,將無(wú)法實(shí)現(xiàn)計(jì)算機(jī)軟件的快速調(diào)用圖像、圖形功能,導(dǎo)致人們無(wú)法在使用軟件時(shí)獲得清晰、直觀的體驗(yàn),自然也無(wú)法實(shí)現(xiàn)軟件的多樣化功能[10]。總結(jié)一下,java語(yǔ)言的開(kāi)發(fā)效率介于python與c++之間,運(yùn)行效率也在兩者之間,是二者的一個(gè)平衡。同時(shí)通用性高,開(kāi)發(fā)性能好,受安卓母公司google的支持。故成為了現(xiàn)在安卓軟件開(kāi)發(fā)的最主流語(yǔ)言。個(gè)人血壓檢測(cè)與分析app需求分析2.1個(gè)人血壓檢測(cè)與分析app對(duì)象人群該軟件主要面向人群為存在血壓疾病的人群或任何需要定時(shí)服藥提醒的人群。2.2個(gè)人血壓檢測(cè)與分析app預(yù)計(jì)實(shí)現(xiàn)功能圖2.1用例圖根據(jù)用例圖顯示,用戶(hù)打開(kāi)軟件后根據(jù)其是否已有賬號(hào)決定其是否需要注冊(cè)賬號(hào),若無(wú)賬號(hào)則需要進(jìn)入注冊(cè)頁(yè)面進(jìn)行注冊(cè)。注冊(cè)功能可以允許用戶(hù)注冊(cè)屬于自己的可以用于該軟件的賬號(hào),不同賬號(hào)間的各類(lèi)數(shù)據(jù)都是不通用的。注冊(cè)賬戶(hù)之后用戶(hù)可以憑借自己的賬號(hào)登錄軟件主體。主體共分為三大項(xiàng),第一項(xiàng)是服藥,它允許用戶(hù)查看自己設(shè)置的服藥計(jì)劃,還可以通過(guò)右上角的加號(hào)來(lái)添加新的服藥計(jì)劃。第二項(xiàng)是血壓,這里可以顯示最近七天或十四天內(nèi)的血壓記錄,同樣可以通過(guò)右上角加號(hào)添加新的血壓測(cè)量數(shù)據(jù)。第三項(xiàng)為個(gè)人,用戶(hù)可以在這里退出登錄或查看過(guò)往所有的服藥歷史記錄。2.3個(gè)人血壓檢測(cè)與分析app用例規(guī)格說(shuō)明在這里我將對(duì)四個(gè)用例進(jìn)行規(guī)格說(shuō)明:登錄、注冊(cè)、添加服藥計(jì)劃和添加血壓。登錄:所有用戶(hù)說(shuō)明用戶(hù)登錄賬號(hào)前提條件用戶(hù)已有賬號(hào)后置條件用戶(hù)登錄成功基本事件流用戶(hù)打開(kāi)軟件->確認(rèn)賬號(hào)密碼已輸入->驗(yàn)證通過(guò)->用戶(hù)成功登錄異常事件流第一異常事件流用戶(hù)名或密碼為空第二異常事件流用戶(hù)名或密碼錯(cuò)誤注冊(cè):所有用戶(hù)說(shuō)明用戶(hù)注冊(cè)賬號(hào)前提條件用戶(hù)無(wú)已有帳號(hào)后置條件用戶(hù)注冊(cè)成功基本事件流用戶(hù)進(jìn)入注冊(cè)頁(yè)面->確認(rèn)賬號(hào)密碼已輸入->用戶(hù)成功注冊(cè)異常事件流第一異常事件流用戶(hù)名或密碼為空添加服藥計(jì)劃:所有用戶(hù)說(shuō)明用戶(hù)添加服藥計(jì)劃前提條件用戶(hù)已經(jīng)登陸后置條件用戶(hù)成功添加服藥計(jì)劃基本事件流用戶(hù)進(jìn)入添加服藥計(jì)劃頁(yè)面->輸入各項(xiàng)數(shù)據(jù)->選擇時(shí)間->用戶(hù)成功添加服藥計(jì)劃異常事件流添加血壓:所有用戶(hù)說(shuō)明用戶(hù)添加血壓數(shù)據(jù)前提條件無(wú)后置條件用戶(hù)成功添加血壓數(shù)據(jù)基本事件流用戶(hù)進(jìn)入添加血壓頁(yè)面->輸入各項(xiàng)數(shù)據(jù)->選擇時(shí)間->用戶(hù)成功添加血壓數(shù)據(jù)異常事件流第一異常事件流血壓數(shù)據(jù)值為空或不是數(shù)字第三章個(gè)人血壓檢測(cè)與分析app的設(shè)計(jì)3.1數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)本app中一共有三種數(shù)據(jù),分別為用戶(hù)數(shù)據(jù)、服藥數(shù)據(jù)以及血壓數(shù)據(jù)。3.1.1用戶(hù)數(shù)據(jù)對(duì)于用戶(hù)數(shù)據(jù),在數(shù)據(jù)庫(kù)中建立表user,表中數(shù)據(jù)分為三列。第一列為id,數(shù)據(jù)類(lèi)型為integer,第二列為name,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度100字節(jié),第三列為password,類(lèi)型為varchar,長(zhǎng)度100字節(jié)。其中id為該表主鍵。創(chuàng)建過(guò)程如圖3.1所示。id項(xiàng)為注冊(cè)新用戶(hù)名到更新數(shù)據(jù)庫(kù)時(shí)自動(dòng)創(chuàng)建,為標(biāo)識(shí)符。name項(xiàng)為用戶(hù)名,存在唯一性,數(shù)據(jù)庫(kù)內(nèi)無(wú)重復(fù)用戶(hù)名。passoword項(xiàng)為密碼,每個(gè)用戶(hù)使用其對(duì)應(yīng)的密碼進(jìn)行登錄,可以設(shè)置任意不為空字符串為密碼。圖3.1用戶(hù)數(shù)據(jù)表3.1.2服藥數(shù)據(jù)對(duì)于服藥數(shù)據(jù),在數(shù)據(jù)庫(kù)中建立表alarm,表中數(shù)據(jù)共有七列。第一列為id,數(shù)據(jù)類(lèi)型為integer,第二列為userId,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度100字節(jié),第三列為type,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度100字節(jié),第四列為meds,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度100字節(jié),第五列為amount,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度100字節(jié),第六列為tips,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度100字節(jié),第七列為time,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度100字節(jié)。其中id為該表主鍵。創(chuàng)建過(guò)程如圖3.2所示。id項(xiàng)為添加服藥計(jì)劃到數(shù)據(jù)庫(kù)時(shí)自動(dòng)創(chuàng)建,為標(biāo)識(shí)符。userId為當(dāng)前登錄用戶(hù)的id,從數(shù)據(jù)庫(kù)中讀取,用于區(qū)分不同用戶(hù)的服藥記錄。type為標(biāo)記用,通過(guò)不同數(shù)據(jù)判斷是否是被刪除過(guò)的數(shù)據(jù),被刪除過(guò)的數(shù)據(jù)在服藥界面不顯示,只在服藥歷史記錄中顯示。meds為藥品名稱(chēng)字符串。amount為該次服藥的數(shù)量。tips為用戶(hù)對(duì)該次服藥自行添加的備注。time為該次服藥記錄的時(shí)間,精度精確到分鐘。圖3.2服藥數(shù)據(jù)表3.1.3血壓數(shù)據(jù)對(duì)于血壓數(shù)據(jù),在數(shù)據(jù)庫(kù)中建立表bloodpressure,表中數(shù)據(jù)共五項(xiàng)。第一列為id,數(shù)據(jù)類(lèi)型為integer。第二列為userId,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度為100字節(jié)。第三列為hbp,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度為100字節(jié)。第四列為lbp,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度為100字節(jié)。第五列為time,數(shù)據(jù)類(lèi)型為varchar,長(zhǎng)度為100字節(jié)。其中id為該表主鍵。創(chuàng)建過(guò)程如圖3.3所示。id為錄入血壓數(shù)據(jù)到數(shù)據(jù)庫(kù)是自動(dòng)創(chuàng)建的,作為標(biāo)識(shí)符使用。userId為當(dāng)前登錄用戶(hù)的id,從數(shù)據(jù)庫(kù)讀取,用以區(qū)分不同用戶(hù)的血壓數(shù)據(jù)。hbp為血壓值中的收縮壓。lbp為血壓值中的舒張壓。time為本次血壓的測(cè)量時(shí)間。圖3.3血壓數(shù)據(jù)表3.2登錄模塊邏輯設(shè)計(jì)登錄模塊是打開(kāi)軟件后的第一個(gè)頁(yè)面,用戶(hù)在給定的兩個(gè)輸入框中分別輸入賬號(hào)(et_account)和密碼(et_password)。點(diǎn)擊登錄之后觸發(fā)按鈕的onclick函數(shù),由onclick函數(shù)先判斷用戶(hù)名或密碼是否為空,不為空則執(zhí)行Login函數(shù)。觸發(fā)函數(shù)后會(huì)進(jìn)入數(shù)據(jù)庫(kù)查找對(duì)應(yīng)的賬號(hào)密碼組合是否存在,存在相同賬號(hào)則提示登陸成功,并進(jìn)入系統(tǒng)主界面,不成功則返回登陸失敗,要求重新輸入。3.3服藥模塊邏輯設(shè)計(jì)服藥模塊主要分為兩個(gè)頁(yè)面:服藥計(jì)劃展示頁(yè)面和服藥計(jì)劃添加頁(yè)面。第一個(gè)頁(yè)面是服藥計(jì)劃展示頁(yè)面,它可以通過(guò)主菜單下側(cè)三個(gè)按鈕之中左側(cè)服藥按鈕點(diǎn)擊進(jìn)入,同時(shí)它也是登陸之后的默認(rèn)頁(yè)面。在頁(yè)面加載時(shí)通過(guò)initData()函數(shù)調(diào)用getData()函數(shù)讀取數(shù)據(jù)庫(kù)中存儲(chǔ)的服藥記錄。獲取到數(shù)據(jù)之后在頁(yè)面中的recyclerView中進(jìn)行顯示。與此同時(shí)每一條服藥計(jì)劃單元都有一個(gè)刪除按鈕用于在觸發(fā)后隱藏?zé)o效計(jì)劃。第二個(gè)頁(yè)面是服藥計(jì)劃添加頁(yè)面,它可以由服藥計(jì)劃展示頁(yè)面點(diǎn)擊右上角的加號(hào)進(jìn)入。該頁(yè)面共有三個(gè)輸入項(xiàng),一個(gè)文字框,第一個(gè)輸入框輸入藥物名稱(chēng)(et_01),第二個(gè)輸入框輸入藥物數(shù)量(et_02),第三個(gè)輸入框輸入用戶(hù)自定義的備注(et_03),文字框通過(guò)點(diǎn)擊激活對(duì)應(yīng)的onclick函數(shù),在onclick函數(shù)中調(diào)用android.app中的DatePickerDialog和TimePickerDialog打開(kāi)時(shí)間選擇界面。選擇結(jié)束后記在第文字框內(nèi)(et_04)。四個(gè)輸入項(xiàng)都完成之后點(diǎn)擊添加按鈕觸發(fā)對(duì)應(yīng)的onclick函數(shù),將三個(gè)輸入項(xiàng)與當(dāng)前時(shí)間組合成一個(gè)服藥計(jì)劃單元存入數(shù)據(jù)庫(kù)(db.insert),同時(shí)根據(jù)時(shí)間設(shè)定好對(duì)應(yīng)的鬧鐘(am.setExact)。3.4血壓模塊邏輯設(shè)計(jì)血壓模塊共分兩個(gè)頁(yè)面:血壓展示頁(yè)面和血壓添加頁(yè)面。第一個(gè)頁(yè)面是血壓展示頁(yè)面,它可以由主頁(yè)面下側(cè)菜單中間按鈕點(diǎn)擊進(jìn)入。進(jìn)入后頁(yè)面加載時(shí)會(huì)執(zhí)行initData函數(shù),隨之調(diào)用getData函數(shù)從數(shù)據(jù)庫(kù)中讀取當(dāng)前用戶(hù)的血壓記錄信息。讀取到之后調(diào)用setData函數(shù)來(lái)顯示當(dāng)前時(shí)間區(qū)段的血壓記錄值,在setData執(zhí)行的過(guò)程中initChartView函數(shù)被調(diào)用,折線圖根據(jù)setData中的數(shù)據(jù)被繪制出來(lái)。頁(yè)面上還有兩個(gè)按鈕,通過(guò)這兩個(gè)按鈕的onclick函數(shù),用戶(hù)可以通過(guò)setData的輸入切換顯示過(guò)去七天或過(guò)去兩周的血壓記錄。第二個(gè)頁(yè)面是血壓添加頁(yè)面,它可以通過(guò)血壓頁(yè)面右上角加號(hào)點(diǎn)擊進(jìn)入。在這個(gè)頁(yè)面中,用戶(hù)需要輸入測(cè)量出的收縮壓(et_num),舒張壓(et_num2)。第三個(gè)輸入框內(nèi)為血壓測(cè)量時(shí)間(et_time),該時(shí)間由DatePickerDialog選擇后直接賦值。點(diǎn)擊添加按鈕觸發(fā)對(duì)應(yīng)的onclick函數(shù),將三個(gè)數(shù)據(jù)組合成血壓數(shù)據(jù)單元存放至數(shù)據(jù)庫(kù)中(db.insert)。3.5個(gè)人模塊邏輯設(shè)計(jì)個(gè)人模塊共兩個(gè)頁(yè)面:個(gè)人信息頁(yè)面和服藥歷史記錄頁(yè)面。第一個(gè)頁(yè)面是個(gè)人信息頁(yè)面,它可以通過(guò)主頁(yè)面下側(cè)菜單右側(cè)按鈕進(jìn)入。該頁(yè)面可以顯示當(dāng)前登錄用戶(hù)的用戶(hù)名,同時(shí)有兩個(gè)可點(diǎn)擊內(nèi)容。點(diǎn)擊服藥記錄可以跳轉(zhuǎn)至服藥歷史記錄頁(yè)面。點(diǎn)擊退出登錄則執(zhí)行onclick函數(shù)跳轉(zhuǎn)回到登錄頁(yè)面第二個(gè)頁(yè)面是服藥歷史記錄頁(yè)面,它通過(guò)個(gè)人信息頁(yè)面點(diǎn)擊服藥歷史進(jìn)入。頁(yè)面加載時(shí)調(diào)用getData函數(shù)獲取對(duì)應(yīng)用戶(hù)過(guò)往服藥記錄。讀取后通過(guò)setAdapter函數(shù)顯示到recyclerView當(dāng)中。第4章個(gè)人血壓檢測(cè)與分析app的實(shí)現(xiàn)與測(cè)試4.1頁(yè)面布局及切換的實(shí)現(xiàn)該app共包含8個(gè)頁(yè)面,分別是登錄頁(yè)面,注冊(cè)頁(yè)面,服藥計(jì)劃顯示頁(yè)面,添加服藥計(jì)劃頁(yè)面,查看血壓頁(yè)面,輸入血壓頁(yè)面,個(gè)人信息頁(yè)面,服藥歷史記錄查看頁(yè)面。4.1.1登錄頁(yè)面該頁(yè)面為登錄用的主界面,進(jìn)入軟件后的第一個(gè)頁(yè)面,頂部有文字提示該頁(yè)面為登錄頁(yè)面。下方頁(yè)面有一張背景圖片、一句歡迎語(yǔ)、兩個(gè)包含提示的輸入框以及一個(gè)登錄按鈕和指向注冊(cè)頁(yè)面的跳轉(zhuǎn)文字。具體實(shí)現(xiàn)效果如圖4.1所示圖4.1登錄頁(yè)面4.1.2注冊(cè)頁(yè)面該頁(yè)面為注冊(cè)用頁(yè)面。頂部有文字提示該頁(yè)面為注冊(cè)頁(yè)面,左側(cè)有返回登錄頁(yè)面的叉號(hào),下方為背景圖片,一句提示語(yǔ)、兩個(gè)包含提示的輸入框和注冊(cè)按鈕。具體實(shí)現(xiàn)效果如圖4.2所示圖4.2注冊(cè)頁(yè)面4.1.3服藥計(jì)劃顯示頁(yè)面該頁(yè)面為服藥計(jì)劃顯示頁(yè)面,頂部標(biāo)題提示該頁(yè)面為服藥計(jì)劃頁(yè)面,右側(cè)加號(hào)點(diǎn)擊后可以進(jìn)入添加服藥計(jì)劃頁(yè)面。中間為服藥計(jì)劃展示部分,每一條服藥計(jì)劃都會(huì)按照格式顯示在屏幕上,從上到下依次排列。底部為底部菜單欄,用以切換三個(gè)主要頁(yè)面。具體實(shí)現(xiàn)效果如圖4.3所示圖4.3服藥計(jì)劃展示頁(yè)面4.1.4添加服藥計(jì)劃頁(yè)面該頁(yè)面為添加服藥計(jì)劃頁(yè)面,頂部標(biāo)題提示該頁(yè)面為添加服藥計(jì)劃頁(yè)面。下側(cè)一共三個(gè)輸入框一個(gè)文字框。文字框分別輸入藥物名稱(chēng)、藥物數(shù)量以及備注。文字框通過(guò)點(diǎn)選來(lái)選擇提示時(shí)間。最下面為添加按鈕,點(diǎn)擊后可以添加一個(gè)服藥計(jì)劃。圖4.4添加服藥計(jì)劃頁(yè)面4.1.5查看血壓頁(yè)面該頁(yè)面為查看血壓頁(yè)面,頂部標(biāo)題提示該頁(yè)面為查看血壓頁(yè)面。標(biāo)題右側(cè)加號(hào)點(diǎn)擊可以進(jìn)入輸入血壓頁(yè)面。中部為主要部分,偏上側(cè)為根據(jù)所選時(shí)間段繪制的血壓值折線。中間為兩個(gè)按鈕,點(diǎn)擊以切換血壓折線時(shí)間段,分別有一周內(nèi)和兩周內(nèi)兩種選項(xiàng)。偏下側(cè)為對(duì)應(yīng)時(shí)間段所有血壓值的列表,每一條都顯示了該次測(cè)量血壓的收縮壓、舒張壓和測(cè)量時(shí)間。最下方為底部菜單欄用以切換三大主要頁(yè)面。具體實(shí)現(xiàn)效果如圖4.5所示。圖4.5查看血壓頁(yè)面4.1.6輸入血壓頁(yè)面該頁(yè)面為血壓輸入頁(yè)面,主要包含三個(gè)輸入框和一個(gè)按鈕。輸入框分別有著對(duì)應(yīng)的名字和提示。其中時(shí)間輸入為點(diǎn)擊后選擇日期。在輸入框下面是用于添加的按鈕。具體實(shí)現(xiàn)效果如圖4.6所示。圖4.6輸入血壓頁(yè)面4.1.7個(gè)人信息頁(yè)面該頁(yè)面為個(gè)人信息頁(yè)面,主要分為三部分。頂部為簡(jiǎn)易的頭像和狀態(tài)顯示以及用戶(hù)名顯示。中部為服藥歷史記錄頁(yè)面的入口和退出登錄按鈕。入口按鈕右側(cè)有裝飾用箭頭指示。下方為主頁(yè)面包含的底部菜單欄,用于在三大主頁(yè)面間進(jìn)行切換。圖4.7個(gè)人信息頁(yè)面4.1.8服藥歷史記錄查看頁(yè)面該頁(yè)面為服藥歷史記錄查看頁(yè)面。頂部有文字提醒該頁(yè)面顯示歷史服藥記錄。下側(cè)為該用戶(hù)對(duì)應(yīng)的歷史服藥記錄。每一條記錄都有四個(gè)部分,分別是名稱(chēng)、數(shù)量、備注和日期。前三項(xiàng)為用戶(hù)自行輸入的數(shù)據(jù),最后一項(xiàng)是精準(zhǔn)度到分的標(biāo)準(zhǔn)時(shí)間格式。圖4.8服藥歷史記錄查看頁(yè)面4.1.9頁(yè)面切換的實(shí)現(xiàn)在這個(gè)程序中一共存在兩種頁(yè)面的切換,第一種是同activity不同fragment間的切換,另外一種是不同activity之間的切換。對(duì)于第一種而言,它存在于MainActivity中,服藥計(jì)劃顯示頁(yè)面、查看血壓頁(yè)面和個(gè)人信息頁(yè)面都是基于MainActivity的不同fragment。當(dāng)某一fragment的選項(xiàng)被選中時(shí),觸發(fā)對(duì)應(yīng)的OnCheckedChangeListener。這時(shí)會(huì)執(zhí)行切換樣式及fragment的函數(shù)。切換時(shí)首先建立一個(gè)FragmentTransactionft。然后將當(dāng)前activity賦值給ft。這可以獲取到當(dāng)前正在顯示的fragment,將它隱藏。然后通過(guò)傳入的參數(shù)判斷我要切換到的目標(biāo)fragment。找到后要先檢查該fragment是否為空即未創(chuàng)建狀態(tài),若頁(yè)面未創(chuàng)建則需將其創(chuàng)建后添加至ft中。然后使用ft.show函數(shù)將其顯示出來(lái)。而對(duì)于第二種來(lái)說(shuō),安卓程序中一般通過(guò)點(diǎn)擊方式切換頁(yè)面。我給每一個(gè)用于切換頁(yè)面的按鈕都綁定了對(duì)應(yīng)的onclick函數(shù)。在這些onclick函數(shù)中分別使用intent指定要跳轉(zhuǎn)的目標(biāo)頁(yè)面,使用startActivity函數(shù)完成頁(yè)面切換,以查看血壓頁(yè)面到輸入血壓頁(yè)面為例。核心代碼://初始化監(jiān)聽(tīng)器.protectedvoidinitListener(){//使用擴(kuò)展類(lèi)的初始化函數(shù).super.initListener();//為下側(cè)單選組添加改變監(jiān)聽(tīng)器.mainRadioGroup.setOnCheckedChangeListener(newRadioGroup.OnCheckedChangeListener(){@OverridepublicvoidonCheckedChanged(RadioGroupradioGroup,intcheckedId){switch(checkedId){caseR.id.rb_plan:ImmersionBar.with(MainActivity.this).keyboardEnable(false).statusBarDarkFont(true).init();showFragment(0);break;caseR.id.rb_bloodpressure:showFragment(1);ImmersionBar.with(MainActivity.this).keyboardEnable(false).statusBarDarkFont(true,0.2f).navigationBarColor(R.color.btn3).init();break;caseR.id.rb_my:showFragment(2);ImmersionBar.with(MainActivity.this).keyboardEnable(false).statusBarDarkFont(true,0.2f).navigationBarColor(R.color.btn3).init();break;}}});}//顯示視圖publicvoidshowFragment(inti){FragmentTransactionft=getSupportFragmentManager().beginTransaction();hideFragments(ft);switch(i){case0:if(planFragment!=null)ft.show(planFragment);else{planFragment=newPlanFragment();ft.add(R.id.frameLayout,planFragment);}break;case1:if(bpFragment!=null)ft.show(bpFragment);else{bpFragment=newBloodPressureFragment();ft.add(R.id.frameLayout,bpFragment);}break;case2:if(meFragment!=null)ft.show(meFragment);else{meFragment=newMeFragment();ft.add(R.id.frameLayout,meFragment);}ImmersionBar.with(this).keyboardEnable(false).statusBarDarkFont(false).navigationBarColor(R.color.colorPrimary).init();break;}mit();}//隱藏視圖privatevoidhideFragments(FragmentTransactionft2){if(planFragment!=null)ft2.hide(planFragment);if(bpFragment!=null)ft2.hide(bpFragment);if(meFragment!=null)ft2.hide(meFragment);}4.2登錄與注冊(cè)的實(shí)現(xiàn)用戶(hù)在初次登錄時(shí)或者手動(dòng)退出登錄之后需要進(jìn)行登錄,這時(shí)如果用戶(hù)沒(méi)有一個(gè)賬號(hào),就進(jìn)入了注冊(cè)流程。注冊(cè)時(shí)用戶(hù)需要輸入一對(duì)用戶(hù)名和密碼,用戶(hù)名可以是任意不超過(guò)100字符的字符串,但不能與已有用戶(hù)名重復(fù)。密碼則是一個(gè)不超過(guò)100字符的非空字符串。除此之外沒(méi)有限制。當(dāng)用戶(hù)輸入完成口點(diǎn)擊注冊(cè)按鈕(btn_register)后會(huì)觸發(fā)它的onclick函數(shù),此時(shí)會(huì)判斷用戶(hù)名或密碼是否存在空串,如果有則會(huì)用toast顯示對(duì)應(yīng)的提示文字并返回。若滿(mǎn)足均為非空串的條件下會(huì)執(zhí)行下一步,記錄下用戶(hù)名和密碼,建立SQLiteDatabasedb來(lái)去數(shù)據(jù)庫(kù)中查找對(duì)應(yīng)用戶(hù)名,若用戶(hù)名已經(jīng)存在則會(huì)提示用戶(hù)名已存在然后返回。否則會(huì)將新的用戶(hù)名密碼對(duì)存放至數(shù)據(jù)庫(kù)中。用戶(hù)名注冊(cè)成功后會(huì)返回登錄界面。在登錄界面內(nèi),用戶(hù)需要輸入自己已經(jīng)注冊(cè)過(guò)的用戶(hù)名及密碼。之后點(diǎn)擊登錄按鈕(btn_login)后觸發(fā)對(duì)應(yīng)的onclick函數(shù),該函數(shù)讀取頁(yè)面中的用戶(hù)名和密碼并將其傳輸給login函數(shù)作為輸入值。login函數(shù)中新建了一個(gè)SQLiteDatabasedb,使用傳入的用戶(hù)名和密碼對(duì)數(shù)據(jù)庫(kù)進(jìn)行檢索,找到完全匹配的用戶(hù)名密碼對(duì)則成功登錄,進(jìn)入系統(tǒng)主界面。失敗則提示用戶(hù)名或密碼錯(cuò)誤,請(qǐng)重試。核心代碼:注冊(cè)實(shí)現(xiàn):databaseHelper=newMyDatabaseHelper(this,"user.db",null,1);btn_register.setOnClickListener(newView.OnClickListener(){//為注冊(cè)按鈕綁定點(diǎn)擊事件的監(jiān)聽(tīng)@OverridepublicvoidonClick(Viewview){//兩項(xiàng)都為空if(StringUtils.getEditTextData(et_account).isEmpty()&&StringUtils.getEditTextData(etPassword).isEmpty()){ToastUtils.showToast(RegisterActivity.this,"請(qǐng)輸入用戶(hù)名或密碼.");return;}//用戶(hù)名為空if(StringUtils.getEditTextData(et_account).isEmpty()){ToastUtils.showToast(RegisterActivity.this,"請(qǐng)輸入用戶(hù)名.");return;}//密碼為空if(StringUtils.getEditTextData(et_password).isEmpty()){ToastUtils.showToast(RegisterActivity.this,"請(qǐng)輸入密碼.");return;}Stringusername=StringUtils.getEditTextData(et_account);Stringpassword=StringUtils.getEditTextData(et_password);SQLiteDatabasedb=databaseHelper.getWritableDatabase();Cursorcursor=db.rawQuery("select*fromuserwherename=?",newString[]{username});if(cursor.moveToNext()){Toast.makeText(RegisterActivity.this,"該賬號(hào)已被注冊(cè).",Toast.LENGTH_SHORT).show();}else{ContentValuesvalues=newContentValues();//把賬號(hào)和密碼添加到value中.values.put("name",username);values.put("password",password);db.insert("user",null,values);//提示信息.Toast.makeText(RegisterActivity.this,"賬號(hào)注冊(cè)成功.",Toast.LENGTH_SHORT).show();finish();}}});登錄實(shí)現(xiàn):@OnClick({R.id.btn_login})publicvoidonViewClicked(Viewview){//綁定點(diǎn)擊事件.switch(view.getId()){//如果是登錄按鈕.caseR.id.btn_login:if(StringUtils.getEditTextData(et_account).isEmpty()&&StringUtils.getEditTextData(et_password).isEmpty()){ToastUtils.showToast(this,"請(qǐng)輸入賬號(hào)和密碼");return;}if(StringUtils.getEditTextData(et_account).isEmpty()){ToastUtils.showToast(this,"請(qǐng)輸入賬號(hào)");return;}if(StringUtils.getEditTextData(et_password).isEmpty()){ToastUtils.showToast(this,"請(qǐng)輸入密碼");return;}Stringusername=StringUtils.getEditTextData(et_account);Stringpassword=StringUtils.getEditTextData(et_password);Login(username,password);break;}}privatevoidLogin(Stringusername,Stringpassword){SQLiteDatabasedb=databaseHelper.getReadableDatabase();//在數(shù)據(jù)庫(kù)中查找對(duì)應(yīng)賬號(hào)密碼.Cursorcursor=db.rawQuery("select*fromuserwherename=?andpassword=?",newString[]{username,password});if(cursor.moveToNext()){//獲取當(dāng)前行用戶(hù)id.intuserId=cursor.getInt(cursor.getColumnIndex("id"));Toast.makeText(LoginActivity.this,"登錄成功!",Toast.LENGTH_SHORT).show();SPUtils.put(LoginActivity.this,"name",username);SPUtils.put(LoginActivity.this,"userId",userId+"");//切換至主頁(yè)面Intentintent=newIntent(loginActivity.this,mainActivity.class);startActivity(intent);//刪除登陸頁(yè)面finish();}else{//登陸失敗Toast.makeText(LoginActivity.this,"賬號(hào)或密碼錯(cuò)誤,請(qǐng)重新輸入",Toast.LENGTH_SHORT).show();}}4.3服藥計(jì)劃編輯及鬧鈴設(shè)置的實(shí)現(xiàn)服藥計(jì)劃方面,我將每一個(gè)服藥計(jì)劃都當(dāng)作一個(gè)鬧鐘項(xiàng)來(lái)處理。對(duì)于服藥計(jì)劃,我設(shè)置了一個(gè)alarmBean,它的屬性id,userId,type,content1,content2,content3和time這幾項(xiàng)。方法則是每一項(xiàng)屬性的getter和setter函數(shù)。對(duì)于添加服藥計(jì)劃數(shù)據(jù)來(lái)說(shuō),在activity_add.xml中,我將添加按鈕賦予一個(gè)id:btn_add。此時(shí)頁(yè)面中存在4個(gè)數(shù)據(jù):et_01、et_o3、et_03、et_04。他們分別代表了名稱(chēng)、數(shù)量、備注和時(shí)間四項(xiàng)。這個(gè)xml所對(duì)應(yīng)的java文件為addalarmActivity.java。在java類(lèi)中,我使用了butterknife框架中的bindView來(lái)獲取數(shù)據(jù)和選中按鈕。@BindView(R.id.et_01)EditTextet_01;@BindView(R.id.et_02)EditTextet_02;@BindView(R.id.et_03)EditTextet_03;@BindView(R.id.et_04)TextViewet_04;@BindView(R.id.btn_add)Buttonbtn_add;該頁(yè)面中第四項(xiàng)的et_04為T(mén)extView,點(diǎn)擊后觸發(fā)onclick函數(shù)。函數(shù)中讀取當(dāng)前時(shí)間并記錄。然后這里我使用了android的DatePickerDialog和timePickerDialog函數(shù),將之前讀取到的時(shí)間自動(dòng)導(dǎo)入并修改來(lái)獲得用戶(hù)想要的時(shí)間組合。最后將分散的時(shí)間變量組合成時(shí)間字符串返回到et_04當(dāng)中顯示給用戶(hù)。該頁(yè)面中的btn_add按鈕在點(diǎn)擊后會(huì)觸發(fā)onclick函數(shù)。觸發(fā)后由于還在同一個(gè)頁(yè)面,java數(shù)據(jù)共享,我們可以直接獲取到在DatePickerDialog和timePickerDialog函數(shù)中組合得到的時(shí)間,將其轉(zhuǎn)換成date類(lèi)型再通過(guò)getTime方法轉(zhuǎn)換為鬧鐘需要的long型整數(shù)。最后通過(guò)alarmManager的am.setExact方法來(lái)設(shè)置一個(gè)精準(zhǔn)鬧鐘。設(shè)置好了鬧鐘之后要將該數(shù)據(jù)添加到數(shù)據(jù)庫(kù)存儲(chǔ)起來(lái),通過(guò)之前的處理我們可以得到時(shí)間字符串和之前獲取的et_01-et_03。id通過(guò)Sputils獲取一個(gè)id,type值為默認(rèn)的0。這樣就獲得了一個(gè)標(biāo)準(zhǔn)的數(shù)據(jù)單元。此時(shí)創(chuàng)建一個(gè)SQLiteDatabase類(lèi)型的數(shù)據(jù)來(lái)獲取數(shù)據(jù)庫(kù)db,再用db.insert將該數(shù)據(jù)插入數(shù)據(jù)庫(kù)中。核心代碼:publicvoidonClick(Viewv){switch(v.getId()){caseR.id.et_04:calendar.setTimeInMillis(System.currentTimeMillis());finalinttyear=calendar.get(Calendar.YEAR);finalinttmonth=calendar.get(Calendar.MONTH);finalinttday=calendar.get(Calendar.DAY_OF_MONTH);finalinttmhour=calendar.get(Calendar.HOUR_OF_DAY);finalintmminute=calendar.get(Calendar.MINUTE);newDatePickerDialog(AddAlarmActivity.this,newDatePickerDialog.OnDateSetListener(){@OverridepublicvoidonDateSet(DatePickerdatePicker,finalintyear,finalintmonth,finalintday){newTimePickerDialog(AddAlarmActivity.this,newTimePickerDialog.OnTimeSetListener(){@OverridepublicvoidonTimeSet(TimePickerview,intthourOfDay,inttminute){calendar.set(Calendar.YEAR,year);calendar.set(Calendar.DAY_OF_MONTH,day);calendar.set(Calendar.MINUTE,tminute);calendar.set(Calendar.MONTH,month);calendar.set(Calendar.MILLISECOND,0);calendar.set(Calendar.HOUR_OF_DAY,thourOfDay);calendar.set(Calendar.SECOND,0);yearformat=format(tyear);monthformat=format(month+1);dayformat=format(day);hourformat=format(hourOfDay);minuteformat=format(minute);Strings=yearformat+"-"+monthformat+"-"+dayformat+""+hourformat+":"+minuteformat;s3=yearformat+"-"+monthformat+"-"+dayformat+""+hourformat+":"+minuteformat+":"+"00";et_04.setText(s);}},mhour,mminute,true).show();}},tyear,tmonth,tday).show();break;caseR.id.btn_add:SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");try{Datedate=simpleDateFormat.parse(s3);longts=date.getTime();Randomr=newRandom();Intentintent=newIntent(AddAlarmActivity.this,CallAlarm.class);intent.putExtra("meds",et_01.getText().toString().trim());PendingIntentsender=PendingIntent.getBroadcast(AddAlarmActivity.this,r.nextInt(),intent,PendingIntent.FLAG_UPDATE_CURRENT);AlarmManageramanager;amanager=(AlarmManager)getSystemService(ALARM_SERVICE);if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){amanager.setExact(AlarmManager.RTC_WAKEUP,ts,sender);}}catch(Exceptione){e.printStackTrace();}Stringtrim=et_01.getText().toString().trim();Stringtrim_3=et_03.getText().toString().trim();Stringtrim_2=et_02.getText().toString().trim();SQLiteDatabasedb=databaseHelper.getReadableDatabase();ContentValuesvalues=newContentValues();values.put("userId",(String)SPUtils.get(AddAlarmActivity.this,"userId",""));values.put("tips",trim_3);values.put("meds",trim);values.put("type","0");values.put("amount",trim_2);values.put("time",s3);db.insert("alarm",null,values);Toast.makeText(AddAlarmActivity.this,"計(jì)劃添加成功!",Toast.LENGTH_SHORT).show();Intentintent=newIntent();intent.setAction("freshHome");sendBroadcast(intent);finish();break;}}對(duì)于查看當(dāng)前服藥計(jì)劃來(lái)說(shuō),使用的頁(yè)面為fragment_plan.xml文件。其對(duì)應(yīng)了兩個(gè)java文件:mainActivity和PlanFragment。其中mainActivity主要提供頁(yè)面切換功能,此處不做詳細(xì)介紹。查看服藥計(jì)劃主要代碼均位于PlanFragment.java文件中。首先是頁(yè)面創(chuàng)建時(shí)時(shí)由extends出的baseActivity調(diào)用的initData函數(shù),該函數(shù)會(huì)調(diào)用getData函數(shù)從數(shù)據(jù)庫(kù)中讀取所有屬于當(dāng)前用戶(hù)且未被標(biāo)記成刪除記錄(type=0)的服藥計(jì)劃。此時(shí)我取得了一個(gè)cursor游標(biāo),每次游標(biāo)移動(dòng)后我都新創(chuàng)建一個(gè)alarmbean,并從cursor中讀取各項(xiàng)數(shù)據(jù)再放入alarmbean中。當(dāng)我完成一個(gè)alarmbean之后將其加入事先創(chuàng)建好的數(shù)組list中。全部數(shù)據(jù)讀取之后通過(guò)adapter中的alarmadapter獲取list_item_plan中預(yù)設(shè)的單元樣式。最后用setAdapter將整個(gè)列表中的數(shù)據(jù)單元放入fragment_plan頁(yè)面中的RecyclerView標(biāo)簽中。核心代碼:privatevoidgetData(){SQLiteDatabasedb=databaseHelper.getReadableDatabase();lists.clear();Cursorcursor=db.rawQuery("select*fromalarmwhereuserId=?andtype=?",newString[]{(String)SPUtils.get(getActivity(),"userId",""),"0"});while(cursor.moveToNext()){AlarmBeanalarmBean=newAlarmBean();intid=cursor.getInt(cursor.getColumnIndex("id"));StringuserId_1=cursor.getString(cursor.getColumnIndex("userId"));Stringtype_1=cursor.getString(cursor.getColumnIndex("type"));Stringmeds=cursor.getString(cursor.getColumnIndex("meds"));Stringamount=cursor.getString(cursor.getColumnIndex("amount"));Stringtips=cursor.getString(cursor.getColumnIndex("tips"));Stringtime=cursor.getString(cursor.getColumnIndex("time"));alarmBean.setId(id);alarmBean.setUserId(userId_1);alarmBean.setMeds(meds);alarmBean.setAmount(amount);alarmBean.setTips(tips);alarmBean.setTime(time);alarmBean.setType(type_1);lists.add(alarmBean);}adapter=newAlarmAdapter(getActivity(),R.layout.list_item_plan,lists);recyclerView.setAdapter(adapter);}4.4血壓折線及時(shí)間段切換的實(shí)現(xiàn)血壓數(shù)據(jù)在錄入時(shí)與去除了鬧鈴功能的服藥計(jì)劃數(shù)據(jù)的錄入過(guò)程幾乎完全一致,在此不做過(guò)多解釋。當(dāng)獲得了血壓數(shù)據(jù)后,在血壓界面創(chuàng)建時(shí)會(huì)根據(jù)時(shí)間段讀取血壓數(shù)據(jù)來(lái)繪制圖表和輸出,默認(rèn)時(shí)間段為包括當(dāng)天在內(nèi)的最近七天。在初始創(chuàng)建或點(diǎn)擊按鈕更新時(shí)調(diào)用setData函數(shù),通過(guò)輸入不同數(shù)字來(lái)更改時(shí)間段。在setData中,我使用了Calendar.getInstance來(lái)獲取當(dāng)前時(shí)間,根據(jù)輸入時(shí)間段用Calendar.add來(lái)調(diào)整日期。使用Calendar.getTime將時(shí)間導(dǎo)入到一個(gè)date對(duì)象中。此時(shí)執(zhí)行dateToWeek函數(shù),通過(guò)循環(huán)將整個(gè)日期列表處理完成后返回一個(gè)list。該list里包含了整個(gè)時(shí)間段的日期,獲取到日期之后進(jìn)行循環(huán),對(duì)每一個(gè)日期在數(shù)據(jù)庫(kù)中尋找userId和日期都匹配的數(shù)據(jù),找不到則置零。全部完成后調(diào)用initChartView函數(shù)完成對(duì)折線圖的渲染,使用adapter獲取預(yù)先設(shè)置好的血壓?jiǎn)卧袷竭M(jìn)行渲染并放入fragment_bloodpressure.xml頁(yè)面中的RecyclerView中顯示。核心代碼:privatevoidsetData(intprogress){listString.clear();SimpleDateFormatformat=newSimpleDateFormat("yyyy-MM-dd");Calendarc=Calendar.getInstance();c.add(Calendar.DATE,progress*-1);Dated=c.getTime();List<Date>days=dateToWeek(d,progress);for(Datedate:days){listString.add(format.format(date));}for(inti=0;i<listString.size();i++){SQLiteDatabasedb=databaseHelper.getReadableDatabase();Cursorcursor=db.rawQuery("select*frombloodpressurewhereuserId=?andtime=?",newString[]{(String)SPUtils.get(getActivity(),"userId",""),listString.get(i)});if(cursor.moveToNext()){BloodPressureBeanbloodpressureBean=newBloodPressureBean();intid=cursor.getInt(cursor.getColumnIndex("id"));StringuserId1=cursor.getString(cursor.getColumnIndex("userId"));Stringhbp=cursor.getString(cursor.getColumnIndex("hbp"));Stringlbp=cursor.getString(cursor.getColumnIndex("lbp"));Stringtime=cursor.getString(cursor.getColumnIndex("time"));bloodpressureBean.setId(id);bloodpressureBean.setUserId(userId1);bloodpressureBean.setTime(time);bloodpressureBean.setHbp(hbp);bloodpressureBean.setLbp(lbp);lists.add(bloodpressureBean);}else{BloodPressureBeanbloodpressureBean=newBloodPressureBean();bloodpressureBean.setUserId((String)SPUtils.get(getActivity(),"userId",""));bloodpressureBean.setTime(listString.get(i));bloodpressureBean.setHbp("0");bloodpressureBean.setLbp("0");lists.add(bloodpressureBean);}}initChartView(lists);adapter=newBloodPressureAdapter(getActivity(),R.layout.list_item_bloodpressure,lists);recyclerView.setAdapter(adapter);}publicstaticList<Date>dateToWeek(Datemdate,intprogress){Datefdate;List<Date>list=newArrayList<Date>();LongfTime=mdate.getTime();for(inta=1;a<=progress;a++){fdate=newDate();fdate.setTime(fTime+(a*24*3600000));list.add(a-1,fdate);}returnlist;}4.5過(guò)往服藥數(shù)據(jù)讀取的實(shí)現(xiàn)用戶(hù)在服藥歷史記錄頁(yè)面可以看到過(guò)往服藥數(shù)據(jù)。在該activity開(kāi)始渲染時(shí)調(diào)用getData函數(shù)。從數(shù)據(jù)庫(kù)中查找與當(dāng)前userId相同且已經(jīng)觸發(fā)過(guò)的所有服藥計(jì)劃。將他們放入alarmbean中存進(jìn)lists。當(dāng)所有數(shù)據(jù)被處理完成后使用adapter對(duì)每一條進(jìn)行渲染,再將其放入activity_history.xml中的RecyclerView中顯示。核心代碼:privatevoidgetData(){StringuserId=(String)SPUtils.get(this,"userId","");db=databaseHelper.getReadableDatabase();Cursorcursor=db.rawQuery("select*fromalarmwhereuserId=?",newString[]{userId});while(cursor.moveToNext()){AlarmBeanalarmBean=newAlarmBean();intid=cursor.getInt(cursor.getColumnIndex("id"));Stringuser
溫馨提示
- 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~2026學(xué)年山東省濟(jì)南市天橋區(qū)七年級(jí)英語(yǔ)第一學(xué)期期末考試試題(含答案無(wú)聽(tīng)力原文及音頻)
- 五年級(jí)下冊(cè)語(yǔ)文期末試卷及答案
- 無(wú)領(lǐng)導(dǎo)小組題目及答案
- 初中數(shù)學(xué)知識(shí)樹(shù)說(shuō)課課件
- 2022~2023臨床執(zhí)業(yè)醫(yī)師考試題庫(kù)及答案第465期
- 微型小說(shuō)三題微型小說(shuō)《在》
- 2022~2023專(zhuān)升本考試題庫(kù)及答案第411期
- 二氧化碳?xì)怏w保護(hù)焊技術(shù)要點(diǎn)
- 臨猗事業(yè)編招聘2022年考試模擬試題及答案解析6
- 施工能力考試題及答案
- 打火機(jī)工廠制度規(guī)范
- 肺含鐵血黃素沉著癥診療指南(2025年版)
- 湖口縣2026年第一批單位公開(kāi)選調(diào)事業(yè)編制工作人員【32人】參考題庫(kù)附答案
- 統(tǒng)計(jì)分析培訓(xùn)課件
- 2025至2030中國(guó)乳鐵蛋白行業(yè)調(diào)研及市場(chǎng)前景預(yù)測(cè)評(píng)估報(bào)告
- 2026年人教版七年級(jí)英語(yǔ)上冊(cè)期末真題試卷含答案
- 高速公路bt合同范本
- 2026年《必背60題》酒店前廳接待經(jīng)理高頻面試題包含詳細(xì)解答
- 超聲波技術(shù)協(xié)議書(shū)
- 眼內(nèi)炎術(shù)后護(hù)理與康復(fù)
- GB/T 5784-2025緊固件六角頭螺栓細(xì)桿B級(jí)
評(píng)論
0/150
提交評(píng)論