【正文】
the behavior of the application is modeled as a finitestate machine while the graphical user interface is modeled by using classes and set of translation rules is defined to obtain a platformdependent representation and then the actual methodology has been validated by creating an application for both the Android and Windows Phone platform and by paring the obtained code to the corresponding versions written in the traditional way.Keywords:UML,PIM,PSM,Statechart,Android,Windows PhoneI. INTRODUCTIONTechnological revolution specifically in telemunication has created a large market for mobile phones and everyday hundreds of different applications are developed for smartphones due to their diverse smartphone is built on a mobile puting platform,with more advanced puting capability and connectivity than a feature phone[1].Development of smartphone applications is the process by which software is developed for resourceconstrained devices and it is executed over a specific operating system like Android,Windows Mobile,iPhone iOS,and Nokia ,each platform use。目前應(yīng)用雖然已經(jīng)實現(xiàn)核心功能,即接收藍牙信號并實現(xiàn)實時繪圖,在終端成功運行,但數(shù)據(jù)分析功能和咨詢功能尚不完善,分析功能需要編寫較為高效的數(shù)據(jù)歸納算法對其本地數(shù)據(jù)進行一定的處理統(tǒng)計,咨詢功能則在分析的基礎(chǔ)上針對不同的數(shù)據(jù)特征作出相應(yīng)的建議;此處,網(wǎng)絡(luò)連接功能仍需進一步開發(fā),以完善數(shù)據(jù)的對比,使應(yīng)用給出的建議更有說服力。設(shè)計中期,主要的工作是完善繪圖功能,使其在繪圖的同時,能夠進行工作,比如存儲數(shù)據(jù)到文件中,又或是根據(jù)波形來計算出一些重要的數(shù)據(jù),這個過程持續(xù)了很長時間,期間遇到的問題文中也有提及,而問題的來源則是對硬件的不熟悉,導(dǎo)致無法掌控傳感器的工作,對應(yīng)到設(shè)計中,即無法對藍牙開發(fā)板進行準(zhǔn)確的有目的性的開發(fā),燒寫的程序的復(fù)雜使得應(yīng)用接收到的信號往往出現(xiàn)波形失真甚至沒有波形的情況,這導(dǎo)致設(shè)計一度沒有進展,好在后來有所發(fā)現(xiàn),糾正了錯誤,使得數(shù)據(jù)的傳輸變得有保障。此外,“便攜式”指明了此應(yīng)用必須通過無線手段進行信號傳輸,于是設(shè)計任務(wù)整體來說,就是開發(fā)一個可以與指定設(shè)備進行無線通信的Android應(yīng)用,這個應(yīng)用既要有普通Android應(yīng)用那樣的外表,又要有充當(dāng)醫(yī)療設(shè)備的覺悟。目前的解決方案是盡量使用可以求得的參數(shù),比如波形的幅度和頻率,使用已經(jīng)可得的數(shù)據(jù)進行最大化的數(shù)據(jù)挖掘,由此分析得出結(jié)論。3. 對比分析波形問題波形的分析涉及到一系列數(shù)學(xué)問題,首先是對波形的除噪去噪,然后是對波形進行小波變換或傳統(tǒng)傅立葉變換,得到頻域的頻譜,接著利用相應(yīng)的數(shù)學(xué)工具對頻譜進行解析,得到一定的結(jié)論。 (false)。 (true)。 }}// 判斷是否為管理員用戶,是則開放功能public void isAdmin() { String user = (user, null)。 User user = new User(admin, ******)。(false)。(無)。 (false)。 (true)。 if (user != null) { (user)。,方法可見上文注冊模塊,在每次進行注冊用戶判斷的時候,都會使用query()方法得到一個已經(jīng)注冊的用戶列表,然后將當(dāng)前的用戶進行遍歷判斷,即如果列表中contains()該用戶,就不再允許注冊,或是可直接登錄;登錄后會用一個xml文件,使用SharedPreference來保存當(dāng)前登錄的用戶名,并將用戶名顯示到主界面的文本上;(user, username)。其他還有一些管理或優(yōu)化線程的方法,原理都類似,需要注意的是Android的線程更新和Java下并不盡然相同,Android下只有主線程即UI線程才能被更新,因此關(guān)于Handler的方法調(diào)用都應(yīng)該放在更新視圖的方法中,即onCreate()或onCreateView()方法中,具體方法可見工程代碼或見附錄。 (message)。 if (msgFlag) = 1。 }。 } (msg)。 break。}方法二:Timer+TimerTask+HandlerTimer timer = new Timer()。 }}。 } ()。Runnable run=new Runnable() { Override public void run() { try { initLine(lineMaibo)。1. 繪圖時的線程運作由于要實現(xiàn)實時傳輸效果,傳輸數(shù)據(jù)頻率和Android端更新數(shù)據(jù)頻率須保持一致,也就讓線程壓力較大,所以在傳輸數(shù)據(jù)的基礎(chǔ)上對線程進行一定的控制和優(yōu)化才能讓程序穩(wěn)定運行,否則程序就會經(jīng)常崩潰,后果輕則應(yīng)用中斷退出,重則占用設(shè)備內(nèi)存甚至引起內(nèi)存泄漏。2. 數(shù)據(jù)抽樣率過高引起的波形不穩(wěn)定通過藍牙開發(fā)板可設(shè)置藍牙傳輸數(shù)據(jù)的頻率,即數(shù)據(jù)抽樣率,一般為100Hz,但由于每次更新圖表時,需要更新整個圖表視圖以保留之前的數(shù)據(jù),數(shù)據(jù)量相對較大,這也就造成了繪圖頻率過高時,整個圖表會有閃爍感甚至線程直接崩潰。 左圖中數(shù)據(jù)看似有規(guī)律性但是波形矮小,一般是因為沒有實際接觸上硬件;而右圖中波形起伏不規(guī)律,一般是由于突然接觸傳感器,使得傳感器自身沒有調(diào)整數(shù)據(jù),藍牙發(fā)送出的數(shù)據(jù)也因此不規(guī)律。}上述代碼初始化了ListView組件,并將從數(shù)據(jù)庫中查詢而得的用戶信息填入列表以顯示出來,此處為了體現(xiàn)查詢效果,將用戶名與密碼一起查詢,用戶可以看到當(dāng)前所有已經(jīng)注冊的用戶名與密碼。 } SimpleAdapter adapter = new SimpleAdapter(this, userItems, , new String[] { username, password }, new int[] { , })。 (password, ())。 MapString, String userItem = new HashMapString, String()。 i ()。 ListMapString, String userItems = new ArrayListMapString, String()。設(shè)置模塊主要是布局文件的編寫,將視圖層層嵌套,以達到界面美觀舒適的效果,如下為查詢用戶的布局代碼[14];RelativeLayoutandroid:id=+id/queryUserandroid:layout_width=match_parentandroid:layout_height=wrap_content TextViewandroid:layout_width=wrap_contentandroid:layout_height=wrap_contentandroid:text=查詢用戶android:layout_marginLeft=10dpandroid:padding=4spandroid:textSize=20sp //RelativeLayout在相應(yīng)的設(shè)置界面下,有此文本的監(jiān)聽器,以響應(yīng)點擊事件。此模塊已有功能,可由下列流程圖進行說明,;否是開始注冊符合要求?存入數(shù)據(jù)庫登錄功能開放部分功能未開放結(jié)束已注冊?是否設(shè)置模塊主要用于設(shè)置一些常規(guī)的配置,分為普通用戶和管理員進行設(shè)置權(quán)限分配,管理員可以使用“用戶管理”中的全部功能,即“增加用戶”“刪除用戶”以及“查詢用戶”,普通用戶則只能使用“查詢用戶”功能,這是為了防止普通用戶無意將修改其他用戶資料而造成的數(shù)據(jù)泄漏。 (false)。 ()。 (username)。 if ((user)) { (true)。 } } } Override public void onLog(String username, String password) { ListUser users = ()。 } else { User user = new User(username, password)。 } } if (existFlag) { (getApplicationContext(), 用戶名已存在, ).show()。 for (User u : users) { if (().equals(username)) { existFlag = true。對填寫文本的處理方法則放在了主界面代碼下,這是因為要判斷用戶是否注冊,部分代碼如下;Override public void onReg(String username, String password) { ListUser users = ()。 } }).setNegativeButton(取消, null)。 } }).setNeutralButton(注冊, new OnClickListener() { Override public void onClick(DialogInterface dialog, int which) { RegClickListener regListener = (RegClickListener) getActivity()。 (view).setPositiveButton(登錄, new OnClickListener() { Override public void onClick(DialogInterface dialog, int which) { RegClickListener logListener = (RegClickListener) getActivity()。對話框與Sqlite輕量數(shù)據(jù)庫連接,會將注冊的用戶名和密碼封裝為一個對象”user”,凡是存取用戶皆由數(shù)據(jù)庫接管,部分代碼如下;dialog_edit_username = (EditText) view .findViewById()。 (false)。未注冊用戶只能使用測試功能,注冊用戶開放咨詢與部分設(shè)置功能,管理員則擁有完整的權(quán)限。其開發(fā)界面如下圖。否是否返回連接藍牙接收到數(shù)據(jù)?存入文件轉(zhuǎn)換數(shù)據(jù)讀寫標(biāo)志?監(jiān)測數(shù)據(jù)波形圖脈搏穩(wěn)定?計算BPM開始是是否 接收后續(xù)流程圖界面布局主要由xml配置文件管理,一般來說,應(yīng)用中有多少個活動界面,就需要多少布局文件,因為本設(shè)計中并不要求有酷炫的界面效果,所有布局相對來說比較簡單。 }}其他還有initChart(),initRenderer(),setChartSettings()等方法,都是為了設(shè)置圖表的固有屬性存在的,讀者可以自行在附錄或附帶的資源中查看源碼。 i count。 (xTemp, yTemp)。 y[i] = (i)。 i count。 if (count 100) { count = 100。 (chartListSize 2) 0) { pluseSure()。 // 如果心率曲線上揚則調(diào)用心率判斷方法 if (chartListSize 2) if (yTemp 0 amp。 xTemp = 0。}在refreshChart()中調(diào)用initLine()方法,即繪圖方法體,()方法添加橫縱坐標(biāo),代碼如下:private static void initLine(XYSeries series) { // 當(dāng)集合dataList中的值超過一定額度時,清空 int chartListSize = ()。 }可以看到,pluseHandler在每一次滿足條件時運行refreshChart(),即刷新視圖:private static void refreshChart() { initLine(lineMaibo)。 // 響應(yīng)線程 (new Runnable() {