ÿþ<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"> <head> <meta http-equiv=Content-Type content="text/html; charset=unicode"> <meta name=ProgId content=Word.Document> <meta name=Generator content="Microsoft Word 15"> <meta name=Originator content="Microsoft Word 15"> <link rel=File-List href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/filelist.xml"> <link rel=Edit-Time-Data href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/editdata.mso"> <!--[if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--> <title>MyRuns Project Document  The MyRuns Project</title> <!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Author>Xing-Dong Yang</o:Author> <o:Template>Normal</o:Template> <o:LastAuthor>Xing-Dong Yang</o:LastAuthor> <o:Revision>38</o:Revision> <o:TotalTime>62</o:TotalTime> <o:Created>2016-05-13T23:24:00Z</o:Created> <o:LastSaved>2017-01-10T17:32:00Z</o:LastSaved> <o:Pages>1</o:Pages> <o:Words>8181</o:Words> <o:Characters>46633</o:Characters> <o:Lines>388</o:Lines> <o:Paragraphs>109</o:Paragraphs> <o:CharactersWithSpaces>54705</o:CharactersWithSpaces> <o:Version>15.00</o:Version> </o:DocumentProperties> <o:OfficeDocumentSettings> <o:AllowPNG/> </o:OfficeDocumentSettings> </xml><![endif]--> <link rel=themeData href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/themedata.thmx"> <link rel=colorSchemeMapping href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/colorschememapping.xml"> <!--[if gte mso 9]><xml> <w:WordDocument> <w:SpellingState>Clean</w:SpellingState> <w:GrammarState>Clean</w:GrammarState> <w:TrackMoves>false</w:TrackMoves> <w:TrackFormatting/> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF/> <w:LidThemeOther>EN-CA</w:LidThemeOther> <w:LidThemeAsian>X-NONE</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:BreakWrappedTables/> <w:SplitPgBreakAndParaMark/> </w:Compatibility> <w:DocumentVariables> <w:__Grammarly_42____i>H4sIAAAAAAAEAKtWckksSQxILCpxzi/NK1GyMqwFAAEhoTITAAAA</w:__Grammarly_42____i> <w:__Grammarly_42___1>H4sIAAAAAAAEAKtWcslP9kxRslIyNDY0sjA1MTIzszA3MjWyNDBR0lEKTi0uzszPAykwqgUAnkMp1ywAAAA=</w:__Grammarly_42___1> </w:DocumentVariables> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> <m:mathPr> <m:mathFont m:val="Cambria Math"/> <m:brkBin m:val="before"/> <m:brkBinSub m:val="&#45;-"/> <m:smallFrac m:val="off"/> <m:dispDef/> <m:lMargin m:val="0"/> <m:rMargin m:val="0"/> <m:defJc m:val="centerGroup"/> <m:wrapIndent m:val="1440"/> <m:intLim m:val="subSup"/> <m:naryLim m:val="undOvr"/> </m:mathPr></w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false" DefSemiHidden="false" DefQFormat="false" DefPriority="99" LatentStyleCount="371"> <w:LsdException Locked="false" Priority="0" QFormat="true" Name="Normal"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 1"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 4"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 5"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 6"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 7"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 8"/> <w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 9"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 6"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 7"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 8"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 9"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 1"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 2"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 3"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 4"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 5"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 6"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 7"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 8"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 9"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Normal Indent"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footnote text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="header"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footer"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index heading"/> <w:LsdException Locked="false" Priority="35" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="caption"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="table of figures"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="envelope address"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="envelope return"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footnote reference"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation reference"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="line number"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="page number"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="endnote reference"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="endnote text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="table of authorities"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="macro"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="toa heading"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 5"/> <w:LsdException Locked="false" Priority="10" QFormat="true" Name="Title"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Closing"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Signature"/> <w:LsdException Locked="false" Priority="1" SemiHidden="true" UnhideWhenUsed="true" Name="Default Paragraph Font"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Message Header"/> <w:LsdException Locked="false" Priority="11" QFormat="true" Name="Subtitle"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Salutation"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Date"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text First Indent"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text First Indent 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Note Heading"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Block Text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Hyperlink"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="FollowedHyperlink"/> <w:LsdException Locked="false" Priority="22" QFormat="true" Name="Strong"/> <w:LsdException Locked="false" Priority="20" QFormat="true" Name="Emphasis"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Document Map"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Plain Text"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="E-mail Signature"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Top of Form"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Bottom of Form"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Normal (Web)"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Acronym"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Address"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Cite"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Code"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Definition"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Keyboard"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Preformatted"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Sample"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Typewriter"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Variable"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Normal Table"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation subject"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="No List"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 6"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 7"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 8"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 4"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 5"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 6"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 7"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 8"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Contemporary"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Elegant"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Professional"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Subtle 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Subtle 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Web 1"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Web 2"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Web 3"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Balloon Text"/> <w:LsdException Locked="false" Priority="39" Name="Table Grid"/> <w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Theme"/> <w:LsdException Locked="false" SemiHidden="true" Name="Placeholder Text"/> <w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading"/> <w:LsdException Locked="false" Priority="61" Name="Light List"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/> <w:LsdException Locked="false" Priority="70" Name="Dark List"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/> <w:LsdException Locked="false" SemiHidden="true" Name="Revision"/> <w:LsdException Locked="false" Priority="34" QFormat="true" Name="List Paragraph"/> <w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/> <w:LsdException Locked="false" Priority="30" QFormat="true" Name="Intense Quote"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/> <w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/> <w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/> <w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/> <w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/> <w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/> <w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/> <w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/> <w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/> <w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/> <w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/> <w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/> <w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/> <w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/> <w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/> <w:LsdException Locked="false" Priority="19" QFormat="true" Name="Subtle Emphasis"/> <w:LsdException Locked="false" Priority="21" QFormat="true" Name="Intense Emphasis"/> <w:LsdException Locked="false" Priority="31" QFormat="true" Name="Subtle Reference"/> <w:LsdException Locked="false" Priority="32" QFormat="true" Name="Intense Reference"/> <w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/> <w:LsdException Locked="false" Priority="37" SemiHidden="true" UnhideWhenUsed="true" Name="Bibliography"/> <w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/> <w:LsdException Locked="false" Priority="41" Name="Plain Table 1"/> <w:LsdException Locked="false" Priority="42" Name="Plain Table 2"/> <w:LsdException Locked="false" Priority="43" Name="Plain Table 3"/> <w:LsdException Locked="false" Priority="44" Name="Plain Table 4"/> <w:LsdException Locked="false" Priority="45" Name="Plain Table 5"/> <w:LsdException Locked="false" Priority="40" Name="Grid Table Light"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 1"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 1"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 1"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 1"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 1"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 1"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 1"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 2"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 2"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 2"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 2"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 2"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 2"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 2"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 3"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 3"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 3"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 3"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 3"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 3"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 3"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 4"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 4"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 4"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 4"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 4"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 4"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 4"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 5"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 5"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 5"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 5"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 5"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 5"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 5"/> <w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 6"/> <w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 6"/> <w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 6"/> <w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 6"/> <w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 6"/> <w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 6"/> <w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 6"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 1"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 1"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 1"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 1"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 1"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 1"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 1"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 2"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 2"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 2"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 2"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 2"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 2"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 2"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 3"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 3"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 3"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 3"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 3"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 3"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 3"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 4"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 4"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 4"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 4"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 4"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 4"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 4"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 5"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 5"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 5"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 5"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 5"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 5"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 5"/> <w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 6"/> <w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 6"/> <w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 6"/> <w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 6"/> <w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 6"/> <w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 6"/> <w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 6"/> </w:LatentStyles> </xml><![endif]--> <link rel=Stylesheet type="text/css" media=all href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/db-simple.css"> <style> <!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Consolas; panose-1:2 11 6 9 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-520092929 1073806591 9 0 415 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman",serif; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast;} h1 {mso-style-priority:9; mso-style-unhide:no; mso-style-qformat:yes; mso-style-link:"Heading 1 Char"; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; mso-outline-level:1; font-size:18.0pt; font-family:"Times New Roman",serif; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; font-weight:bold;} h2 {mso-style-priority:9; mso-style-unhide:no; mso-style-qformat:yes; mso-style-link:"Heading 2 Char"; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; mso-outline-level:2; font-size:13.0pt; font-family:"Times New Roman",serif; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; font-weight:bold;} h3 {mso-style-priority:9; mso-style-unhide:no; mso-style-qformat:yes; mso-style-link:"Heading 3 Char"; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; mso-outline-level:3; font-size:13.5pt; font-family:"Times New Roman",serif; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; font-weight:bold;} a:link, span.MsoHyperlink {mso-style-noshow:yes; mso-style-priority:99; color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {mso-style-noshow:yes; mso-style-priority:99; color:purple; text-decoration:underline; text-underline:single;} p {mso-style-noshow:yes; mso-style-priority:99; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman",serif; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast;} code {mso-style-noshow:yes; mso-style-priority:99; font-family:"Courier New"; mso-ascii-font-family:"Courier New"; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:"Courier New"; mso-bidi-font-family:"Courier New";} pre {mso-style-noshow:yes; mso-style-priority:99; mso-style-link:"HTML Preformatted Char"; margin:0cm; margin-bottom:.0001pt; mso-pagination:widow-orphan; tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt; background:#EEEEEE; font-size:10.0pt; font-family:"Courier New"; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast;} span.Heading1Char {mso-style-name:"Heading 1 Char"; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"Heading 1"; mso-ansi-font-size:16.0pt; mso-bidi-font-size:16.0pt; font-family:"Calibri Light",sans-serif; mso-ascii-font-family:"Calibri Light"; mso-ascii-theme-font:major-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:major-fareast; mso-hansi-font-family:"Calibri Light"; mso-hansi-theme-font:major-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:major-bidi; color:#2E74B5; mso-themecolor:accent1; mso-themeshade:191;} span.Heading2Char {mso-style-name:"Heading 2 Char"; mso-style-noshow:yes; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"Heading 2"; mso-ansi-font-size:13.0pt; mso-bidi-font-size:13.0pt; font-family:"Calibri Light",sans-serif; mso-ascii-font-family:"Calibri Light"; mso-ascii-theme-font:major-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:major-fareast; mso-hansi-font-family:"Calibri Light"; mso-hansi-theme-font:major-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:major-bidi; color:#2E74B5; mso-themecolor:accent1; mso-themeshade:191;} span.Heading3Char {mso-style-name:"Heading 3 Char"; mso-style-noshow:yes; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"Heading 3"; mso-ansi-font-size:12.0pt; mso-bidi-font-size:12.0pt; font-family:"Calibri Light",sans-serif; mso-ascii-font-family:"Calibri Light"; mso-ascii-theme-font:major-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:major-fareast; mso-hansi-font-family:"Calibri Light"; mso-hansi-theme-font:major-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:major-bidi; color:#1F4D78; mso-themecolor:accent1; mso-themeshade:127;} span.HTMLPreformattedChar {mso-style-name:"HTML Preformatted Char"; mso-style-noshow:yes; mso-style-priority:99; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"HTML Preformatted"; font-family:Consolas; mso-ascii-font-family:Consolas; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Consolas; mso-bidi-font-family:Consolas;} p.clearer, li.clearer, div.clearer {mso-style-name:clearer; mso-style-noshow:yes; mso-style-priority:99; mso-style-unhide:no; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman",serif; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast;} p.rightimage, li.rightimage, div.rightimage {mso-style-name:right_image; mso-style-noshow:yes; mso-style-priority:99; mso-style-unhide:no; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:11.25pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman",serif; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast;} p.leftimage, li.leftimage, div.leftimage {mso-style-name:left_image; mso-style-noshow:yes; mso-style-priority:99; mso-style-unhide:no; mso-margin-top-alt:auto; margin-right:11.25pt; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman",serif; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast;} span.SpellE {mso-style-name:""; mso-spl-e:yes;} span.GramE {mso-style-name:""; mso-gram-e:yes;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-size:10.0pt; mso-ansi-font-size:10.0pt; mso-bidi-font-size:10.0pt;} @page WordSection1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:35.4pt; mso-footer-margin:35.4pt; mso-paper-source:0;} div.WordSection1 {page:WordSection1;} /* List Definitions */ @list l0 {mso-list-id:181668785; mso-list-template-ids:-2087042724;} @list l0:level1 {mso-level-number-format:bullet; mso-level-text:·ð; mso-level-tab-stop:36.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l0:level2 {mso-level-number-format:bullet; mso-level-text:o; mso-level-tab-stop:72.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:"Courier New"; mso-bidi-font-family:"Times New Roman";} @list l0:level3 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:108.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l0:level4 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:144.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l0:level5 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:180.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l0:level6 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:216.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l0:level7 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:252.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l0:level8 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:288.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l0:level9 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:324.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l1 {mso-list-id:1034379090; mso-list-template-ids:597065882;} @list l1:level1 {mso-level-number-format:bullet; mso-level-text:·ð; mso-level-tab-stop:36.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l1:level2 {mso-level-number-format:bullet; mso-level-text:o; mso-level-tab-stop:72.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:"Courier New"; mso-bidi-font-family:"Times New Roman";} @list l1:level3 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:108.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l1:level4 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:144.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l1:level5 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:180.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l1:level6 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:216.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l1:level7 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:252.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l1:level8 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:288.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l1:level9 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:324.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l2 {mso-list-id:1225021397; mso-list-template-ids:2086282194;} @list l2:level1 {mso-level-number-format:bullet; mso-level-text:·ð; mso-level-tab-stop:36.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l2:level2 {mso-level-number-format:bullet; mso-level-text:o; mso-level-tab-stop:72.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:"Courier New"; mso-bidi-font-family:"Times New Roman";} @list l2:level3 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:108.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l2:level4 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:144.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l2:level5 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:180.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l2:level6 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:216.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l2:level7 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:252.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l2:level8 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:288.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l2:level9 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:324.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l3 {mso-list-id:1970280126; mso-list-template-ids:2021680658;} @list l3:level1 {mso-level-number-format:bullet; mso-level-text:·ð; mso-level-tab-stop:36.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l3:level2 {mso-level-number-format:bullet; mso-level-text:o; mso-level-tab-stop:72.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:"Courier New"; mso-bidi-font-family:"Times New Roman";} @list l3:level3 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:108.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l3:level4 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:144.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l3:level5 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:180.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l3:level6 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:216.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l3:level7 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:252.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l3:level8 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:288.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l3:level9 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:324.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l4 {mso-list-id:1982614121; mso-list-template-ids:-691133368;} @list l4:level1 {mso-level-number-format:bullet; mso-level-text:·ð; mso-level-tab-stop:36.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Symbol;} @list l4:level2 {mso-level-number-format:bullet; mso-level-text:o; mso-level-tab-stop:72.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:"Courier New"; mso-bidi-font-family:"Times New Roman";} @list l4:level3 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:108.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l4:level4 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:144.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l4:level5 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:180.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l4:level6 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:216.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l4:level7 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:252.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l4:level8 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:288.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} @list l4:level9 {mso-level-number-format:bullet; mso-level-text:§ð; mso-level-tab-stop:324.0pt; mso-level-number-position:left; text-indent:-18.0pt; mso-ansi-font-size:10.0pt; font-family:Wingdings;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} --> </style> <!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman",serif;} </style> <![endif]--> <meta http-equiv=Content-Style-Type content="text/css"> <!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="1026"/> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1"/> </o:shapelayout></xml><![endif]--> </head> <body bgcolor=white lang=EN-CA link=blue vlink=purple style='tab-interval:36.0pt'> <div class=WordSection1> <p class=MsoNormal><b><span style='font-size:16.5pt;font-family:"Arial",sans-serif; mso-fareast-font-family:"Times New Roman";color:black'>Dartmouth CS 65/165</span></b><span style='font-size:16.5pt;font-family:"Arial",sans-serif;mso-fareast-font-family: "Times New Roman";color:black'><o:p></o:p></span></p> <div id=container> <div id=sitesubtitle> <p class=MsoNormal><b><span style='font-size:10.5pt;font-family:"Arial",sans-serif; mso-fareast-font-family:"Times New Roman"'>Smartphone Programming</span></b><span style='font-size:10.5pt;font-family:"Arial",sans-serif;mso-fareast-font-family: "Times New Roman"'><o:p></o:p></span></p> </div> <div id=siterightheader> <p class=MsoNormal align=right style='text-align:right'><b style='mso-bidi-font-weight: normal'><span style='font-size:10.5pt;font-family:"Arial",sans-serif; mso-fareast-font-family:"Times New Roman"'>Professor Xing-Dong Yang <o:p></o:p></span></b></p> <p class=MsoNormal align=right style='text-align:right'><b style='mso-bidi-font-weight: normal'><span style='font-size:10.5pt;font-family:"Arial",sans-serif; mso-fareast-font-family:"Times New Roman"'>Course materials developed by Professor Andrew T. Campbell<o:p></o:p></span></b></p> </div> </div> <div class=MsoNormal align=center style='text-align:center'><!-- --><span style='font-family:"Arial",sans-serif;mso-fareast-font-family:"Times New Roman"'> <hr size=8 width="100%" align=center> </span></div> <div id=header> <h1><span style='mso-fareast-font-family:"Times New Roman"'>The <span class=SpellE>MyRuns</span> Project<o:p></o:p></span></h1> </div> <h2 id=created-033014><span style='mso-fareast-font-family:"Times New Roman"'>Created 03/30/14<o:p></o:p></span></h2> <h2 id=updated-040314-added-the-icons-for-the-project.><span style='mso-fareast-font-family: "Times New Roman"'>Updated 04/03/14 <span class=GramE>Added</span> the icons for the project.<o:p></o:p></span></h2> <h2 id=updated-042014-added-database-implementation---implement-database-operations---hints><span style='mso-fareast-font-family:"Times New Roman"'>Updated 04/20/14 Added Database Implementation -&gt; Implement Database Operations -&gt; Hints<o:p></o:p></span></h2> <h2 id=updated-022016-add-apks-to-include-the-new-crop-and-camera-code.><span style='mso-fareast-font-family:"Times New Roman"'>Updated 02/20/16 Add APKs to include the new crop and camera code.<o:p></o:p></span></h2> <h2 id=updated-022016-updated-the-appbackend-diagram-to-refelect-gcm-apis.><span style='mso-fareast-font-family:"Times New Roman"'>Updated 02/20/16 Updated the app/backend diagram to <span class=SpellE>refelect</span> GCM APIs.<o:p></o:p></span></h2> <h1 id="chap:overview"><span style='mso-fareast-font-family:"Times New Roman"'>Overview<o:p></o:p></span></h1> <h2 id=the-big-picture><span style='mso-fareast-font-family:"Times New Roman"'>The Big Picture<o:p></o:p></span></h2> <p>The <span class=SpellE>MyRuns</span> app that you will build over the next 6 weeks as a set of thematic programming assignments is a simple fitness app for Android. It allows you to capture your runs and walks and view the stats on Google Maps. It uses sensors (viz. GPS, accelerometers) in the phone to infer your activity (e.g., running) in an automatic manner. We start by building out the UI then add GPS, Google maps, the inference model and database components. The app comprises a client that runs on the phone and a backend cloud component using Google App Engine. So you get <span class=SpellE>first hand</span> knowledge on implementing a native app on the phone and a cloud component. That's very cool.</p> <p>This is a fun and challenging set of assignments that <span class=SpellE>let's</span> you get experience with many of the common programming challenges when building an Android app. You can use this experience as a foundation for creating and programming your own ideas as part of the group project at the end of the class. We will also publish the apps from the project phase of the class on Google Play. We will therefore experience design, programming, testing and publishing an app -- the complete lifecycle.</p> <p>What is the idea of this document? It presents a lot of details on the <span class=SpellE>MyRuns</span> app. Think of it as a high-level specification and some pointers on design. BTW, you are free to design your app as you like or follow the guidelines layout here.<o:p></o:p></p> <h2 id=the-small-picture><span style='mso-fareast-font-family:"Times New Roman"'>The Small Picture<o:p></o:p></span></h2> <p>The class assignments break down into 6 thematic labs that allow you to incrementally and systematically build a complex app. While this document does not attempt to answer all the questions -- and in places it gives quite a lot of detail and is vague in other parts -- you can download the following APKs for each lab assignment to your phone and play with it. By doing this you will best understand what the app is doing. Your job is to replicate the UI (or modify it) and functionality. The labs area as follows:</p> <ul type=disc> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l1 level1 lfo1;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Lab 1 -- The User Profile -- Demo <a href="../APKs/MyRuns-Android-chk1.apk">MyRuns-Android-chk1.apk</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l1 level1 lfo1;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Lab 2 -- The User Interface (UI) -- Demo <a href="../APKs/MyRuns-Android-chk2.apk">MyRuns-Android-chk2.apk</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l1 level1 lfo1;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Lab 3 -- The Database -- Demo <a href="../APKs/MyRuns-Android-chk3.apk">MyRuns-Android-chk3.apk</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l1 level1 lfo1;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Lab 4 -- Google Maps -- Demo <a href="../APKs/MyRuns-Android-chk4.apk">MyRuns-Android-chk4.apk</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l1 level1 lfo1;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Lab 5 -- Activity Recognition -- Demo <a href="../APKs/MyRuns-Android-chk5.apk">MyRuns-Android-chk5.apk</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l1 level1 lfo1;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Lab 6 -- App Engine -- </span><a href="https://youtu.be/23rf0ZW2rDQ">demo video</a><span style='mso-fareast-font-family: "Times New Roman"'><o:p></o:p></span></li> </ul> <p>Note, as part of the development of the app you will need a set of <a href="http://www.cs.dartmouth.edu/~campbell/cs65/myruns/myruns_icons.zip">icons.</a> You can see where to use them by demoing the <span class=SpellE>apks</span> (above). Feel free to use your own icons if you wish.<o:p></o:p></p> <h2 id=this-document><span style='mso-fareast-font-family:"Times New Roman"'>This Document<o:p></o:p></span></h2> <p>There is a lot of information in this document -- do not panic.</p> <p>The document contains information for the complete <span class=SpellE>MyRuns</span> app. Again, do not feel overwhelmed by all the details. What you should do is read the complete document and then focus on what needs to be design and programmed for each lab. You start with lab 1 and finish with lab 6. So this week focus on lab 1 not the others labs. The reason we give out the complete design is so you can keep the complete project in mind as you develop each lab each week. The idea is that you can reuse common components as you move through the piecemeal programming of each successive lab.</p> <p>Once more: this document contains a lot of material, but we need to know what the app does in the first place to help you digest it while keeping the big picture in mind. Each lab includes an example APK for you to download and run on your phone. This gives you a good idea of what is expect at the UI level and in terms of the new features each lab adds to the cumulative app.</p> <p>In summary, read the spec. Each week read the lab description (which is more pointers into the document than a detailed lab description) and run the APK. Then start designing and programming the lab. Once you are done testing your code works you should submit the lab on the Canvas.</p> <p>Tip: once you have read the complete document then read it again.<o:p></o:p></p> <h2 id=sections><span style='mso-fareast-font-family:"Times New Roman"'>Sections<o:p></o:p></span></h2> <p>The document has the following sections:</p> <p><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:labs">Labs</a> section describes what you need to accomplish for each lab. There are <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:lablist">6 labs</a></p> <p><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:sub">Submission of labs</a> explains what to submit and how.</p> <p><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:sub">User Interface</a> section discusses the user interfaces and functionality.</p> <p><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:uiimpl">User Interface Implementation</a> section specifies how to implement the user interface.</p> <p><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:dbimpl">Database Implementation</a> section describes how to design and implement the database.</p> <p><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:serviceimpl">Service Implementation</a> discusses the design considerations for service implementation.<o:p></o:p></p> <h2 id="chap:lablist"><span style='mso-fareast-font-family:"Times New Roman"'>Lab Assignments<o:p></o:p></span></h2> <p>The following labs make up the <span class=SpellE>MyRuns</span> app -- we just list the labs here and discuss them in more detail <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:labs">later</a>.</p> <ul type=disc> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:labs:1">Lab 1</a>: Complete the profile activity. Save profile on the SD card and retrieve it later. You can download the <span class=SpellE>apk</span> from <a href="../APKs/MyRuns-Android-chk1.apk">here</a>.<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:labs:2">Lab 2</a>: Complete the user interface, including all the activities, main activity's Action Tabs. You should be able to navigate between all activities. You can download the <span class=SpellE>apk</span> from <a href="../APKs/MyRuns-Android-chk2.apk">here</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:labs:3">Lab 3</a>: Design and implement the database. You need to define database table schema as well as data entry object used in the App. Your database design should be able to store each exercise entry's basic information as well as GPS trace. You should implement the database CRUD (Create, read, update and delete) operations. You should be able to add new entries manually in that start tab, and see the list of all entries in the history tab. You should be able to click on one particular entry to view or delete its information. The history tab should be able to update the list according to your modifications. You can download the <span class=SpellE>apk</span> from <a href="../APKs/MyRuns-Android-chk3.apk">here</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:labs:4">Lab 4</a>: Design and implement the tracking service. Draw the real-time GPS trace on Google Maps using the continuous location updates. Save the traces in the database and visualize the GPS trace history on Google Maps. You should also be able to view the history trace from the history tab. You can download the <span class=SpellE>apk</span> from <a href="../APKs/MyRuns-Android-chk4.apk">here</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:labs:5">Lab 5</a>: Implement activity recognition. You should train an activity classifier by collecting accelerometer data, then use the classifier in your app. You can download the <span class=SpellE>apk</span> from <a href="../APKs/MyRuns-Android-chk5.apk">here</a><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l0 level1 lfo2;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'><a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:labs:6">Lab 6</a>: Synchronize exercise history to the real Google <span class=SpellE>AppEngine</span> hosted cloud using Google Cloud Messaging.<o:p></o:p></span></li> </ul> <h2 id="chap:sub"><span style='mso-fareast-font-family:"Times New Roman"'>Submission of programming assignments<o:p></o:p></span></h2> <h1><span style='font-size:12.0pt;mso-font-kerning:0pt;font-weight:normal'>Submit your work through Canvas. You need to put your files (Android Studio project, <span class=SpellE>AssignmentName.apk</span>, README.txt if needed) into a folder and name your folder <span class=SpellE>FirstName_LastName_AssignmentName</span> (e.g. Jun_Gong_MyRuns1). Finally you need to zip your folder and use the same name to name your zip file. Please leave a note on Canvas to specify the name of the other student if you do pair programming. Note that the same information should also show up in README.txt, which is usually used if you want to tell your graders that you are using your free 24 hour pass.<o:p></o:p></span></h1> <h1><span style='mso-fareast-font-family:"Times New Roman"'>User Interface<o:p></o:p></span></h1> <p>This section discusses the user interface (UI) and main functionality.<o:p></o:p></p> <h2 id="chap:ui:walk_through"><span style='mso-fareast-font-family:"Times New Roman"'>User Interface Walk-through<o:p></o:p></span></h2> <p>When you launch the app you are bought to the main interface as shown in the figures below. The main UI consists of three tabs (from left to right): <em>start, history and settings</em>. When the app starts, it focusses on the start tab. The app offers a number of modes to record workouts -- for example, manual input which is a bit tedious and the GPS mode as shown in the figures. You can view your workout history by tapping on the history tab. In the setting tab, you can set your personal information, e.g., name, email, etc. We are going to introduce each of these three tabs in the following section.</p> <p><span style='mso-no-proof:yes'><img border=0 width=381 height=680 id="_x0000_i1043" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/start_frag.png" alt="Start Fragment"></span><span style='mso-no-proof:yes'><img border=0 width=381 height=680 id="_x0000_i1042" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/history_frag.png" alt="History Fragment"></span><span style='mso-no-proof:yes'><img border=0 width=381 height=680 id="_x0000_i1041" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/settings_frag.png" alt="Settings Fragment"></span><o:p></o:p></p> <h2 id="chap:ui:start_tab"><span style='mso-fareast-font-family:"Times New Roman"'>Start Tab<o:p></o:p></span></h2> <p>You can record your work out in three ways: <em>manual input, GPS or automatic modes</em>. This section describes how each method works.<o:p></o:p></p> <h3 id=manual-entry-mode><span style='mso-fareast-font-family:"Times New Roman"'>Manual Entry Mode<o:p></o:p></span></h3> <p>Manual entry is activated when you select  Manual Entry for the  Input Type using the start tab. You can specify the type of activity in  Activity Type spinner. When you click  Start , you will be brought to the manual input interface, where you can input the details of your workout. The table below shows the information type (e.g., heart rate), the type of widget used for data entry (e.g., <span class=SpellE>TimePickerDialog</span>) and short note on how the data could be stored (e.g., Store the timestamp in long) for data associated with a workout that the use can manually enter.</p> <p><span style='mso-no-proof:yes'><img border=0 width=381 height=680 id="_x0000_i1040" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/manual_entry.png" alt="Manual Entry"></span><span style='mso-no-proof:yes'><img border=0 width=381 height=680 id="_x0000_i1039" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/manual_entry_dialog.png" alt="Manual Entry"></span></p> <p>The corresponding details of exercise are listed in the following table.</p> <div> <p class=MsoNormal><span style='mso-fareast-font-family:"Times New Roman"; mso-no-proof:yes'><img border=0 width=820 height=340 id="_x0000_i1038" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/workout_table.png"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <p>When the user clicks on any exercise/workout entry, the app should show a data entry dialog. When user taps save, the entry should be saved to the database. More on the database later.<o:p></o:p></p> <h3 id=gps-mode><span style='mso-fareast-font-family:"Times New Roman"'>GPS Mode<o:p></o:p></span></h3> <p>The GPS entry mode is when the user selects  GPS for the  Input Type on the start tab. You can specify the type of activity using the  Activity Type spinner. When you click (it's more tapping and not clicking on a smartphone but you get my drift)  Start , you will be brought to a map interface, where you can see your location trace and some information about your current activity. Also, a notification icon is shown in the notification area, indicating the app is tracking your location.</p> <div> <p class=MsoNormal><span style='mso-fareast-font-family:"Times New Roman"; mso-no-proof:yes'><img border=0 width=779 height=680 id="_x0000_i1037" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/map_view.jpg"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <h3 id=automatic-mode><span style='mso-fareast-font-family:"Times New Roman"'>Automatic Mode<o:p></o:p></span></h3> <p>The automatic entry mode is when the user selects  Automatic for the  Input Type using the start tab. It is similar to the  GPS mode except the activity type (i.e., walking, running) is automatically inferred using a classifier and features computed from the accelerometer data. The real time activity inference will be shown in the status area. The final activity type is determined as the activity label (e.g., walking) that has been inferred more times than other activity label over a defined period of time.<o:p></o:p></p> <h3 id=sync><span style='mso-fareast-font-family:"Times New Roman"'>Sync<o:p></o:p></span></h3> <p>When  Sync button is clicked, the workouts/exercise records should be send to remote server and stored in the cloud.<o:p></o:p></p> <h2 id="chap:ui:history_tab"><span style='mso-fareast-font-family:"Times New Roman"'>History Tab<o:p></o:p></span></h2> <p>The History tab shows the list of all recorded workout entries. Each entry consists two lines: <em>title and text</em>. The title includes the activity type and time of the activity while text captures distance and activity duration.</p> <p>When the user clicks on an entry, assuming the entry was input manually, then the app shows an interface containing the status, as shown in the screen shot below. Otherwise the app opens the map interface to show the trace. When user clicks  DELETE in the action bar, the entry should be removed from the history tab.</p> <div> <p class=MsoNormal><span style='mso-fareast-font-family:"Times New Roman"; mso-no-proof:yes'><img border=0 width=381 height=680 id="_x0000_i1036" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/history_manual_view.png"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <h2 id="chap:ui:settings_tab"><span style='mso-fareast-font-family:"Times New Roman"'>Settings Tab<o:p></o:p></span></h2> <p>As discussed in the <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:ui:walk_through">User Interface Walk-through</a> section, you can set up the user profile (open a new activity), privacy setting (check box), unit preference (pop-up dialog with radio boxes) and comment (pop-up dialog with text box) in the &quot;Settings Tab&quot;. All setting modifications should be saved automatically.</p> <p><span style='mso-no-proof:yes'><img border=0 width=409 height=680 id="_x0000_i1035" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/profile_activity.png" alt="Profile Activity"></span><span style='mso-no-proof:yes'><img border=0 width=409 height=680 id="_x0000_i1034" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/profile_camera.png" alt="Select Image Source"></span><span style='mso-no-proof:yes'><img border=0 width=409 height=680 id="_x0000_i1033" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/profile_crop.png" alt="Settings Fragment"></span></p> <p>When the user clicks the  User Profile a new view is presented, as shown in the screenshots above. The user should be able to input their photo, name, email, phone number, etc. When the user click the &quot;Change&quot; button, they can choose to take a picture using the camera or select one from the gallery (as shown in the middle figure). The interface should allow the user to take or get a picture and crop it, as shown in the picture on the right). The following table shows detailed definitions of the user profile.</p> <div> <p class=MsoNormal><span style='mso-fareast-font-family:"Times New Roman"; mso-no-proof:yes'><img border=0 width=898 height=340 id="_x0000_i1032" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/settings_table.png"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <h1 id="chap:design"><span style='mso-fareast-font-family:"Times New Roman"'>System Design Principles<o:p></o:p></span></h1> <p>This section provides an overview of <span class=SpellE>MyRuns</span>' system design principles. We use MVC as the architectural design pattern. Model view controller (MVC) is one of many software design patterns, which has been widely adopted to develop software architecture for user interfaces. The design consideration of MVC is to separate business logic from user interfaces. In what follows, the design of profile management and tracking are illustrated.<o:p></o:p></p> <h2 id=profile-management><span style='mso-fareast-font-family:"Times New Roman"'>Profile Management<o:p></o:p></span></h2> <p>The design of the profile management is shown in the diagram below. As you can see from the previous section, the user can input, view, and change their profiles. The user profile contains items such as name, gender, photo, phone, gender, and class. <span class=SpellE>Therefore<span class=GramE>,we</span></span> can define a class to represent this data structure. This profile class also handles where to save the profile data and how to retrieve the profile data, which is transparent to other module. The profile definition is the <strong>model</strong> component in MVC.</p> <div> <p class=MsoNormal><span style='mso-fareast-font-family:"Times New Roman"; mso-no-proof:yes'><img border=0 width=569 height=454 id="_x0000_i1031" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/profile_design.jpg"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <p>We design the user interface in the profile activity layout. It defines how the profile data will be presented to the user and how the user update the profile in term of where they input the information and how they signal the system to save the profile. The profile activity layout is the <strong>view</strong> component in MVC.</p> <p>The profile activity glues the profile definition and the user interface together: it get data from the profile definition then push the data to the profile activity layout to show the profile to the user; when the user click the <strong>Save</strong> button, the activity is signaled. It retrieve the updated data from the view and push it to the profile definition to save.<o:p></o:p></p> <h2 id=tracking><span style='mso-fareast-font-family:"Times New Roman"'>Tracking<o:p></o:p></span></h2> <p>Tracking is the most complex module on <span class=SpellE>MyRuns</span>, which is shown below.</p> <div> <p class=MsoNormal><span style='mso-fareast-font-family:"Times New Roman"; mso-no-proof:yes'><img border=0 width=636 height=340 id="_x0000_i1030" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/tracking_design.jpg"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <p>As you can see from the diagram, the model has three sub-modules: tracking service, trace data structure, and trace database. The trace data structure defines what data is in a trace (e.g., GPS coordinates, time, duration, <span class=SpellE>etc</span>). All traces are saved in the trace database. The tracking service collect GPS coordinates as well as other trace related information.</p> <p>The <span class=SpellE>MapView</span> layout defines how the trace data will be presented to the user. It shows the live location trace, as well as location traces from the history.</p> <p>The <span class=SpellE>MapView</span> activity glues the user interface and the underline data structure, database, and tracking service together. If the user is tracking, the activity starts the tracking service, which creates an instance of the trace data structure. The service insert GPS coordinates to the trace instance, and notifies the activity, which, in turn, updates the <span class=SpellE>MapView</span> layout to show the latest location trace. After the user finished tracking, the activity stops the service, then save the trace instance to the database.</p> <p>If the user want to view a trace from history, the <span class=SpellE>MapView</span> activity retrieve the record from the database, then updates the <span class=SpellE>MapView</span> layout to show the trace.</p> <p>The implementation detail is described in later sections.<o:p></o:p></p> <h1 id="chap:uiimpl"><span style='mso-fareast-font-family:"Times New Roman"'>User Interface Implementation<o:p></o:p></span></h1> <p>This section provides an overview (read hints without details) of the design and implementation of the user interfaces.<o:p></o:p></p> <h2 id="chap:uiimpl:mainactivity"><span style='mso-fareast-font-family:"Times New Roman"'>Main Activity<o:p></o:p></span></h2> <p>The main activity is a navigation interface to access different interfaces by clicking different tabs on the top of the screen. The tabs use an <span class=SpellE>ActionBar</span> to add multiple Tabs to one activity. <o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:uiimpl:start_frag"><span style='mso-fareast-font-family:"Times New Roman"'>Start Fragment<o:p></o:p></span></h2> <h3 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=main-interface><span style='mso-fareast-font-family:"Times New Roman"'>Main Interface<o:p></o:p></span></h3> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The start tab allows the user to enter exercise information manually as discussed earlier. The root layout could be <span class=SpellE>LinearLayout</span>. You can also use other layout types if you wish. You will need spinner widgets for the layout to create a drop-down list for both the input type and activity type options.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You also need to implement the <span class=SpellE>setOnClickListener</span> for the &quot;Start&quot; and &quot;Sync&quot; buttons. Once the &quot;Start&quot; button is clicked, the app should fire the different activities according to the &quot;Input Type&quot;. If the input type is &quot;Manual Entry&quot;, then the <span class=SpellE>ManualInputActivity</span> allows the user to enter exercise stats; when &quot;GPS&quot; or &quot;Automatic&quot; is selected, the <span class=SpellE>MapDisplayActivity</span> should be shown to the user. The interfaces for both activities are discussed in <a href="http://www.cs.dartmouth.edu/~campbell/cs65/myruns/myruns_manual.html#chap:ui:start_tab">Start Tab</a> section. The &quot;Activity Type&quot; should be passed to the new activities by putting the value to the intent s extras. Activity types may include Running, Walking, <span class=GramE>Standing</span>, Cycling, Hiking, Downhill Skiing, Cross-Country Skiing, Snowboarding, Skating, Swimming, Mountain Biking, Wheelchair, Elliptical and Other.<o:p></o:p></p> <h3 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=manualinputactivity><span class=SpellE><span style='mso-fareast-font-family: "Times New Roman"'>ManualInputActivity</span></span><span style='mso-fareast-font-family: "Times New Roman"'><o:p></o:p></span></h3> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The user enters exercise information using dialogs driven by the <span class=SpellE>ManualInputActivity</span>. Therefore, you need to implement all the related dialogs in a <span class=SpellE>DialogFragment</span>, say <span class=SpellE>MyRunsDialogFragment</span>, or implement a <span class=SpellE>DialogFragment</span> for each dialog. After the user is done with inputting information using dialogs, the <span class=SpellE>ManualInputActivity</span> will store the input temporarily in an <a href="http://www.cs.dartmouth.edu/~campbell/cs65/myruns/myruns_manual.html#chap:dbimpl:data_struct"><span class=SpellE>ExerciseEntry</span></a> object. When the user clicks the &quot;Save&quot; button, the app saves the temporary data associated with the exercise stats in the database  so an insert in the database is going to occur when an exercise object representing all the information associated with a manually input single exercise is inserted as a new row in to the database. That was a torturous sentence class ;-) In dialog fragment's <span class=SpellE><span class=GramE>onCreateDialog</span></span><span class=GramE>(</span>), you should set which activity's method should be called when the user clicks the OK button.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Please read Android API documents for details on <span class=SpellE>DialogFragment</span>.<o:p></o:p></p> <h3 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=mapdisplayactivity><span class=SpellE><span style='mso-fareast-font-family: "Times New Roman"'>MapDisplayActivity</span></span><span style='mso-fareast-font-family: "Times New Roman"'><o:p></o:p></span></h3> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The <span class=SpellE>MapDisplayActivity</span> layout has three part: <em>map view, status and buttons</em>. In order to overlay the status on the map, you can use <span class=SpellE>FrameLayout</span> and put both <span class=SpellE>mapfragment</span> and a <span class=SpellE>LinearLayout</span> which contains the <span class=SpellE>textviews</span> needed to show the status. Buttons can be put in another <span class=SpellE>LinearLayout</span>. The following layout skeleton shows such design.</p> <pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>&lt;<span class=SpellE>FrameLayout</span>&gt;<span style='mso-spacerun:yes'>    </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>&lt;fragment<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>            </span><span class=SpellE>android:id</span>=&quot;@+id/map&quot;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>  </span><span style='mso-spacerun:yes'>          </span><span class=GramE>class</span>=&quot;<span class=SpellE>com.google.android.gms.maps.MapFragment</span>&quot; &gt;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>&lt;/fragment&gt;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>       </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>&lt;<span class=SpellE>LinearLayout</span>&gt;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>            </span>&lt;<span class=SpellE>TextView</span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span><span class=SpellE>android:id</span>=&quot;@+id/<span class=SpellE>type_stats</span>&quot;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span><span class=SpellE><span class=GramE>android:</span>text</span>=&quot; &quot; /&gt;<span style='mso-spacerun:yes'>   </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>            </span>....<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>&lt;/<span class=SpellE>LinearLayout</span>&gt;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>       </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>&lt;<span class=SpellE>LinearLayout</span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>            </span><span class=SpellE><span class=GramE>android:</span>layout_gravity</span>=&quot;bottom&quot; &gt;<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>            </span>&lt;Button<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span><span class=SpellE>android:id</span>=&quot;@+id/<span class=SpellE>btnSave</span>&quot;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span><span class=SpellE><span class=GramE>android:</span>onClick</span>=&quot;<span class=SpellE>onSaveClicked</span>&quot; /&gt;<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>            </span>&lt;Button<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span><span class=SpellE>android:id</span>=&quot;@+id/<span class=SpellE>btnCancel</span>&quot;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span><span class=SpellE><span class=GramE>android:</span>onClick</span>=&quot;<span class=SpellE>onCancelClicked</span>&quot;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span><span class=SpellE>android:text</span>=&quot;@string/<span class=SpellE>ui_button_cancel_title</span>&quot; /&gt;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>&lt;/<span class=SpellE>LinearLayout</span>&gt;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>&lt;/<span class=SpellE>FrameLayout</span>&gt;<o:p></o:p></code></pre> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>In order to show the map properly, you need to get a Google MAP API key for your app. You can check Android developers to find out how to do that.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The location trace needs to be updated once a location update is available and processed. You need to create a starting marker marking the start position, ending marker marking your current location and al line showing your trace. The starting marker needs to be place at the first location coordinate. Draw a single polyline along all the collected location coordinate. Place the ending marker at the last location coordinate.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Exercise status include activity type, average speed, current speed, climb, calories and distance. Please refer to the demo <span class=SpellE>apk</span> for details.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span class=SpellE>MapDisplay</span> has two modes: <em>displaying history entry and showing the live location trace</em>. To display a history entry, you need to figure out a way to retrieve the data from the database. To show the live location trace, you need to receive an update notification from the <span class=SpellE>TrackingService</span> and update the map accordingly. Please refer to <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:uiimpl:history_frag">History Fragment</a> and <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:serviceimpl">Service Implementation</a> for more details.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:uiimpl:history_frag"><span style='mso-fareast-font-family:"Times New Roman"'>History Fragment<o:p></o:p></span></h2> <h3 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=main-interface-1><span style='mso-fareast-font-family:"Times New Roman"'>Main Interface<o:p></o:p></span></h3> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The History Fragment loads all exercise entries from the database then displays the entries as a <span class=SpellE>ListView</span>. As mentioned in class, a <span class=SpellE>ListView</span> uses an adapter to show data. You can implement <span class=GramE>an</span> custom adapter class, for example, <span class=SpellE>ActivityEntriesAdapter</span>, which extends <span class=SpellE>ArrayAdapter</span>&lt;<span class=SpellE>ExerciseEntry</span>&gt; that exposes data from an array to the widget. You need to implement how the <span class=SpellE>ListView</span> displays each record. This can be done by using the override of the <span class=SpellE><span class=GramE>getView</span></span><span class=GramE>(</span>) method in <span class=SpellE>ActivityEntriesAdapter</span>. There should be two rows for each record. The format of the first row is as follows: &lt;Activity Type&gt; &lt;Date&gt;. The second row's format is: &lt;Distance&gt; &lt;Duration&gt;. One such example is showing in <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:ui:walk_through">User Interface Walk-through</a> (middle picture). You need to handle user's unit preference as well. You need to show the distance in user's selected unit (metric or imperial units, see <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:uiimpl:settings">Settings Fragment</a>)</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span class=SpellE>ListView s</span> <span class=SpellE>onListItemClick</span> should be implemented when the user clicks on history entries. When the selected entry s input type is manual entry, the app opens <span class=SpellE>DisplayEntryActivity</span> to show the details. Otherwise it opens <span class=SpellE>MapDisplayActivity</span> to show the trace along with the status. You need to pass exercise entry s unique database id to next activity, so that they can retrieve the entry from the database.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>History list also needs to respond to history entry updates. When the user delete an entry through the web interface (see later), the cloud will send a message to the app and the app needs to update the database. When the user is viewing a history fragment, the app should be able to update the view to reflect any changes.<o:p></o:p></p> <h3 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=displayentryactivity><span class=SpellE><span style='mso-fareast-font-family: "Times New Roman"'>DisplayEntryActivity</span></span><span style='mso-fareast-font-family: "Times New Roman"'><o:p></o:p></span></h3> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The <span class=SpellE>DisplayEntryActivity</span> has two jobs: 1) retrieve and display all the columns of a specific exercise entry to the list of <span class=SpellE>TextView</span>; and 2) setup a click listener for the option menu to call the <span class=SpellE>deleteEntryInDB</span> function in the <span class=SpellE>ExerciseEntryHelper</span> (see database section).</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The user can view a summarized list of all exercises using the tab history fragment. If the user clicks on one of the summaries on the list view then detailed information associated with the single exercise is displayed by <span class=SpellE>DisplayEntryActivity</span>.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Importantly, the user can delete the whole exercise entry by clicking on the &quot;DELETE&quot; button in the upper right hand corner of the UI layout  take a look at the app once you click on an summarized entry in the list view.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:uiimpl:settings"><span style='mso-fareast-font-family:"Times New Roman"'>Settings Fragment<o:p></o:p></span></h2> <h3 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=main-interface-2><span style='mso-fareast-font-family:"Times New Roman"'>Main Interface<o:p></o:p></span></h3> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The Settings Fragment is quite different from the Start Fragment and History Fragment classes. Because the Settings Fragment sets up various application preferences settings, it inherits from <span class=SpellE>PreferenceFragment</span>. We only need to call <span class=SpellE>addPreferencesFromResource</span> in the <span class=SpellE><span class=GramE>onCreate</span></span><span class=GramE>(</span>) method to load the preferences UI from an XML resource. This XML file is called preference.xml in directory: res/xml. The preference UI is displayed when the &quot;settings&quot; Tab is clicked.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Most of the elements in the Settings Fragment are common widgets, e.g., <span class=SpellE>CheckBoxPreference</span>, <span class=SpellE>ListPreference</span>. There are two other elements in the design: <em>user profile and class homepage</em>. When clicking these two elements a new activity should pop-up. This is achieved using the <span class=SpellE>PreferenceScreen</span> XML tag  see <span class=SpellE>PreferenceFragment</span> for more details.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Clicking on class homepage should invoke and open a browser and go to our class webpage. This is a nice example of one of your components using other apps on your phone; that is the browser.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Hint: you can directly set <span class=SpellE>android<span class=GramE>:action</span></span> and <span class=SpellE>android:data</span> for an intent inside XML file. Clicking on the user profile will open the profile activity.<o:p></o:p></p> <h3 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=profile-activity><span style='mso-fareast-font-family:"Times New Roman"'>Profile Activity<o:p></o:p></span></h3> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The UI in Android is controlled by an XML file in the res/layout folder; in this case you need to specify the layout, for example, in the profile.xml. The profile.xml layout should consist of a linear hierarchical of widgets and layouts. Android provides a  drag and drop method as part of the graphical layout  so you can either directly edit the xml file or use the graphical tool to design your layout, or both: you can easily switch between both modes as shown in class.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The layout should be a <span class=SpellE>ScrollView</span> element. Inside the <span class=SpellE>ScrollView</span> use a vertical <span class=SpellE>LinearLayout</span>. You need to program all elements contained the layout. The titles for all elements (e.g. Name, Email, Phone etc.) are <span class=SpellE>TextView</span> widgets. The editable boxes are <span class=SpellE>EditText</span> widgets. And the buttons for gender element are <span class=SpellE>RadioButtons</span> grouped as a <span class=SpellE>RadioGroup</span>. You will assign IDs to your widgets in the XML code, which you will refer later in your Java code. It s not necessary to give every item an ID. For example the <span class=SpellE>TextViews</span> item, you won t use them in the future, so their ID fields are not important. The grey hints in each <span class=SpellE>EditText</span> are specified by property  <span class=SpellE>android<span class=GramE>:hint</span></span> . Please set different keyboard layout for numerical and text input box using <span class=SpellE>android<span class=GramE>:inputType</span></span> property of <span class=SpellE>EditText</span>. By doing this, when you first interact with the text box, the keyboard layout is optimized for your type of input: for phone number field, the keyboard will be all numbers with larger buttons, etc. For email, the keyboard will be a <span class=GramE>Qwerty</span> keyboard. Note that all properties specified in the XML file can also be specified and modified in the Java code. But use XML as much as possible rather than programming the UI. If the appearance of the UI changes as the program executes, you will need to do some UI work in the Java code.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>In profile.xml, specify event handlers or <span class=SpellE>callbacks</span> for the two buttons. The callback logic for the save button captures the current information in the <span class=SpellE>EditText</span> and <span class=SpellE>RadioButton</span> elements and stores the user data; in the case of cancel button nothing is done other than to exit the activity. Here is an example of how you setup event handler for save button.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You should implement two private helper function methods in the activity to help load user data that has already been saved - called <span class=SpellE><span class=GramE>loadProfile</span></span><span class=GramE>(</span>) - and one to save the user data  called <span class=SpellE>saveProifle</span>(). Consider <span class=SpellE><span class=GramE>saveProifle</span></span><span class=GramE>(</span>): this function saves the user input data using a <span class=SpellE>SharedPreference</span> object, as discussed in class. After calling the helper function the activity simply displays some toast to the screen letting the user know that the data is saved. Similarly, when the application is started (either for the first time or restarted) the activity needs to load the user data using the <span class=SpellE><span class=GramE>loadProfile</span></span><span class=GramE>(</span>) helper. Your helper function calls <span class=SpellE><span class=GramE>loadProfile</span></span><span class=GramE>(</span>) method in <span class=SpellE>onCreate</span>() and uses the same <span class=SpellE>SharedPreference</span> object to load the data and display it to the screen. Think about the edge case the first time that the app runs when no previous data is saved. You will need to make sure some default data (e.g., empty string elements) are displayed.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You will need to add <span class=GramE>a</span> <span class=SpellE>ImageView</span> for displaying the photo and a button to trigger a Dialog, which will ask the user to either use camera or existing photos as shown above (central image). The selected photo needs to be cropped to fit the size of the <span class=SpellE>ImageView</span>. Also, you need to handle screen rotations. Recall in the class, a screen rotation will trigger <span class=SpellE><span class=GramE>onCreate</span></span><span class=GramE>(</span>), which will remove the unsaved pictures in this case. You can utilize <span class=SpellE><span class=GramE>onSaveInstanceState</span></span><span class=GramE>(</span>) to save the temporary profile picture and reload it in <span class=SpellE>onCreate</span>().</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Note, the triggered dialog invokes <span class=SpellE>MyRunsDialogFragment</span> that inherits <span class=SpellE>DialogFragment</span>. We will reuse the <span class=SpellE>MyRunsDialogFragment</span> class in future labs to handle all customized dialog boxes for the <span class=SpellE>MyRuns</span> app. In <span class=SpellE>MyRunsDialogFragment</span>, you can differentiate various dialog fragments by supplying distinctive dialog IDs in the <span class=SpellE>onCreateDialog</span> method.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Setting the profile image is challenging. When user clicks the &quot;Change&quot; change button, the activity shows a dialog asking if the user wants to take a picture or select one from the gallery as discussed above. Based on the users input the activity starts the camera or galley apps. You need to use <span class=SpellE><span class=GramE>startActivityForResult</span></span><span class=GramE>(</span>) to get results back from the camera or galley app, as discussed in class. Consider the following workflow: start an activity to get an image (either by camera or gallery), the activity returns the results to the profile activity, the profile activity then start another activity to crop the image. Finally, the profile activity gets the cropped image back from the cropping activity and displays it in the image view. You can use <span class=SpellE>MediaStore.ACTION_IMAGE_CAPTURE</span> to open the camera, <span class=SpellE>Intent.ACTION_PICK</span> to open the gallery.<o:p></o:p></p> <h1 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:dbimpl"><span style='mso-fareast-font-family:"Times New Roman"'>Database Implementation<o:p></o:p></span></h1> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>This section discusses the design and implementation of the database.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:dbimpl:data_struct"><span style='mso-fareast-font-family:"Times New Roman"'>Data structure<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span class=SpellE>ExerciseEntry</span> is the core data structure of the app. It defines what information a workout entry should have -- we use the term workout and exercise interchangeably in this document. It can be defined as below.</p> <pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>public</span> class <span class=SpellE>ExerciseEntry</span> {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> Long id;<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> <span class=SpellE>int</span> <span class=SpellE>mInputType</span>;<span style='mso-spacerun:yes'>        </span>// Manual, GPS or automatic<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> <span class=SpellE>int</span> <span class=SpellE>mActivityType</span>;<span style='mso-spacerun:yes'>     </span>// Running, cycling etc. <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> Calendar <span class=SpellE>mDateTime</span>;<span style='mso-spacerun:yes'>    </span>// When does this entry happen<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> <span class=SpellE>int</span> <span class=SpellE>mDuration</span>;<span style='mso-spacerun:yes'>         </span>// Exercise duration in seconds<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> double <span class=SpellE>mDistance</span>;<span style='mso-spacerun:yes'>      </span>// Distance traveled. Either in meters or feet.<span style='mso-spacerun:yes'>   </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> double <span class=SpellE>mAvgPace</span>;<span style='mso-spacerun:yes'>       </span>// Average pace<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> double <span class=SpellE>mAvgSpeed</span>;<span style='mso-spacerun:yes'>      </span>// Average speed<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> <span class=SpellE>int</span> <span class=SpellE>mCalorie</span>;<span style='mso-spacerun:yes'>          </span>// Calories burnt<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> double <span class=SpellE>mClimb</span>;<span style='mso-spacerun:yes'>         </span>// Climb. Either in meters or feet.<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> <span class=SpellE>int</span> <span class=SpellE>mHeartRate</span>;<span style='mso-spacerun:yes'>        </span>// Heart rate<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> String <span class=SpellE>mComment</span>;<span style='mso-spacerun:yes'>       </span>// Comments<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>private</span> <span class=SpellE>ArrayList</span>&lt;<span class=SpellE>LatLng</span>&gt; <span class=SpellE>mLocationList</span>; // Location list<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>}<o:p></o:p></code></pre> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You need to implement methods to set/get these attributes. For example, you need to implement methods to convert <span class=SpellE>mLocationList</span> to byte array to save in the database and convert byte array to array list when retrieving the location list.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=database-table-schema><span style='mso-fareast-font-family:"Times New Roman"'>Database Table Schema<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>There is only one table needed. It can be defined as follow:</p> <pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>CREATE TABLE IF NOT EXISTS ENTRIES (<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>_id INTEGER PRIMARY KEY AUTOINCREMENT, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>input_type</span></span> INTEGER NOT NULL, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>activity_type</span></span> INTEGER NOT NULL, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>date_time</span></span> DATETIME NOT NULL, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>duration</span> INTEGER NOT NULL, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>distance</span> FLOAT, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>avg_pace</span></span> FLOAT, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>avg_speed</span></span> FLOAT,<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>calories</span> INTEGER, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>climb</span> FLOAT, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>heartrate</span> INTEGER, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>comment</span> TEXT, <o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>privacy</span> INTEGER,<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>gps_data</span></span> BLOB );<o:p></o:p></code></pre> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The <em>_id is the primary key</em>. In database, the primary key uniquely identifies a record. &quot;AUTOINCREMENT&quot; indicates that the value will be set automatically and incrementally. The field <span class=SpellE>gps_data</span> stores all the GPS coordinates. We use BLOB to save all the coordinates. A BLOB value is a blob of data, stored exactly as it was input. (<span class=GramE>see</span> <a href="http://www.sqlite.org/datatype3.html">here</a>) As mentioned in <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:dbimpl:data_struct">Data structure</a>, you should store the location list in <span class=SpellE>gps_data</span>.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=implement-database-operations><span style='mso-fareast-font-family:"Times New Roman"'>Implement Database Operations<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The design principle of the database operations is to hide database operation details from app's other modules. That is, other modules, e.g. history tab, do not need to operate the database directly to get data entries from or save data entries to the database. There is concept called <a href="http://hibernate.org/orm/what-is-an-orm/">Object-relational mapping</a> which converts relational database operations to object-oriented operations. <a href="http://hibernate.org/orm/">Hibernate</a> is such platform. We will implement this concept in the simplest form. We define a helper class to encapsulate all the database operations. You can use <a href="http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html"><span class=SpellE>SQLiteOpenHelper</span></a> to implement your helper class. All necessary methods are defined as follows.</p> <pre><code><span style='mso-spacerun:yes'>    </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// Constructor<span style='mso-spacerun:yes'>  </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>public</span> <span class=SpellE>ExerciseEntryDbHelper</span>(Context context) {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>// DATABASE_NAME is, of course the name of the database, which is defined as a <span class=SpellE>tring</span> constant<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>  </span><span style='mso-spacerun:yes'>      </span>// DATABASE_VERSION is the version of database, which is defined as an integer constant<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>super(</span>context, DATABASE_NAME, null, DATABASE_VERSION);<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>}<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// <span class=GramE>Create</span> table schema if not exists<span style='mso-spacerun:yes'>    </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>@Override<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>public</span> void <span class=SpellE>onCreate</span>(<span class=SpellE>SQLiteDatabase</span> <span class=SpellE>db</span>) {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>db.execSQL</span></span><span class=GramE>(</span>CREATE_TABLE_ENTRIES);<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>}<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// Insert a item given each column value<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>public</span> long <span class=SpellE>insertEntry</span>(<span class=SpellE>ExerciseEntry</span> entry) {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>}<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// Remove an entry by giving its index<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>public</span> void <span class=SpellE>removeEntry</span>(long <span class=SpellE>rowIndex</span>) {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>   </span><span style='mso-spacerun:yes'> </span>}<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// Query a specific entry by its index.<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>public</span> <span class=SpellE>ExerciseEntry</span> <span class=SpellE>fetchEntryByIndex</span>(long <span class=SpellE>rowId</span>) {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>}<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// Query the entire table, return all rows<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>public</span> <span class=SpellE>ArrayList</span>&lt;<span class=SpellE>ExerciseEntry</span>&gt; <span class=SpellE>fetchEntries</span>() {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>}<o:p></o:p></code></pre> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>In each method defined above, you need to get a database object using <span class=SpellE><span class=GramE>getReadableDatabase</span></span><span class=GramE>(</span>) or <span class=SpellE>getWritableDatabase</span>(), then do the reads/writes. Remember to close database cursors and database object after you are done.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>As you can see from the class interface definitions, the input or output of these methods are all <span class=SpellE><em>ExerciseEntry</em></span> objects. When the history tab is loaded, it uses <span class=SpellE><span class=GramE>fetchEntries</span></span><span class=GramE>(</span>) to get the list of all entries. Then the list can be bound to an adapter so that the list view can show the entries. When the user selects an entry in the history tab, the app can use the <span class=SpellE><span class=GramE>fetchEntryByIndex</span></span><span class=GramE>(</span>) to get the entry s details and display them either in a display activity (if it is a manual entry) or in the map (if it is not a manual entry). If an entry is generated, you can use <span class=SpellE><span class=GramE>insertEntry</span></span><span class=GramE>(</span>) to insert it to the database.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Hint:</p> <ul type=disc> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l3 level1 lfo3;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Use Sqlite3, which is natively supported by Android<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l3 level1 lfo3;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Implement the helper class by extending <span class=SpellE>SQLiteOpenHelper</span><o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l3 level1 lfo3;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>You would save the location trace in either a Location list or a <span class=SpellE>LatLng</span> list. In order to save the trace to the <span class=SpellE>gps_data</span> blob field, you need to convert the list to a byte array when you save the record, and convert the byte array to the list when you read it from the database.<o:p></o:p></span></li> </ul> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id=use-database-helper-in-activities><span style='mso-fareast-font-family:"Times New Roman"'>Use Database Helper in Activities<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>To implement the database in the activities, you should create a database helper object. For example, if you define your helper class as <span class=SpellE>ExerciseEntryDbHelper</span>, you should create the helper object like this:</p> <pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=SpellE>ExerciseEntryDbHelper</span> <span class=SpellE>exerciseEntryDbHelper</span> = new <span class=SpellE><span class=GramE>ExerciseEntryDbHelper</span></span><span class=GramE>(</span>this);<o:p></o:p></code></pre> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>After this, you can use this object to operate the database. For example, if you want to remove an entry from the database:</p> <pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=SpellE><span class=GramE>exerciseEntryDbHelper.removeEntry</span></span><span class=GramE>(</span><span class=SpellE>entryID</span>);<o:p></o:p></code></pre> <h1 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:serviceimpl"><span style='mso-fareast-font-family:"Times New Roman"'>Service Implementation<o:p></o:p></span></h1> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>This section discusses the design considerations for service implementation.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:serviceimpl:tracking"><span style='mso-fareast-font-family:"Times New Roman"'>Tracking Service Design<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>There are two tracking mode. When the user clicks the start button in start tab, the <span class=SpellE>onStartBtnClick</span> handler passes the parameters (i.e., input type (GPS/automatic) and activity type) to <span class=SpellE>MapDisplayActivity</span>. <span class=SpellE>MapDisplayActivity</span> is also used to display the history entry, so it needs to determine if it should display a history entry or start a new entry. If it needs to display an entry, then <span class=SpellE>StartTabFragment</span> should pass the row id to it so that it can retrieve the entry from the database.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>If <span class=SpellE>MapDisplayActivity</span> needs to record a new workout, it starts the tracking service, get the exercise entry from the service, then update the map when it receives an update from the tracking service. The following flow chart shows the work flow of tracking service.</p> <div> <p class=MsoNormal style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span style='mso-fareast-font-family:"Times New Roman";mso-no-proof:yes'><img border=0 width=785 height=1021 id="_x0000_i1029" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/tracking_service.jpg"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You need to start the service explicitly instead of using the bind the service only (you can try to figure out why yourself). Also, you need to make sure the activity will not leak bound services. You can check this by inspecting logcat output. The key idea is that <span class=SpellE>TrackingService</span> creates an exercise entry and updates it when a new location update or activity inference update is available. The <span class=SpellE>TrackingService</span> sends a message to the <span class=SpellE>MapDisplayActivity</span>, so that the activity can update the map in a timely fashion. <span class=SpellE>MapDisplayActivity</span> gets the exercise entry when it is bound to the service, and saves the entry in the database once the tracking is completed.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Hints:</p> <ul type=disc> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l4 level1 lfo4;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Put parameters in intent s extras. The intent is used to start activity/service;<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l4 level1 lfo4;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Use Play Service API to implement collecting location coordinates;<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l4 level1 lfo4;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>All data update should be done in <span class=SpellE>TrackingService</span>, display the route should be done in <span class=SpellE>MapDisplayActivity</span>;<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l4 level1 lfo4;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Only use one polyline to draw the trace;<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l4 level1 lfo4;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Center the map when necessary;<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l4 level1 lfo4;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>Manage the notification in <span class=SpellE>TrackingService</span>, e.g., display the icon in <span class=SpellE><span class=GramE>onBind</span></span><span class=GramE>(</span>), remove it in <span class=SpellE>onDestroy</span>().<o:p></o:p></span></li> </ul> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:serviceimpl:activity"><span style='mso-fareast-font-family:"Times New Roman"'>Activity Recognition<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>In the automatic mode, the app continually infers the activity type using accelerometer data. The activity classifier is built using Weka. The following figure shows the activity classification process. <span class=SpellE>TrackingService</span> should implement <span class=SpellE><span class=GramE>onSensorChanged</span></span><span class=GramE>(</span>) interface to receive accelerometer updates. Once it received an update, it put the accelerometer reading into a data queue. A working thread continuously gets readings from the queue.</p> <div> <p class=MsoNormal style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span style='mso-fareast-font-family:"Times New Roman";mso-no-proof:yes'><img border=0 width=728 height=569 id="_x0000_i1028" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/activity_recognition.jpg"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Once the app has 64 readings, a feature vector is generated which will be the input of Weka classifier. The classifier generates a label that indicates user s current activity (e.g., walking). The label is then updated in the <span class=SpellE>ExcerciseEntry</span>. A basic counting approach determines the overall activity based on the ratios of each label; that is if walking and running are measured the activity with the most labels become the overall label for the period.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The feature vector is generated as follows:</p> <pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>max</span> = max(<span class=SpellE>accBlock</span>);<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// Compute the re and <span class=SpellE>im</span>:<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// setting values of re and <span class=SpellE>im</span> by reference.<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=SpellE><span class=GramE>fft.fft</span></span><span class=GramE>(</span>re, <span class=SpellE>im</span>);<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>for</span> (<span class=SpellE>int</span> i = 0; i &lt; <span class=SpellE>re.length</span>; i++) {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span style='mso-spacerun:yes'>    </span>// Compute each coefficient<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>double</span> mag = <span class=SpellE>Math.sqrt</span>(re[i] * re[i] + <span class=SpellE>im</span>[i]* <span class=SpellE>im</span>[i]);<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>// <span class=GramE>Adding</span> the computed FFT coefficient to the<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>// <span class=SpellE>featVect</span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>featVect.add</span></span><span class=GramE>(</span><span class=SpellE>Double.valueOf</span>(mag));<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>// Clear the field<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>im</span></span><span class=GramE>[</span>i] = .0;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>}<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>// <span class=GramE>Finally</span>, append max after frequency components<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=SpellE><span class=GramE>featVect.add</span></span><span class=GramE>(</span><span class=SpellE>Double.valueOf</span>(max));</code></pre> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>To collect the training data, import the <a href="../code/myrunsdatacollector.zip">myrunsdatacollector.zip</a> to Android Studio, build it and install it on your phone. This is the data collector app that you will use to collect training data to create classification model in Weka. The collector allows you to label different activities. The output of the collector is a single file called <span class=SpellE>feature.arff</span>, which is input to Weka to create the classifier.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:serviceimpl:cloud"><span style='mso-fareast-font-family:"Times New Roman"'>Google App Engine<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>When the user clicks  Sync , all local history entries will be uploaded to Google App Engine. Users can view the entry from browser. When the user clicks one entry s  DELETE button, the entry should be deleted both remotely on the cloud and locally on the phone. Make sure that you are deploying the server to the cloud. An example web interface is shown below.</p> <div> <p class=MsoNormal style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span style='mso-fareast-font-family:"Times New Roman";mso-no-proof:yes'><img border=0 width=1893 height=356 id="_x0000_i1027" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/web_interface.png"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The following figure shows how the system works. The app registers Google Cloud Messaging (GCM) in the <span class=SpellE>MainActivity</span> to receive entry deletion updates from the server. When the app is registered with GCM, it sends its device id to the server. The <span class=SpellE>GcmRegistrationAsyncTask</span> in the <span class=SpellE>MainActivity</span>, sends the device id to the server. In the server, it is handled by the <span class=SpellE>RegistrationEndPoint</span>, which then saves the device id into the <span class=SpellE>datastore</span>. When the user clicks on the  Sync button, the <span class=SpellE>StartTabFragment</span> retrieves all the entries from the database, and then converts them into JSON format. <span class=SpellE>ServerUtilities</span> then posts the JSON format data to server s <span class=SpellE>PostDataServlet</span> which in turn save the data to the <span class=SpellE>datastore</span>. In the server, the <span class=SpellE>MyRunsAppEngineServlet</span> fetches all the entries from the <span class=SpellE>datastore</span> and displays them on the web interface as a HTML table. When the user clicks the delete button, it passes through <span class=SpellE>SendDeleteMessageServlet</span>, which deletes the particular entry from the <span class=SpellE>datastore</span> and redirects to <span class=SpellE>MyRunsAppEngineServlet</span>. In the meantime the <span class=SpellE>SendDeleteMessageServlet</span> also sends a GCM message using <span class=SpellE>MessagingEndPoint</span> to the device, which contains the ID of the field to be deleted. This message is received by the <span class=SpellE>GCMBroadcastReceiver</span>, and the <span class=SpellE>GCMIntentReceiver</span> is invoked, which in turn deletes the entry from the local database.</p> <div> <p class=MsoNormal style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><span style='mso-fareast-font-family:"Times New Roman";mso-no-proof:yes'><img border=0 width=1126 height=569 id="_x0000_i1026" src="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project_files/app_engine.png"></span><span style='mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></p> </div> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>MyRuns_Lab6_AppEngineServlet provides user the list of all entries (as shown in the first picture). When user clicks the  Delete button, the request will be posted to <span class=SpellE>SendDeleteMessageServlet</span> where a message will be sent to the app and the selected entry will be deleted from the <span class=SpellE>datastore</span>. When the deletion is done, it should redirect to MyRuns_Lab6_AppEngineServlet to show the entry list. The entry should has been remove.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Hint:</p> <ul type=disc> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l2 level1 lfo5;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>You should know how Google Cloud Messaging works<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l2 level1 lfo5;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>You should know the concept of Java Servlet<o:p></o:p></span></li> <li class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; mso-list:l2 level1 lfo5;tab-stops:list 36.0pt'><span style='mso-fareast-font-family: "Times New Roman"'>You should know Google <span class=SpellE>Datastore</span> is not a database<o:p></o:p></span></li> </ul> <h1 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:labs"><span style='mso-fareast-font-family:"Times New Roman"'>The <span class=SpellE>MyRuns</span> Labs<o:p></o:p></span></h1> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>The 6 labs serve as checkpoints along the way to build the complete lab. Follow each lab after reading the complete documentation. We provide the APK for each lab and the pointers <span class=SpellE>beflow</span> as well as the detailed spec (above). In what follows, we discuss each lab.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:labs:1"><span style='mso-fareast-font-family:"Times New Roman"'>Lab 1 -- The User Profile<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><em>Demo the lab: You can download <a href="../APKs/MyRuns-Android-chk1.apk">MyRuns-Android-chk1.apk</a> and run the app to see how it operates. Use that knowledge to fill in the gaps in the above document</em>.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Complete the profile activity. Save profile to the SD/flash card and reload when needed.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>This is the first in a series of labs that allow you to develop the <span class=SpellE>MyRuns</span> App to capture and display your physical activities using your Android phone. This lab focuses on developing a simple UI for setting up your profile: i.e. name, email, phone number, gender and major. It works as follows: the app presents the user with an activity that allows them to input and save their profile. When the app is opened again, the saved profile information should be reloaded and displayed, allowing the user to review their data and make further changes if needed.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>In this lab there is a single activity. The UI design for the activity is specified in <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:ui:settings_tab">Settings Tab</a> section, and the implementation design is specified in <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:uiimpl:settings">Settings Fragment</a> section. The application is defined in the AndroidManifest.xml file. You specify all of these files in XML and Java code. Recall the manifest captures the key information about the application to the Android system, information the system needs before it can run any of the application's code -- for example, the activity name, etc. Typically you will update the manifest for example if you have an application with more than one activity.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><strong>Note: since <span class=SpellE>DialogFragment</span> has not been taught at this point, you do not have to implement the selection of the profile image through &quot;select from gallery&quot;. When the &quot;Change&quot; button is clicked, you only need to take a picture using the camera but you have to be able to crop the picture.</strong></p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You cannot use <span class=SpellE>println</span> or <span class=SpellE>printf</span> for logging purpose with Android -- for control flow or looking at programming state such as variables. As discussed in the notes Android supports a logging capability that you can add to your code. Take a look at the class notes that uses <span class=SpellE><span class=GramE>Log.d</span></span><span class=GramE>(</span>TAG, ..). Setup your on TAG and add <span class=SpellE><span class=GramE>Log.d</span></span><span class=GramE>(</span>)s to all your methods -- also checkout Log. If your program crashed, don t be panic. Look into the system log in the <span class=SpellE>LogCat</span> window, it will print out the function call stack upon crash. If you see logs with red font then that is associated with the exception. Most of the time you will find what causes your crash. We will discuss debugging techniques in more detail next week in class.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:labs:2"><span style='mso-fareast-font-family:"Times New Roman"'>Lab 2 -- The User Interface (UI)<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><em>Demo the lab: You can download <a href="../APKs/MyRuns-Android-chk2.apk">MyRuns-Android-chk2.apk</a> and run the app to see how it operates. Use that knowledge to fill in the gaps in the above document</em>.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>In this lab, you need to complete all the user interfaces, including all the activities, main activity's Action Tabs. You should be able to navigate between all of the activities.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You need to continue implementing the profile activity. In Lab 1, you have implemented setting profile picture by taking a photo. As described in <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:ui:settings_tab">Settings Tab</a> section, user should also be able to select a picture from the gallery as their profile image. To make your life easier, we provide you the code to convert image URI to real file path.</p> <pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span><span class=GramE>private</span> String <span class=SpellE>getRealPathFromURI</span>(Uri <span class=SpellE>contentUri</span>) {<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>String[</span>] <span class=SpellE>proj</span> = new String[] { <span class=SpellE>android.provider.MediaStore.Images.ImageColumns.DATA</span> };<o:p></o:p></code></pre><pre><code><o:p>&nbsp;</o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>Cursor <span class=SpellE>cursor</span> = <span class=SpellE><span class=GramE>getContentResolver</span></span><span class=GramE>(</span>).query(<span class=SpellE>contentUri</span>, <span class=SpellE>proj</span>, null,<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span><span class=GramE>null</span>, null);<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>int</span></span> <span class=SpellE>column_index</span> = cursor<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>                </span>.<span class=SpellE><span class=GramE>getColumnIndexOrThrow</span></span><span class=GramE>(</span><span class=SpellE>MediaStore.Images.Media.DATA</span>);<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>cursor.moveToFirst</span></span><span class=GramE>(</span>);<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span>String filename = <span class=SpellE><span class=GramE>cursor.getString</span></span><span class=GramE>(</span><span class=SpellE>column_index</span>);<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=SpellE><span class=GramE>cursor.close</span></span><span class=GramE>(</span>);<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>        </span><span class=GramE>return</span> filename;<o:p></o:p></code></pre><pre><code><span style='mso-spacerun:yes'>    </span>}</code></pre> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>It is possible that the Android Gallery app would show pictures from your Picasa, but you can't access these pictures directly. Again, to make your life easier, we do not require you to handle this situation.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You need to implement all the activities shown in <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:sub">User Interface</a>. To be specific, you need to implement the main activity containing three fragments: start, history and settings. You should be able to switch to different tab. When you rotate the screen, the tab that is open should stay opened. Switching to default tab is not acceptable when the screen rotated. You need to figure out how to save selected tab as discussed in <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:uiimpl:mainactivity">Main Activity</a> section.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You don't need to show the map in <span class=SpellE>MapDisplayActivity</span>.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:labs:3"><span style='mso-fareast-font-family:"Times New Roman"'>Lab 3 -- The Database<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><em>Demo the lab: You can download <a href="../APKs/MyRuns-Android-chk3.apk">MyRuns-Android-chk3.apk</a> and run the app to see how it operates. Use that knowledge to fill in the gaps in the above document</em>.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Complete the database design and implementation following the <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:dbimpl">Database Implementation</a> section. You should be able to add an exercise entry manually from the <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:ui:start_tab">start tab</a> at the main activity, view the entries in the <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:ui:history_tab">history tab</a>, and delete the entry from <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:uiimpl:history_frag"><span class=SpellE>DisplayEntryActivity</span></a>. You need to use <span class=SpellE>AsyncTaskLoader</span> for reading data from the database (<a href="Loaders.htm">see an example here</a>).</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You need to show the data in correct format. For example, if the user set their unit preference to Metric (Kilometers), all distance related data should be shown in kilometers. If you save the data in miles, you need to convert it to kilometers before showing it. You need to think of a good way to convert the raw exercise entry data to human readable format. You also need to display some data in the map in Lab 4. Try to come up with a good design to avoid duplicate code.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:labs:4"><span style='mso-fareast-font-family:"Times New Roman"'>Lab 4 -- Google Maps<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><em>Demo the lab: You can download <a href="../APKs/MyRuns-Android-chk4.apk">MyRuns-Android-chk4.apk</a> and run the app to see how it operates. Use that knowledge to fill in the gaps in the above document</em>.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Design and implement the tracking services. Draw the real-time GPS trace on Google Maps using the continuous location updates. Save the traces in the database and visualize the GPS trace history on Google Maps. You should also be able to view the history trace from the history tab.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>To be specific, you need to finish implementing the <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:uiimpl:start_frag"><span class=SpellE>MapViewActivity</span></a> and <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:serviceimpl:tracking">tracking service</a>.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:labs:5"><span style='mso-fareast-font-family:"Times New Roman"'>Lab 5 -- Activity Recognition<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'><em>Demo the lab: You can download <a href="../APKs/MyRuns-Android-chk5.apk">MyRuns-Android-chk5.apk</a> and run the app to see how it operates. Use that knowledge to fill in the gaps in the above document</em>.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>Implement activity recognition. You should train an activity classifier by collecting accelerometer data, then apply the classifier in your app.</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>To be specific, you need to finish implementing <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:serviceimpl:activity">activity classifier</a>. This is a three-part problem: collecting training data using the data collector, train the classifier and implement the classifier.<o:p></o:p></p> <h2 style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt' id="chap:labs:6"><span style='mso-fareast-font-family:"Times New Roman"'>Lab 6 -- App Engine<o:p></o:p></span></h2> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>We do not provide demo <span class=SpellE>apk</span> for this lab because it requires setting up app engine and modifying the configuration for each individual programmer, which is not feasible. However, here is a <a href="https://youtu.be/23rf0ZW2rDQ">demo video</a>, which can give you a brief idea of what you need to develop. The video only shows that the backend works on your local machine but you need to deploy it to the cloud.&nbsp;&nbsp;</p> <p style='tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt'>You should finish the whole <a href="MyRuns%20Project%20Document%20 %20The%20MyRuns%20Project.html#chap:serviceimpl:cloud">app engine side</a>, which includes displaying history entries, delete an entry, <span class=GramE>receive</span> uploaded history list and managing <span class=SpellE>datastore</span>. You need to publish your server to the cloud instead of running it locally. On the app side, your app should be able to upload the history list to the server, receive delete messages from app engine and delete any corresponding entries from the database. If the user is using history tab, the app should update the history list when an entry is deleted from the app engine by the user.</p> </div> </body> </html>