├── .gitattributes
├── .gitignore
├── .nuget
└── NuGet.targets
├── BackgroundTasks
├── BackgroundTasks.csproj
├── Converters.cs
├── OEMTask.cs
├── Properties
│ └── AssemblyInfo.cs
├── packages.config
└── project.json
├── README.md
├── Steps.sln
└── Steps
├── AboutPage.xaml
├── AboutPage.xaml.cs
├── App.xaml
├── App.xaml.cs
├── Assets
├── BadgeLogo.scale-240.png
├── Images
│ ├── back.png
│ ├── next.png
│ ├── pin-48px.png
│ ├── pushpin.png
│ └── unpin-48px.png
├── Logo.png
├── SplashScreen.scale-240.png
├── Square44x44Logo.png
├── Square44x44Logo.scale-240.png
├── SquareTile150x150.scale-240.png
├── SquareTile71x71.scale-240.png
├── StoreLogo.png
├── Tiles
│ ├── 150x150.png
│ ├── 30x30.png
│ ├── IconicTileMediumLarge - Copy.png
│ ├── IconicTileMediumLarge.png
│ ├── IconicTileSmall.png
│ ├── small_square0.png
│ ├── small_square1.png
│ ├── small_square2.png
│ ├── small_square3.png
│ ├── square.png
│ ├── square0.png
│ ├── square1.png
│ ├── square2.png
│ ├── square3.png
│ ├── wide0.png
│ ├── wide1.png
│ ├── wide2.png
│ ├── wide3.png
│ ├── wide4.png
│ ├── wide5.png
│ ├── wide6.png
│ ├── wide7.png
│ └── wide8.png
├── WideLogo.scale-240.png
├── steps_background_02.png
├── steps_background_02_620x300.png
├── steps_launcher.png
├── steps_launcher150x150.png
└── steps_launcher310x150.png
├── DataConverter.cs
├── DataModels
└── MainModel.cs
├── MainPage.xaml
├── MainPage.xaml.cs
├── Package.appxmanifest
├── Properties
├── AssemblyInfo.cs
└── Default.rd.xml
├── Simulations
├── long run.txt
├── short recording.txt
└── short walk.txt
├── Steps.csproj
├── StepsEngine.cs
├── Strings
└── en-US
│ ├── ActivateSensorCore.resw
│ └── Resources.resw
└── project.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 |
11 | [Dd]ebug/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | [Bb]in/
16 | [Oo]bj/
17 |
18 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
19 | !packages/*/build/
20 |
21 | # MSTest test Results
22 | [Tt]est[Rr]esult*/
23 | [Bb]uild[Ll]og.*
24 |
25 | *_i.c
26 | *_p.c
27 | *.ilk
28 | *.meta
29 | *.obj
30 | *.pch
31 | *.pdb
32 | *.pgc
33 | *.pgd
34 | *.rsp
35 | *.sbr
36 | *.tlb
37 | *.tli
38 | *.tlh
39 | *.tmp
40 | *.tmp_proj
41 | *.log
42 | *.vspscc
43 | *.vssscc
44 | .builds
45 | *.pidb
46 | *.log
47 | *.scc
48 |
49 | # Visual C++ cache files
50 | ipch/
51 | *.aps
52 | *.ncb
53 | *.opensdf
54 | *.sdf
55 | *.cachefile
56 |
57 | # Visual Studio profiler
58 | *.psess
59 | *.vsp
60 | *.vspx
61 |
62 | # Guidance Automation Toolkit
63 | *.gpState
64 |
65 | # ReSharper is a .NET coding add-in
66 | _ReSharper*/
67 | *.[Rr]e[Ss]harper
68 |
69 | # TeamCity is a build add-in
70 | _TeamCity*
71 |
72 | # DotCover is a Code Coverage Tool
73 | *.dotCover
74 |
75 | # NCrunch
76 | *.ncrunch*
77 | .*crunch*.local.xml
78 |
79 | # Installshield output folder
80 | [Ee]xpress/
81 |
82 | # DocProject is a documentation generator add-in
83 | DocProject/buildhelp/
84 | DocProject/Help/*.HxT
85 | DocProject/Help/*.HxC
86 | DocProject/Help/*.hhc
87 | DocProject/Help/*.hhk
88 | DocProject/Help/*.hhp
89 | DocProject/Help/Html2
90 | DocProject/Help/html
91 |
92 | # Click-Once directory
93 | publish/
94 |
95 | # Publish Web Output
96 | *.Publish.xml
97 |
98 | # NuGet Packages Directory
99 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
100 | #packages/
101 |
102 | # Windows Azure Build Output
103 | csx
104 | *.build.csdef
105 |
106 | # Windows Store app package directory
107 | AppPackages/
108 |
109 | # Others
110 | sql/
111 | *.Cache
112 | ClientBin/
113 | [Ss]tyle[Cc]op.*
114 | ~$*
115 | *~
116 | *.dbmdl
117 | *.[Pp]ublish.xml
118 | *.pfx
119 | *.publishsettings
120 |
121 | # RIA/Silverlight projects
122 | Generated_Code/
123 |
124 | # Backup & report files from converting an old project file to a newer
125 | # Visual Studio version. Backup files are not needed, because we have git ;-)
126 | _UpgradeReport_Files/
127 | Backup*/
128 | UpgradeLog*.XML
129 | UpgradeLog*.htm
130 |
131 | # SQL Server files
132 | App_Data/*.mdf
133 | App_Data/*.ldf
134 |
135 |
136 | #LightSwitch generated files
137 | GeneratedArtifacts/
138 | _Pvt_Extensions/
139 | ModelManifest.xml
140 |
141 | # =========================
142 | # Windows detritus
143 | # =========================
144 |
145 | # Windows image file caches
146 | Thumbs.db
147 | ehthumbs.db
148 |
149 | # Folder config file
150 | Desktop.ini
151 |
152 | # Recycle Bin used on file shares
153 | $RECYCLE.BIN/
154 |
155 | # Mac desktop service store files
156 | .DS_Store
157 | /Steps/project.lock.json
158 | /Steps/.vs/config
159 |
--------------------------------------------------------------------------------
/.nuget/NuGet.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\..\
5 |
6 |
7 | true
8 |
9 |
10 | false
11 |
12 |
13 | true
14 |
15 |
16 | true
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
31 |
32 |
33 |
34 |
35 | $(SolutionDir).nuget
36 |
37 |
38 |
39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config
40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config
41 |
42 |
43 |
44 | $(MSBuildProjectDirectory)\packages.config
45 | $(PackagesProjectConfig)
46 |
47 |
48 |
49 |
50 | $(NuGetToolsPath)\NuGet.exe
51 | @(PackageSource)
52 |
53 | "$(NuGetExePath)"
54 | mono --runtime=v4.0.30319 $(NuGetExePath)
55 |
56 | $(TargetDir.Trim('\\'))
57 |
58 | -RequireConsent
59 | -NonInteractive
60 |
61 | "$(SolutionDir) "
62 | "$(SolutionDir)"
63 |
64 |
65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
67 |
68 |
69 |
70 | RestorePackages;
71 | $(BuildDependsOn);
72 |
73 |
74 |
75 |
76 | $(BuildDependsOn);
77 | BuildPackage;
78 |
79 |
80 |
81 |
82 |
83 |
84 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
99 |
100 |
103 |
104 |
105 |
106 |
108 |
109 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/BackgroundTasks/BackgroundTasks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {086C4C13-0C8E-4275-A196-42CD28A4E523}
8 | winmdobj
9 | Properties
10 | BackgroundTasks
11 | BackgroundTasks
12 | en-US
13 | UAP
14 | 10.0.10586.0
15 | 10.0.10240.0
16 | 14
17 | 512
18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | false
20 |
21 |
22 | AnyCPU
23 | true
24 | full
25 | false
26 | bin\Debug\
27 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
28 | prompt
29 | 4
30 |
31 |
32 | AnyCPU
33 | pdbonly
34 | true
35 | bin\Release\
36 | TRACE;NETFX_CORE;WINDOWS_UWP
37 | prompt
38 | 4
39 |
40 |
41 | ARM
42 | true
43 | bin\ARM\Debug\
44 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
45 | ;2008
46 | full
47 | ARM
48 | false
49 | prompt
50 |
51 |
52 | ARM
53 | bin\ARM\Release\
54 | TRACE;NETFX_CORE;WINDOWS_UWP
55 | true
56 | ;2008
57 | pdbonly
58 | ARM
59 | false
60 | prompt
61 |
62 |
63 | x64
64 | true
65 | bin\x64\Debug\
66 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
67 | ;2008
68 | full
69 | x64
70 | false
71 | prompt
72 |
73 |
74 | x64
75 | bin\x64\Release\
76 | TRACE;NETFX_CORE;WINDOWS_UWP
77 | true
78 | ;2008
79 | pdbonly
80 | x64
81 | false
82 | prompt
83 |
84 |
85 | x86
86 | true
87 | bin\x86\Debug\
88 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
89 | ;2008
90 | full
91 | x86
92 | false
93 | prompt
94 |
95 |
96 | x86
97 | bin\x86\Release\
98 | TRACE;NETFX_CORE;WINDOWS_UWP
99 | true
100 | ;2008
101 | pdbonly
102 | x86
103 | false
104 | prompt
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | 14.0
117 |
118 |
119 |
126 |
--------------------------------------------------------------------------------
/BackgroundTasks/Converters.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Microsoft
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy
4 | * of this software and associated documentation files (the "Software"), to deal
5 | * in the Software without restriction, including without limitation the rights
6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | * copies of the Software, and to permit persons to whom the Software is
8 | * furnished to do so, subject to the following conditions:
9 |
10 | * The above copyright notice and this permission notice shall be included in
11 | * all copies or substantial portions of the Software.
12 |
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | */
20 | using System.Collections.Generic;
21 | using Windows.Devices.Sensors;
22 | using Lumia.Sense;
23 |
24 | namespace BackgroundTasks.Converters
25 | {
26 | ///
27 | /// Extracts the step counts from pedometer readings or Lumia StepCountData
28 | ///
29 | public sealed class StepCountData
30 | {
31 | public uint RunningCount { get; private set; }
32 | public uint WalkingCount { get; private set; }
33 | public uint UnknownCount { get; private set; }
34 |
35 | public uint TotalCount
36 | {
37 | get
38 | {
39 | return RunningCount + WalkingCount + UnknownCount;
40 | }
41 | }
42 |
43 | ///
44 | /// Factory that creates a StepCountData object from PedometerReadings
45 | ///
46 | ///
47 | ///
48 | public static StepCountData FromPedometerReadings(IReadOnlyList readings)
49 | {
50 | StepCountData steps = new StepCountData();
51 | // Get the most recent batch of 3 readings (one per StepKind)
52 | for (int i = 0; i < readings.Count && i < 3; i++)
53 | {
54 | var reading = readings[readings.Count - i - 1];
55 | switch (reading.StepKind)
56 | {
57 | case PedometerStepKind.Running:
58 | steps.RunningCount = (uint)reading.CumulativeSteps;
59 | break;
60 | case PedometerStepKind.Walking:
61 | steps.WalkingCount = (uint)reading.CumulativeSteps;
62 | break;
63 | case PedometerStepKind.Unknown:
64 | steps.UnknownCount = (uint)reading.CumulativeSteps;
65 | break;
66 | default:
67 | break;
68 | }
69 | }
70 |
71 | // Subtract the counts from the earliest batch of 3 readings (one per StepKind)
72 | for (int i = 0; i < readings.Count && i < 3; i++)
73 | {
74 | var reading = readings[i];
75 | switch (reading.StepKind)
76 | {
77 | case PedometerStepKind.Running:
78 | steps.RunningCount -= (uint)reading.CumulativeSteps;
79 | break;
80 | case PedometerStepKind.Walking:
81 | steps.WalkingCount -= (uint)reading.CumulativeSteps;
82 | break;
83 | case PedometerStepKind.Unknown:
84 | steps.UnknownCount -= (uint)reading.CumulativeSteps;
85 | break;
86 | default:
87 | break;
88 | }
89 | }
90 |
91 | return steps;
92 | }
93 |
94 | ///
95 | /// Factory that creates a StepCountData object from a Lumia StepCount
96 | ///
97 | ///
98 | ///
99 | public static StepCountData FromLumiaStepCount(StepCount stepCount)
100 | {
101 | StepCountData steps = new StepCountData();
102 |
103 | steps.RunningCount = stepCount.RunningStepCount;
104 | steps.WalkingCount = stepCount.WalkingStepCount;
105 | steps.UnknownCount = 0;
106 |
107 | return steps;
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/BackgroundTasks/OEMTask.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Microsoft
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy
4 | * of this software and associated documentation files (the "Software"), to deal
5 | * in the Software without restriction, including without limitation the rights
6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | * copies of the Software, and to permit persons to whom the Software is
8 | * furnished to do so, subject to the following conditions:
9 |
10 | * The above copyright notice and this permission notice shall be included in
11 | * all copies or substantial portions of the Software.
12 |
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | */
20 | using System;
21 | using System.Threading.Tasks;
22 | using Windows.ApplicationModel.Background;
23 | using Windows.Data.Xml.Dom;
24 | using Windows.Devices.Sensors;
25 | using Windows.UI.Notifications;
26 | using Lumia.Sense;
27 |
28 | using BackgroundTasks.Converters;
29 |
30 | namespace BackgroundTasks
31 | {
32 | ///
33 | /// Background task class for step counter trigger
34 | ///
35 | public sealed class StepTriggerTask : IBackgroundTask
36 | {
37 | #region Constant definitions
38 | ///
39 | /// Tile ID
40 | ///
41 | private const string TILE_ID = "SecondaryTile.Steps";
42 |
43 | ///
44 | /// Target daily step count
45 | ///
46 | private const uint TARGET_STEPS = 10000;
47 |
48 | ///
49 | /// Number of large meter images
50 | ///
51 | private const uint NUM_LARGE_METER_IMAGES = 9;
52 |
53 | ///
54 | /// Number of small meter images
55 | ///
56 | private const uint NUM_SMALL_METER_IMAGES = 4;
57 | #endregion
58 |
59 | #region Private members
60 | ///
61 | /// Number of steps
62 | ///
63 | private StepCountData _steps;
64 |
65 | ///
66 | /// Sens error code
67 | ///
68 | private SenseError _lastError;
69 | #endregion
70 |
71 | ///
72 | /// Performs the work of a background task. The system calls this method when
73 | /// the associated background task has been triggered.
74 | ///
75 | /// An interface to an instance of the background task
76 | public async void Run(IBackgroundTaskInstance taskInstance)
77 | {
78 | BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
79 | try
80 | {
81 | if (await GetStepsAsync())
82 | {
83 | UpdateTile(_steps.RunningCount + _steps.WalkingCount);
84 | }
85 | }
86 | catch (Exception)
87 | {
88 | }
89 | deferral.Complete();
90 | }
91 |
92 | ///
93 | /// Returns small live tile image index
94 | ///
95 | /// Current step count
96 | /// Small live tile image index
97 | public static uint GetSmallLiveTileImageIndex(uint stepCount)
98 | {
99 | return (NUM_SMALL_METER_IMAGES - 1) * Math.Min(stepCount, TARGET_STEPS) / TARGET_STEPS;
100 | }
101 |
102 | ///
103 | /// Returns large live tile image index
104 | ///
105 | /// Current step count
106 | /// Large live tile image index
107 | public static uint GetLargeLiveTileImageIndex(uint stepCount)
108 | {
109 | return (NUM_LARGE_METER_IMAGES - 1) * Math.Min(stepCount, TARGET_STEPS) / TARGET_STEPS;
110 | }
111 |
112 | ///
113 | /// Gets number of steps for current day
114 | ///
115 | /// true if steps were successfully fetched, false otherwise
116 | private async Task GetStepsAsync()
117 | {
118 | // First try the pedometer
119 | try
120 | {
121 | var readings = await Pedometer.GetSystemHistoryAsync(DateTime.Now.Date, DateTime.Now - DateTime.Now.Date);
122 | _steps = StepCountData.FromPedometerReadings(readings);
123 | return true;
124 | }
125 | catch (Exception)
126 | {
127 | // Continue to the fallback
128 | }
129 |
130 | // Fall back to using Lumia Sensor Core.
131 | StepCounter stepCounter = null;
132 | try
133 | {
134 | stepCounter = await StepCounter.GetDefaultAsync();
135 | StepCount count = await stepCounter.GetStepCountForRangeAsync(
136 | DateTime.Now.Date,
137 | DateTime.Now - DateTime.Now.Date);
138 | _steps = StepCountData.FromLumiaStepCount(count);
139 | }
140 | catch (Exception e)
141 | {
142 | _lastError = SenseHelper.GetSenseError(e.HResult);
143 | return false;
144 | }
145 | finally
146 | {
147 | if (stepCounter != null)
148 | {
149 | stepCounter.Dispose();
150 | }
151 | }
152 | return true;
153 | }
154 |
155 | ///
156 | /// Update the live tile
157 | ///
158 | /// Step count
159 | private void UpdateTile(uint stepCount)
160 | {
161 | uint meterIndex = GetLargeLiveTileImageIndex(stepCount);
162 | uint smallMeterIndex = GetSmallLiveTileImageIndex(stepCount);
163 | var smallTile = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare71x71Image);
164 | XmlNodeList imageAttribute = smallTile.GetElementsByTagName("image");
165 | ((XmlElement)imageAttribute[0]).SetAttribute("src", "ms-appx:///Assets/Tiles/small_square" + smallMeterIndex + ".png");
166 | var bindingSmall = (XmlElement)smallTile.GetElementsByTagName("binding").Item(0);
167 |
168 | // Square tile
169 | var SquareTile = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150PeekImageAndText01);
170 | var tileTextAttributes = SquareTile.GetElementsByTagName("text");
171 | tileTextAttributes[0].AppendChild(SquareTile.CreateTextNode((_steps.TotalCount).ToString() + " steps"));
172 | tileTextAttributes[1].AppendChild(SquareTile.CreateTextNode(_steps.RunningCount.ToString() + " running steps"));
173 | tileTextAttributes[2].AppendChild(SquareTile.CreateTextNode(_steps.WalkingCount.ToString() + " walking steps"));
174 | var bindingSquare = (XmlElement)SquareTile.GetElementsByTagName("binding").Item(0);
175 | bindingSquare.SetAttribute("branding", "none");
176 | XmlNodeList img = SquareTile.GetElementsByTagName("image");
177 | ((XmlElement)img[0]).SetAttribute("src", "ms-appx:///Assets/Tiles/square" + smallMeterIndex + ".png");
178 |
179 | // Wide tile
180 | var wideTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150ImageAndText02);
181 | var squareTileTextAttributes = wideTileXml.GetElementsByTagName("text");
182 | squareTileTextAttributes[0].AppendChild(wideTileXml.CreateTextNode(stepCount.ToString() + " steps today"));
183 | imageAttribute = wideTileXml.GetElementsByTagName("image");
184 | ((XmlElement)imageAttribute[0]).SetAttribute("src", "ms-appx:///Assets/Tiles/wide" + meterIndex + ".png");
185 | var bindingWide = (XmlElement)wideTileXml.GetElementsByTagName("binding").Item(0);
186 | bindingWide.SetAttribute("branding", "none");
187 |
188 | var nodeWide = smallTile.ImportNode(bindingWide, true);
189 | var nodeSquare = smallTile.ImportNode(bindingSquare, true);
190 | smallTile.GetElementsByTagName("visual").Item(0).AppendChild(nodeWide);
191 | smallTile.GetElementsByTagName("visual").Item(0).AppendChild(nodeSquare);
192 | var tileNotification = new TileNotification(smallTile);
193 | var tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILE_ID);
194 | tileUpdater.Update(tileNotification);
195 | }
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/BackgroundTasks/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("BackgroundTasks")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("BackgroundTasks")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/BackgroundTasks/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/BackgroundTasks/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "LumiaSensorCoreSDKUWP": "1.2.0.127",
4 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
5 | },
6 | "frameworks": {
7 | "uap10.0": {}
8 | },
9 | "runtimes": {
10 | "win10-arm": {},
11 | "win10-arm-aot": {},
12 | "win10-x86": {},
13 | "win10-x86-aot": {},
14 | "win10-x64": {},
15 | "win10-x64-aot": {}
16 | }
17 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Steps
2 | =====
3 | Steps is a sample application demonstrating the usage of Step Counter API. In this
4 | sample application, history data is used to display a graph of user’s steps during
5 | current day, and up to 7 days in the past.
6 |
7 | Starting with Windows 10, this sample supports the Windows.Devices.Sensors.Pedometer.
8 | It checks if the Pedometer is present before falling back to using the SensorCore
9 | Step Counter.
10 |
11 |
12 | 1. Instructions
13 | --------------------------------------------------------------------------------
14 |
15 | Learn about the Lumia SensorCore SDK from the Lumia Developer's Library. The
16 | example requires the Lumia SensorCore SDK's NuGet package but will retrieve it
17 | automatically (if missing) on first build.
18 |
19 | To build the application you need to have Windows 10 and Windows 10 SDK installed.
20 |
21 | Using the Windows 10 SDK:
22 |
23 | 1. Open the SLN file: File > Open Project, select the file `Steps.sln`
24 | 2. Select ARM
25 | 3. Select the target 'Device'.
26 | 4. Press F5 to build the project and run it on the device.
27 |
28 | Alternatively you can also build the example for the emulator (x86) in which case
29 | the Steps will use simulated data. In order to use the emulator, you need to uncomment
30 | the code block in StepsEngine to use the emulator, and include Lumia.Sense.Testing.
31 |
32 | Please refer to the official SDK sample documentation for Universal Windows Platform
33 | development.
34 | https://github.com/microsoft/windows-universal-samples/
35 |
36 | 2. Implementation
37 | --------------------------------------------------------------------------------
38 |
39 | Two important functions for Steps sample in the SensorCore SDK's StepCounter class
40 | are GetCurrentReadingAsync and GetStepCountHistoryAsync. These functions are used in
41 | the sample to show graph of today's walking and running steps and current amount
42 | of the steps.
43 |
44 | GetCurrentReadingAsync returns cumulative number of steps from the last motion
45 | data reset. The sample shows the total number of steps for today so we need
46 | to get the cumulative step count reading at the beginning of the day and then
47 | subtract it from the current cumulative step count reading.
48 |
49 | The number of steps at the beginning of the day is got by calling:
50 |
51 | GetStepCountHistoryAsync(DateTime.Now.Date, DateTime.Now-DateTime.Now.Date)
52 |
53 | The function call returns step count history array for today at five minute
54 | intervals. The array has cumulative step count readings at 00:00, 00:05, 00:10...
55 | To calculate step count reading for today we subtract the step count at 00:00
56 | from the value of GetCurrentReadingAsync.
57 |
58 | To draw the graph we use the same array that the above call to GetStepCountHistoryAsync
59 | returns.
60 |
61 | 3. Version history
62 | --------------------------------------------------------------------------------
63 | * Version 2.0.0.2: Minor revision to error handling
64 | * Version 2.0.0.1: Minor revision to assets
65 | * Version 2.0.0.0: Updated to Universal Windows Platform
66 | * Version 1.1.0.3: Updated to use latest Lumia SensorCore SDK 1.1 Preview
67 | * Version 1.1.0.2:
68 | * Some bug fixes made in this release.
69 | * Version 1.1:
70 | * Step counter on live tile gets updated using triggers for background tasks.
71 | * Besides today up to 7 days of step history made available.
72 | * Update to use Lumia SensorCore SDK 1.0
73 | * Version 1.0: The first release.
74 |
75 |
76 | 4. Downloads
77 | ---------
78 |
79 | | Project | Release | Download |
80 | | ------- | --------| -------- |
81 | | Steps | v2.0.0.2 | [steps-2.0.0.2.zip](https://github.com/Microsoft/steps/archive/v2.0.0.2.zip) |
82 | | Steps | v1.1.0.3 | [steps-1.1.0.3.zip](https://github.com/Microsoft/steps/archive/v1.1.0.3.zip) |
83 | | Steps | v1.1.0.2 | [steps-1.1.0.2.zip](https://github.com/Microsoft/steps/archive/v1.1.0.2.zip) |
84 | | Steps | v1.1 | [steps-1.1.zip](https://github.com/Microsoft/steps/archive/v1.1.zip) |
85 | | Steps | v1.0 | [steps-1.0.zip](https://github.com/Microsoft/steps/archive/v1.0.zip) |
86 |
87 |
88 | 5. See also
89 | --------------------------------------------------------------------------------
90 |
91 | The projects listed below are exemplifying the usage of the SensorCore APIs
92 |
93 | * Steps - https://github.com/Microsoft/steps
94 | * Places - https://github.com/Microsoft/places
95 | * Tracks - https://github.com/Microsoft/tracks
96 | * Activities - https://github.com/Microsoft/activities
97 | * Recorder - https://github.com/Microsoft/recorder
98 |
--------------------------------------------------------------------------------
/Steps.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Steps", "Steps\Steps.csproj", "{F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackgroundTasks", "BackgroundTasks\BackgroundTasks.csproj", "{086C4C13-0C8E-4275-A196-42CD28A4E523}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|ARM = Debug|ARM
14 | Debug|x64 = Debug|x64
15 | Debug|x86 = Debug|x86
16 | Release|Any CPU = Release|Any CPU
17 | Release|ARM = Release|ARM
18 | Release|x64 = Release|x64
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|Any CPU.ActiveCfg = Debug|x86
23 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|ARM.ActiveCfg = Debug|ARM
24 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|ARM.Build.0 = Debug|ARM
25 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|ARM.Deploy.0 = Debug|ARM
26 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|x64.ActiveCfg = Debug|x64
27 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|x64.Build.0 = Debug|x64
28 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|x64.Deploy.0 = Debug|x64
29 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|x86.ActiveCfg = Debug|x86
30 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|x86.Build.0 = Debug|x86
31 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Debug|x86.Deploy.0 = Debug|x86
32 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|Any CPU.ActiveCfg = Release|x86
33 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|ARM.ActiveCfg = Release|ARM
34 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|ARM.Build.0 = Release|ARM
35 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|ARM.Deploy.0 = Release|ARM
36 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|x64.ActiveCfg = Release|x64
37 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|x64.Build.0 = Release|x64
38 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|x64.Deploy.0 = Release|x64
39 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|x86.ActiveCfg = Release|x86
40 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|x86.Build.0 = Release|x86
41 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}.Release|x86.Deploy.0 = Release|x86
42 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Debug|ARM.ActiveCfg = Debug|ARM
45 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Debug|ARM.Build.0 = Debug|ARM
46 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Debug|x64.ActiveCfg = Debug|x64
47 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Debug|x64.Build.0 = Debug|x64
48 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Debug|x86.ActiveCfg = Debug|x86
49 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Debug|x86.Build.0 = Debug|x86
50 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Release|Any CPU.Build.0 = Release|Any CPU
52 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Release|ARM.ActiveCfg = Release|ARM
53 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Release|ARM.Build.0 = Release|ARM
54 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Release|x64.ActiveCfg = Release|x64
55 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Release|x64.Build.0 = Release|x64
56 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Release|x86.ActiveCfg = Release|x86
57 | {086C4C13-0C8E-4275-A196-42CD28A4E523}.Release|x86.Build.0 = Release|x86
58 | EndGlobalSection
59 | GlobalSection(SolutionProperties) = preSolution
60 | HideSolutionNode = FALSE
61 | EndGlobalSection
62 | EndGlobal
63 |
--------------------------------------------------------------------------------
/Steps/AboutPage.xaml:
--------------------------------------------------------------------------------
1 |
13 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/Steps/AboutPage.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | * Copyright (c) 2015 Microsoft
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 |
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | using System;
22 | using System.IO;
23 | using System.Linq;
24 | using Windows.UI.Xaml;
25 | using Windows.UI.Xaml.Controls;
26 | using Windows.Storage;
27 | using System.Xml;
28 | using System.Xml.Linq;
29 |
30 | ///
31 | /// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkID=390556
32 | ///
33 | namespace Steps
34 | {
35 | ///
36 | /// An empty page that can be used on its own or navigated to within a Frame.
37 | ///
38 | public sealed partial class AboutPage : Page
39 | {
40 | ///
41 | /// Constructor
42 | ///
43 | public AboutPage()
44 | {
45 | this.InitializeComponent();
46 | Loaded += AboutPage_Loaded;
47 | }
48 |
49 | ///
50 | /// Loaded event raised after the component is initialized
51 | ///
52 | /// The sender of the event
53 | /// Event arguments
54 | async void AboutPage_Loaded(object sender, RoutedEventArgs e)
55 | {
56 | string version = "";
57 | var uri = new System.Uri("ms-appx:///AppxManifest.xml");
58 | StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
59 | using (var rastream = await file.OpenReadAsync())
60 | using (var appManifestStream = rastream.AsStreamForRead())
61 | {
62 | using (var reader = XmlReader.Create(appManifestStream, new XmlReaderSettings { IgnoreWhitespace = true, IgnoreComments = true }))
63 | {
64 | var doc = XDocument.Load(reader);
65 | var app = doc.Descendants(doc.Root.Name.Namespace + "Identity").FirstOrDefault();
66 | if (app != null)
67 | {
68 | var versionAttribute = app.Attribute("Version");
69 | if (versionAttribute != null)
70 | {
71 | version = versionAttribute.Value;
72 | }
73 | }
74 | }
75 | }
76 | VersionNumber.Text = version;
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/Steps/App.xaml:
--------------------------------------------------------------------------------
1 |
13 |
18 |
19 |
--------------------------------------------------------------------------------
/Steps/App.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | The MIT License (MIT)
3 | Copyright (c) 2015 Microsoft
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 | */
23 | using System;
24 | using Windows.ApplicationModel;
25 | using Windows.ApplicationModel.Activation;
26 | using Windows.UI.Xaml;
27 | using Windows.UI.Xaml.Controls;
28 | using Windows.UI.Xaml.Media.Animation;
29 | using Windows.UI.Xaml.Navigation;
30 |
31 | namespace Steps
32 | {
33 | ///
34 | /// Provides application-specific behavior to supplement the default Application class.
35 | ///
36 | sealed partial class App : Application
37 | {
38 | #region Public properties
39 | ///
40 | /// Step counter engine
41 | ///
42 | /// Step counter engine
43 | public static IStepsEngine Engine { get; private set; }
44 | #endregion
45 |
46 | ///
47 | /// Transition collection
48 | ///
49 | private TransitionCollection transitions;
50 |
51 | ///
52 | /// Initializes the singleton application object. This is the first line of authored code
53 | /// executed, and as such is the logical equivalent of main() or WinMain().
54 | ///
55 | public App()
56 | {
57 | this.InitializeComponent();
58 |
59 | this.Suspending += OnSuspending;
60 | }
61 |
62 | ///
63 | /// Invoked when the application is launched normally by the end user. Other entry points
64 | /// will be used when the application is launched to open a specific file, to display
65 | /// search results, and so forth.
66 | ///
67 | /// Details about the launch request and process.
68 | protected async override void OnLaunched(LaunchActivatedEventArgs e)
69 | {
70 | #if DEBUG
71 | if (System.Diagnostics.Debugger.IsAttached)
72 | {
73 | this.DebugSettings.EnableFrameRateCounter = true;
74 | }
75 | #endif
76 | Frame rootFrame = Window.Current.Content as Frame;
77 |
78 | // Instantiate the step engine
79 | Engine = await StepsEngineFactory.GetDefaultAsync();
80 |
81 | // Do not repeat app initialization when the Window already has content,
82 | // just ensure that the window is active
83 | if (rootFrame == null)
84 | {
85 | // Create a Frame to act as the navigation context and navigate to the first page
86 | rootFrame = new Frame();
87 | rootFrame.CacheSize = 1;
88 |
89 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
90 | {
91 | }
92 |
93 | // Place the frame in the current Window
94 | Window.Current.Content = rootFrame;
95 | }
96 |
97 | if (rootFrame.Content == null)
98 | {
99 | // Removes the turnstile navigation for startup.
100 | if (rootFrame.ContentTransitions != null)
101 | {
102 | this.transitions = new TransitionCollection();
103 | foreach (var c in rootFrame.ContentTransitions)
104 | {
105 | this.transitions.Add(c);
106 | }
107 | }
108 |
109 | rootFrame.ContentTransitions = null;
110 | rootFrame.Navigated += this.RootFrame_FirstNavigated;
111 |
112 | // When the navigation stack isn't restored navigate to the first page,
113 | // configuring the new page by passing required information as a navigation
114 | // parameter
115 | if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
116 | {
117 | throw new Exception("Failed to create initial page");
118 | }
119 | }
120 |
121 | // Ensure the current window is active
122 | Window.Current.Activate();
123 | }
124 |
125 | ///
126 | /// Handles the back button press and navigates through the history of the root frame.
127 | ///
128 | /// The source of the event.
129 | /// Details about the back button press.
130 | private void HardwareButtons_BackPressed(object sender, Windows.UI.Core.BackRequestedEventArgs e)
131 | {
132 | Frame frame = Window.Current.Content as Frame;
133 | if (frame == null)
134 | {
135 | return;
136 | }
137 | if (frame.CanGoBack)
138 | {
139 | frame.GoBack();
140 | e.Handled = true;
141 | }
142 | }
143 |
144 | ///
145 | /// Restores the content transitions after the app has launched.
146 | ///
147 | /// The object where the handler is attached.
148 | /// Details about the navigation event.
149 | private void RootFrame_FirstNavigated(object sender, NavigationEventArgs e)
150 | {
151 | var rootFrame = sender as Frame;
152 | rootFrame.ContentTransitions = this.transitions ?? new TransitionCollection() { new NavigationThemeTransition() };
153 | rootFrame.Navigated -= this.RootFrame_FirstNavigated;
154 | Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += HardwareButtons_BackPressed;
155 | }
156 |
157 | ///
158 | /// Invoked when application execution is being suspended. Application state is saved
159 | /// without knowing whether the application will be terminated or resumed with the contents
160 | /// of memory still intact.
161 | ///
162 | /// The source of the suspend request.
163 | /// Details about the suspend request.
164 | private void OnSuspending(object sender, SuspendingEventArgs e)
165 | {
166 | var deferral = e.SuspendingOperation.GetDeferral();
167 | //Save application state and stop any background activity
168 | deferral.Complete();
169 | }
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/Steps/Assets/BadgeLogo.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/BadgeLogo.scale-240.png
--------------------------------------------------------------------------------
/Steps/Assets/Images/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Images/back.png
--------------------------------------------------------------------------------
/Steps/Assets/Images/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Images/next.png
--------------------------------------------------------------------------------
/Steps/Assets/Images/pin-48px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Images/pin-48px.png
--------------------------------------------------------------------------------
/Steps/Assets/Images/pushpin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Images/pushpin.png
--------------------------------------------------------------------------------
/Steps/Assets/Images/unpin-48px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Images/unpin-48px.png
--------------------------------------------------------------------------------
/Steps/Assets/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Logo.png
--------------------------------------------------------------------------------
/Steps/Assets/SplashScreen.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/SplashScreen.scale-240.png
--------------------------------------------------------------------------------
/Steps/Assets/Square44x44Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Square44x44Logo.png
--------------------------------------------------------------------------------
/Steps/Assets/Square44x44Logo.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Square44x44Logo.scale-240.png
--------------------------------------------------------------------------------
/Steps/Assets/SquareTile150x150.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/SquareTile150x150.scale-240.png
--------------------------------------------------------------------------------
/Steps/Assets/SquareTile71x71.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/SquareTile71x71.scale-240.png
--------------------------------------------------------------------------------
/Steps/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/150x150.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/30x30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/30x30.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/IconicTileMediumLarge - Copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/IconicTileMediumLarge - Copy.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/IconicTileMediumLarge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/IconicTileMediumLarge.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/IconicTileSmall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/IconicTileSmall.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/small_square0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/small_square0.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/small_square1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/small_square1.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/small_square2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/small_square2.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/small_square3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/small_square3.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/square.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/square0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/square0.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/square1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/square1.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/square2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/square2.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/square3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/square3.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide0.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide1.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide2.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide3.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide4.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide5.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide6.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide7.png
--------------------------------------------------------------------------------
/Steps/Assets/Tiles/wide8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/Tiles/wide8.png
--------------------------------------------------------------------------------
/Steps/Assets/WideLogo.scale-240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/WideLogo.scale-240.png
--------------------------------------------------------------------------------
/Steps/Assets/steps_background_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/steps_background_02.png
--------------------------------------------------------------------------------
/Steps/Assets/steps_background_02_620x300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/steps_background_02_620x300.png
--------------------------------------------------------------------------------
/Steps/Assets/steps_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/steps_launcher.png
--------------------------------------------------------------------------------
/Steps/Assets/steps_launcher150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/steps_launcher150x150.png
--------------------------------------------------------------------------------
/Steps/Assets/steps_launcher310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/steps/7e50b2ca6c64054363a5874f5a1b499df7e93124/Steps/Assets/steps_launcher310x150.png
--------------------------------------------------------------------------------
/Steps/DataConverter.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | * Copyright (c) 2015 Microsoft
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 |
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | using System;
22 | using Windows.UI.Xaml.Data;
23 |
24 | namespace Steps
25 | {
26 | ///
27 | /// Returns the half value of the step graph
28 | ///
29 | public class Half : IValueConverter
30 | {
31 | ///
32 | /// Converts a value.
33 | ///
34 | /// The value produced by the binding source.
35 | /// The type of the binding target property.
36 | /// The converter parameter to use.
37 | /// The language of the conversion.
38 | /// A converted value. If the method returns null, the valid null value is used.
39 | public object Convert( object value, Type targetType, object parameter, string language )
40 | {
41 | return (double)value / 2;
42 | }
43 |
44 | ///
45 | /// Converts back to the initial value.
46 | ///
47 | /// The value that is produced by the binding target.
48 | /// The type to convert to.
49 | /// The converter parameter to use.
50 | /// The language of the conversion.
51 | /// A converted value. If the method returns null, the valid null value is used.
52 | public object ConvertBack( object value, Type targetType, object parameter, string language )
53 | {
54 | return "";
55 | }
56 | }
57 |
58 | ///
59 | /// Returns the margin o the step graph.
60 | ///
61 | public class Margin : IValueConverter
62 | {
63 | ///
64 | /// Converts a value.
65 | ///
66 | /// The value produced by the binding source.
67 | /// The type of the binding target property.
68 | /// The converter parameter to use.
69 | /// The language of the conversion.
70 | /// A converted value. If the method returns null, the valid null value is used.
71 | public object Convert( object value, Type targetType, object parameter, string language )
72 | {
73 | return (double)value - 6;
74 | }
75 |
76 | ///
77 | /// Converts back to the initial value.
78 | ///
79 | /// The value that is produced by the binding target.
80 | /// The type to convert to.
81 | /// The converter parameter to use.
82 | /// The language of the conversion.
83 | /// A converted value. If the method returns null, the valid null value is used.
84 | public object ConvertBack( object value, Type targetType, object parameter, string language )
85 | {
86 | return "";
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Steps/DataModels/MainModel.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | * Copyright (c) 2015 Microsoft
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 |
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | using System;
22 | using System.Collections.Generic;
23 | using System.ComponentModel;
24 | using System.Globalization;
25 | using System.Runtime.CompilerServices;
26 | using System.Threading.Tasks;
27 |
28 | namespace Steps
29 | {
30 | ///
31 | /// Main model used in the application
32 | ///
33 | public class MainModel : INotifyPropertyChanged
34 | {
35 | #region Constants
36 | ///
37 | /// Resolution of the graph in minutes
38 | ///
39 | /// Minimum resolution is five minutes
40 | private const int GRAPH_RESOLUTION = 30;
41 |
42 | ///
43 | /// Zoom scales (maximum number of steps to show in graph)
44 | ///
45 | private readonly List ZOOM_SCALES_STEPS = new List() { 5000, 10000, 20000 };
46 |
47 | ///
48 | /// Graph canvas margin in pixels
49 | ///
50 | private const int GRAPH_MARGIN_X = 6;
51 | #endregion
52 |
53 | #region Events
54 | ///
55 | /// Property changed event.
56 | ///
57 | public event PropertyChangedEventHandler PropertyChanged;
58 | #endregion
59 |
60 | #region Private members
61 | ///
62 | /// Day offset to today, i.e. 0 = today, 1 = yesterday etc.
63 | ///
64 | private uint _dayOffset;
65 |
66 | ///
67 | /// Walking steps count for selected day
68 | ///
69 | private uint _walkingSteps = 0;
70 |
71 | ///
72 | /// Running steps count for selected day
73 | ///
74 | private uint _runningSteps = 0;
75 |
76 | ///
77 | /// Width of graph canvas in pixels
78 | ///
79 | private double _width;
80 |
81 | ///
82 | /// Height of graph canvas in pixels
83 | ///
84 | private double _height;
85 |
86 | ///
87 | /// Current zoom level
88 | ///
89 | private int _zoomIndex = 0;
90 |
91 | ///
92 | /// Collection of steps for currently selected day
93 | ///
94 | private List> _steps = new List>();
95 | #endregion
96 |
97 | ///
98 | /// Day offset to today, i.e. 0 = today, 1 = yesterday etc.
99 | ///
100 | public uint DayOffset
101 | {
102 | get
103 | {
104 | return _dayOffset;
105 | }
106 | set
107 | {
108 | _dayOffset = value;
109 | NotifyPropertyChanged("DateString");
110 | NotifyPropertyChanged("DayOffset");
111 | }
112 | }
113 |
114 | ///
115 | /// Gets maximum steps range for graph
116 | ///
117 | public string ScaleMax { get { return ZOOM_SCALES_STEPS[_zoomIndex].ToString(); } }
118 |
119 | ///
120 | /// Gets half steps range for graph
121 | ///
122 | public string ScaleHalf { get { return (ZOOM_SCALES_STEPS[_zoomIndex] / 2).ToString(); } }
123 |
124 | ///
125 | /// Gets margin of the step graph
126 | ///
127 | public string GraphMarginX { get { return (GRAPH_MARGIN_X).ToString(); } }
128 |
129 | ///
130 | /// Get the date for the graph
131 | ///
132 | public string DateString
133 | {
134 | get
135 | {
136 | CultureInfo ci = new CultureInfo("en-GB");
137 | string format = "D";
138 | if (DayOffset == 0)
139 | {
140 | return "Today";
141 | }
142 | else if (DayOffset == 1)
143 | {
144 | return "Yesterday";
145 | }
146 | else
147 | {
148 | DateTime time = DateTime.Now - TimeSpan.FromDays(DayOffset);
149 | return time.ToString(format, ci);
150 | }
151 | }
152 | }
153 |
154 | ///
155 | /// Number of walking steps for the day
156 | ///
157 | public uint TotalWalkingSteps
158 | {
159 | get
160 | {
161 | return _walkingSteps;
162 | }
163 | set
164 | {
165 | if (value != _walkingSteps)
166 | {
167 | _walkingSteps = value;
168 | NotifyPropertyChanged("TotalWalkingSteps");
169 | NotifyPropertyChanged("TotalSteps");
170 | }
171 | }
172 | }
173 |
174 | ///
175 | /// Number of running steps for the day
176 | ///
177 | public uint TotalRunningSteps
178 | {
179 | get
180 | {
181 | return _runningSteps;
182 | }
183 | set
184 | {
185 | if (value != _runningSteps)
186 | {
187 | _runningSteps = value;
188 | NotifyPropertyChanged("TotalRunningSteps");
189 | NotifyPropertyChanged("TotalSteps");
190 | }
191 | }
192 | }
193 |
194 | ///
195 | /// Total number of steps for the day
196 | ///
197 | public uint TotalSteps
198 | {
199 | get
200 | {
201 | return _walkingSteps + _runningSteps;
202 | }
203 | }
204 |
205 | ///
206 | /// This property makes canvas path that is displayed to the user.
207 | /// For instance string could look like "M 6,255 L 10,255 L 14,255 L 18,255 L 23,255...
208 | /// where M 6, 255 is a start point for path ( 6 pixels from left, 255 pixels down)
209 | /// L 10, 255 line that goes 4 pixels to right from previous point
210 | /// More details here: http://msdn.microsoft.com/en-us/library/ms752293(v=vs.110).aspx
211 | ///
212 | public string PathString
213 | {
214 | get
215 | {
216 | if (_steps == null) return "";
217 | String path = "";
218 | if (_steps.Count > 1)
219 | {
220 | double xOffs = GRAPH_MARGIN_X + ((_width - 2 * GRAPH_MARGIN_X) * _steps[0].Key.TotalMinutes) / (24 * 60);
221 | double yOffs = (_height - (Math.Min(ZOOM_SCALES_STEPS[_zoomIndex], _steps[0].Value) * _height / ZOOM_SCALES_STEPS[_zoomIndex]));
222 | path = "M " + (uint)xOffs + "," + (uint)yOffs;
223 | foreach (var item in _steps)
224 | {
225 | uint stepcount = Math.Min(ZOOM_SCALES_STEPS[_zoomIndex], item.Value);
226 | xOffs = GRAPH_MARGIN_X + ((_width - 2 * GRAPH_MARGIN_X) * item.Key.TotalMinutes) / (24 * 60);
227 | yOffs = _height - (stepcount * _height / ZOOM_SCALES_STEPS[_zoomIndex]);
228 | path += " L " + (uint)xOffs + "," + (uint)yOffs;
229 | }
230 | }
231 | return path;
232 | }
233 | }
234 |
235 | ///
236 | /// Increases day offset
237 | ///
238 | /// Asynchronous task
239 | public async Task IncreaseDayOffsetAsync()
240 | {
241 | if (DayOffset < 6)
242 | {
243 | DayOffset++;
244 | await UpdateAsync();
245 | }
246 | }
247 |
248 | ///
249 | /// Decreases day offset
250 | ///
251 | /// Asynchronous task
252 | public async Task DecreaseDayOffsetAsync()
253 | {
254 | if (DayOffset != 0)
255 | {
256 | DayOffset--;
257 | await UpdateAsync();
258 | }
259 | }
260 |
261 | ///
262 | /// Updates model
263 | ///
264 | /// Asynchronous task
265 | public async Task UpdateAsync()
266 | {
267 | _steps = null;
268 | try
269 | {
270 | var stepCount = await App.Engine.GetTotalStepCountAsync(DateTime.Today - TimeSpan.FromDays(DayOffset));
271 | TotalRunningSteps = stepCount.RunningCount;
272 | TotalWalkingSteps = stepCount.WalkingCount;
273 |
274 | _steps = await App.Engine.GetStepsCountsForDay(DateTime.Today - TimeSpan.FromDays(DayOffset), GRAPH_RESOLUTION);
275 | NotifyPropertyChanged("");
276 | }
277 | catch (Exception)
278 | {
279 | TotalRunningSteps = 0;
280 | TotalWalkingSteps = 0;
281 | NotifyPropertyChanged("");
282 | }
283 | }
284 |
285 | ///
286 | /// Sets graph dimensions
287 | ///
288 | /// Width of graph canvas in pixels
289 | /// Height of graph canvas in pixels
290 | public void SetDimensions(double width, double height)
291 | {
292 | _width = width;
293 | _height = height;
294 | NotifyPropertyChanged("");
295 | }
296 |
297 | ///
298 | /// Cycles zoom level
299 | ///
300 | public void CycleZoomLevel()
301 | {
302 | _zoomIndex = (_zoomIndex + 1) % ZOOM_SCALES_STEPS.Count;
303 | NotifyPropertyChanged("");
304 | }
305 |
306 | ///
307 | /// Executes when a property has changed
308 | ///
309 | /// Property which will be changed
310 | private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
311 | {
312 | if (PropertyChanged != null)
313 | {
314 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
315 | }
316 | }
317 | }
318 | }
319 |
--------------------------------------------------------------------------------
/Steps/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
13 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/Steps/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | * Copyright (c) 2015 Microsoft
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 |
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | using System;
22 | using System.Threading;
23 | using System.Threading.Tasks;
24 | using Windows.ApplicationModel.Background;
25 | using Windows.ApplicationModel.Resources;
26 | using Windows.UI;
27 | using Windows.UI.StartScreen;
28 | using Windows.UI.Xaml;
29 | using Windows.UI.Xaml.Controls;
30 | using Windows.UI.Xaml.Input;
31 | using Windows.UI.Xaml.Navigation;
32 | using Lumia.Sense;
33 |
34 | namespace Steps
35 | {
36 | public sealed partial class MainPage : Page
37 | {
38 | #region Private constants
39 | ///
40 | /// Tile ID
41 | ///
42 | private const string TILE_ID = "SecondaryTile.Steps";
43 |
44 | ///
45 | /// Target daily step count
46 | ///
47 | private const uint TARGET_STEPS = 10000;
48 |
49 | ///
50 | /// Number of large meter images
51 | ///
52 | private const uint NUM_LARGE_METER_IMAGES = 9;
53 |
54 | ///
55 | /// Number of small meter images
56 | ///
57 | private const uint NUM_SMALL_METER_IMAGES = 4;
58 | #endregion
59 |
60 | #region Private members
61 | ///
62 | /// Model for the app
63 | ///
64 | private MainModel _model = null;
65 |
66 | ///
67 | /// Synchronization object
68 | ///
69 | private SemaphoreSlim _sync = new SemaphoreSlim(1);
70 |
71 | ///
72 | /// Timer to update step counts periodically
73 | ///
74 | private DispatcherTimer _pollTimer;
75 |
76 | ///
77 | /// Loads resources dynamically
78 | ///
79 | private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView("Resources");
80 |
81 | #endregion
82 |
83 | public MainPage()
84 | {
85 | this.InitializeComponent();
86 |
87 | _model = new MainModel();
88 | LayoutRoot.DataContext = _model;
89 | StepGraph.Loaded += StepGraph_Loaded;
90 | }
91 |
92 | #region NavigationHelper registration
93 | ///
94 | /// Called when a page is no longer the active page in a frame.
95 | ///
96 | /// Provides data for non-cancelable navigation events
97 | protected async override void OnNavigatedFrom(NavigationEventArgs e)
98 | {
99 | if (_pollTimer != null)
100 | {
101 | _pollTimer.Stop();
102 | _pollTimer = null;
103 | }
104 | await App.Engine.DeactivateAsync();
105 | }
106 |
107 | ///
108 | /// Called when navigating to this page
109 | ///
110 | /// Event arguments
111 | protected async override void OnNavigatedTo(NavigationEventArgs e)
112 | {
113 | await App.Engine.ActivateAsync();
114 |
115 | UpdateMenuAndAppBarIcons();
116 |
117 | await _sync.WaitAsync();
118 | try
119 | {
120 | await _model.UpdateAsync();
121 | }
122 | finally
123 | {
124 | _sync.Release();
125 | }
126 |
127 | // Start poll timer to update steps counts periodically
128 | if (_pollTimer == null)
129 | {
130 | _pollTimer = new DispatcherTimer();
131 | _pollTimer.Interval = TimeSpan.FromSeconds(5);
132 | _pollTimer.Tick += PollTimerTick;
133 | _pollTimer.Start();
134 | }
135 | }
136 |
137 | #endregion
138 |
139 | ///
140 | /// Step counter poll timer callback
141 | ///
142 | /// Sender object
143 | /// Event arguments
144 | private async void PollTimerTick(object sender, object e)
145 | {
146 | await _sync.WaitAsync();
147 | try
148 | {
149 | // No need to update if we are not looking at today
150 | if (_model.DayOffset == 0)
151 | {
152 | await _model.UpdateAsync();
153 | }
154 | }
155 | finally
156 | {
157 | _sync.Release();
158 | }
159 | }
160 |
161 | ///
162 | /// Executes when the Step graph finished loading.
163 | ///
164 | /// Sender object
165 | /// Event arguments
166 | private void StepGraph_Loaded(object sender, RoutedEventArgs e)
167 | {
168 | _model.SetDimensions(StepGraph.ActualWidth, StepGraph.ActualHeight);
169 | }
170 |
171 | ///
172 | /// Step graph tap event handler
173 | ///
174 | /// Sender object
175 | /// Event arguments
176 | private void StepGraph_Tapped(object sender, TappedRoutedEventArgs e)
177 | {
178 | _model.CycleZoomLevel();
179 | }
180 |
181 | ///
182 | /// Decrease opacity of the command bar when closed
183 | ///
184 | /// The sender of the event
185 | /// Event arguments
186 | private void CommandBar_Closed(object sender, object e)
187 | {
188 | cmdBar.Opacity = 0.5;
189 | }
190 |
191 | ///
192 | /// Increase opacity of command bar when opened
193 | ///
194 | /// The sender of the event
195 | /// Event arguments
196 | private void CommandBar_Opened(object sender, object e)
197 | {
198 | cmdBar.Opacity = 1;
199 | }
200 |
201 | ///
202 | /// About menu item click event handler
203 | ///
204 | /// Sender object
205 | /// Event arguments
206 | private void AboutButton_Click(object sender, RoutedEventArgs e)
207 | {
208 | this.Frame.Navigate(typeof(AboutPage));
209 | }
210 |
211 | ///
212 | /// Removes background task
213 | ///
214 | /// Name of task to be removed
215 | /// Asynchronous task
216 | private async static Task RemoveBackgroundTaskAsync(string taskName)
217 | {
218 | BackgroundAccessStatus result = await BackgroundExecutionManager.RequestAccessAsync();
219 | if (result != BackgroundAccessStatus.Denied)
220 | {
221 | // Remove previous registration
222 | foreach (var task in BackgroundTaskRegistration.AllTasks)
223 | {
224 | if (task.Value.Name == taskName)
225 | {
226 | task.Value.Unregister(true);
227 | }
228 | }
229 | }
230 | }
231 |
232 | ///
233 | /// Registers background task
234 | ///
235 | /// Task trigger
236 | /// Task name
237 | /// Task entry point
238 | /// Asynchronous task
239 | private async static Task RegisterBackgroundTaskAsync(IBackgroundTrigger trigger, String taskName, String taskEntryPoint)
240 | {
241 | BackgroundAccessStatus result = await BackgroundExecutionManager.RequestAccessAsync();
242 | if (result != BackgroundAccessStatus.Denied)
243 | {
244 | await RemoveBackgroundTaskAsync(taskName);
245 |
246 | // Register task
247 | BackgroundTaskBuilder myTaskBuilder = new BackgroundTaskBuilder();
248 | myTaskBuilder.SetTrigger(trigger);
249 | myTaskBuilder.TaskEntryPoint = taskEntryPoint;
250 | myTaskBuilder.Name = taskName;
251 | BackgroundTaskRegistration myTask = myTaskBuilder.Register();
252 | }
253 | }
254 |
255 | ///
256 | /// Creates or removes a secondary tile
257 | ///
258 | /// true to remove tile, false to create tile
259 | /// Asynchronous task
260 | private async Task CreateOrRemoveTileAsync(bool removeTile)
261 | {
262 | if (!removeTile)
263 | {
264 | var steps = await App.Engine.GetTotalStepCountAsync(DateTime.Now.Date);
265 | uint stepCount = steps.TotalCount;
266 | uint meter = (NUM_SMALL_METER_IMAGES - 1) * Math.Min(stepCount, TARGET_STEPS) / TARGET_STEPS;
267 | uint meterSmall = (NUM_LARGE_METER_IMAGES - 1) * Math.Min(stepCount, TARGET_STEPS) / TARGET_STEPS;
268 | try
269 | {
270 | var secondaryTile = new SecondaryTile(TILE_ID, "Steps", "/MainPage.xaml", new Uri("ms-appx:///Assets/Tiles/square" + meterSmall + ".png", UriKind.Absolute), TileSize.Square150x150);
271 | secondaryTile.VisualElements.Square71x71Logo = new Uri("ms-appx:///Assets/Tiles/small_square" + meterSmall + ".png", UriKind.Absolute);
272 | secondaryTile.VisualElements.ShowNameOnSquare150x150Logo = true;
273 | secondaryTile.VisualElements.ShowNameOnSquare310x310Logo = false;
274 | secondaryTile.VisualElements.ShowNameOnWide310x150Logo = false;
275 | secondaryTile.VisualElements.BackgroundColor = Color.FromArgb(255, 0, 138, 0);
276 | secondaryTile.VisualElements.Wide310x150Logo = new Uri("ms-appx:///Assets/Tiles/wide" + meter + ".png", UriKind.Absolute);
277 | secondaryTile.RoamingEnabled = false;
278 | await secondaryTile.RequestCreateAsync();
279 | }
280 | catch (Exception)
281 | {
282 | }
283 | }
284 | else
285 | {
286 | SecondaryTile secondaryTile = new SecondaryTile(TILE_ID);
287 | await secondaryTile.RequestDeleteAsync();
288 | UpdateMenuAndAppBarIcons();
289 | }
290 | }
291 |
292 | ///
293 | /// Updates menu and app bar icons
294 | ///
295 | private void UpdateMenuAndAppBarIcons()
296 | {
297 | // Show unpin or pin button
298 | if (!SecondaryTile.Exists(TILE_ID))
299 | {
300 | var icon = new BitmapIcon();
301 | icon.UriSource = new Uri("ms-appx:///Assets/Images/pin-48px.png", UriKind.Absolute);
302 | pinButton.Icon = icon;
303 | pinButton.Label = _resourceLoader.GetString("PinButton/Label");
304 | }
305 | else
306 | {
307 | var icon = new BitmapIcon();
308 | icon.UriSource = new Uri("ms-appx:///Assets/Images/unpin-48px.png", UriKind.Absolute);
309 | pinButton.Icon = icon;
310 | pinButton.Label = _resourceLoader.GetString("UnpinLabel");
311 | }
312 |
313 | backButton.IsEnabled = _model.DayOffset != 6;
314 | nextButton.IsEnabled = _model.DayOffset != 0;
315 | }
316 |
317 | ///
318 | /// Creates secondary tile if it is not yet created or removes the tile if it already exists.
319 | ///
320 | /// Sender object
321 | /// Event arguments
322 | private async void ApplicationBar_PinTile(object sender, RoutedEventArgs e)
323 | {
324 | bool removeTile = SecondaryTile.Exists(TILE_ID);
325 | if (removeTile)
326 | {
327 | await RemoveBackgroundTaskAsync("StepTriggered");
328 | }
329 | else
330 | {
331 | ApiSupportedCapabilities caps = await SenseHelper.GetSupportedCapabilitiesAsync();
332 | // Use StepCounterUpdate to trigger live tile update if it is supported. Otherwise we use time trigger
333 | if (caps.StepCounterTrigger)
334 | {
335 | var myTrigger = new DeviceManufacturerNotificationTrigger(SenseTrigger.StepCounterUpdate, false);
336 | await RegisterBackgroundTaskAsync(myTrigger, "StepTriggered", "BackgroundTasks.StepTriggerTask");
337 | }
338 | else
339 | {
340 | BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();
341 | IBackgroundTrigger trigger = new TimeTrigger(15, false);
342 | await RegisterBackgroundTaskAsync(trigger, "StepTriggered", "BackgroundTasks.StepTriggerTask");
343 | }
344 | }
345 | await CreateOrRemoveTileAsync(removeTile);
346 | }
347 |
348 | ///
349 | /// Next day button click event handler
350 | ///
351 | /// Sender object
352 | /// Event arguments
353 | private async void ApplicationBarIconButtonNext_Click(object sender, RoutedEventArgs e)
354 | {
355 | await _sync.WaitAsync();
356 | try
357 | {
358 | await _model.DecreaseDayOffsetAsync();
359 | UpdateMenuAndAppBarIcons();
360 | }
361 | finally
362 | {
363 | _sync.Release();
364 | }
365 | }
366 |
367 | ///
368 | /// Previous day button click event handler
369 | ///
370 | /// Sender object
371 | /// Event arguments
372 | private async void ApplicationBarIconButtonBack_Click(object sender, RoutedEventArgs e)
373 | {
374 | await _sync.WaitAsync();
375 | try
376 | {
377 | await _model.IncreaseDayOffsetAsync();
378 | UpdateMenuAndAppBarIcons();
379 | }
380 | finally
381 | {
382 | _sync.Release();
383 | }
384 | }
385 | }
386 | }
387 |
--------------------------------------------------------------------------------
/Steps/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Steps - Microsoft SensorCore SDK sample
7 | Sensors QA
8 | Assets\StoreLogo.png
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Steps/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Steps")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Steps")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/Steps/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Steps/Simulations/short walk.txt:
--------------------------------------------------------------------------------
1 | { " D a t a P o l l H i s t o r y " : [ ] , " C u r r e n t R e a d i n g H i s t o r y " : [ { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 5 1 1 5 5 1 0 9 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 5 3 1 4 7 1 7 6 4 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 5 5 1 5 0 7 2 0 0 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 5 7 1 3 5 7 1 1 1 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 5 9 1 7 1 7 2 3 7 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 6 1 1 7 5 6 0 0 1 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 6 3 1 8 0 5 4 2 9 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 6 5 1 8 4 2 0 1 1 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 6 7 1 7 9 1 9 8 8 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 6 9 2 0 5 1 2 5 3 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 7 1 2 1 0 2 3 3 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 7 3 2 1 4 9 1 7 9 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 7 5 2 1 6 6 2 5 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 7 7 2 2 2 4 9 9 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 7 9 2 4 9 6 6 9 3 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 8 1 2 5 4 3 5 2 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 2 4 " , " W a l k T i m e " : " 1 6 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 8 3 2 5 7 9 1 9 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 4 4 " , " W a l k T i m e " : " 2 7 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 8 5 2 5 7 1 6 6 4 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 4 8 " , " W a l k T i m e " : " 2 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 8 7 2 5 9 1 3 0 7 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 5 1 " , " W a l k T i m e " : " 3 1 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 8 9 2 5 2 0 1 3 2 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 5 5 " , " W a l k T i m e " : " 3 3 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 9 1 2 5 5 0 9 0 2 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 5 8 " , " W a l k T i m e " : " 3 5 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 9 3 2 5 7 1 3 7 0 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 6 1 " , " W a l k T i m e " : " 3 7 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 9 5 2 5 6 0 8 4 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 6 5 " , " W a l k T i m e " : " 3 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 9 7 2 5 7 6 1 2 7 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 6 8 " , " W a l k T i m e " : " 4 1 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 1 9 9 2 5 7 0 3 5 9 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 7 1 " , " W a l k T i m e " : " 4 3 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 0 1 2 5 7 5 9 9 9 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 7 4 " , " W a l k T i m e " : " 4 5 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 0 3 2 5 7 6 1 7 4 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 7 8 " , " W a l k T i m e " : " 4 7 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 0 5 1 2 8 4 0 2 1 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 8 1 " , " W a l k T i m e " : " 4 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 0 7 1 5 5 9 9 4 8 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 8 4 " , " W a l k T i m e " : " 5 1 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 0 9 1 5 9 7 8 7 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 8 7 " , " W a l k T i m e " : " 5 3 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 1 1 1 6 3 9 3 5 1 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 9 1 " , " W a l k T i m e " : " 5 5 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 1 3 1 6 7 8 7 4 8 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 9 4 " , " W a l k T i m e " : " 5 7 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 1 5 1 7 1 6 9 6 8 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 9 7 " , " W a l k T i m e " : " 5 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 1 7 1 7 5 7 4 0 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 0 0 " , " W a l k T i m e " : " 6 1 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 1 9 1 5 7 8 9 3 7 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 0 3 " , " W a l k T i m e " : " 6 3 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 2 1 1 9 3 3 0 1 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 0 6 " , " W a l k T i m e " : " 6 5 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 2 3 2 0 9 5 7 1 8 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 0 9 " , " W a l k T i m e " : " 6 7 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 2 5 1 5 0 4 2 3 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 2 7 1 6 7 4 6 9 3 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 2 9 1 7 5 4 1 3 4 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 3 1 1 0 6 6 6 1 4 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 3 3 1 0 8 2 3 3 1 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 3 5 1 0 8 0 6 0 8 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 3 7 2 5 1 9 3 7 8 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 3 9 1 1 6 7 4 1 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 4 1 2 0 3 6 5 3 4 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 4 3 2 1 4 8 6 2 1 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 4 5 2 5 1 9 3 4 9 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 4 7 1 2 6 9 2 8 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 4 9 2 5 7 2 6 0 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 5 1 2 0 3 6 5 1 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 5 3 2 5 7 2 7 4 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 5 5 2 5 1 9 3 6 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 5 7 2 5 7 1 8 3 3 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 5 9 2 5 7 6 2 6 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 6 1 2 0 3 6 5 2 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 6 3 1 2 6 0 4 0 0 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 6 5 1 7 1 4 2 4 7 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 6 7 2 5 7 3 8 4 9 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 6 9 2 5 7 4 8 6 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 7 1 2 0 3 6 7 6 6 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 7 3 2 5 7 3 9 6 7 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 7 5 1 7 2 4 4 1 9 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 7 7 2 5 7 5 5 6 3 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 7 9 2 5 7 4 3 5 7 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 8 1 2 1 9 5 2 2 3 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 8 3 2 5 1 9 3 1 5 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } , { " T i m e s t a m p " : " 1 3 0 3 8 8 9 9 2 8 5 2 5 1 9 2 9 1 " , " R u n S t e p s " : " 0 " , " R u n T i m e " : " 0 " , " W a l k S t e p s " : " 1 1 3 " , " W a l k T i m e " : " 6 9 0 0 0 0 0 0 0 " } ] , " R e c o r d i n g I n f o " : { " V e r s i o n " : " 1 0 0 0 " , " T y p e " : " 1 " , " D e s c r i p t i o n " : " " , " S t a r t " : " 1 3 0 3 8 8 9 9 1 4 9 0 9 4 6 6 3 1 " , " L e n g t h " : " 1 3 6 8 0 6 6 9 9 0 " } }
--------------------------------------------------------------------------------
/Steps/Steps.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x86
7 | {F5356085-5ED1-4855-BBCD-3A4E8F9A1B0A}
8 | AppContainerExe
9 | Properties
10 | Steps
11 | Steps
12 | en-US
13 | UAP
14 | 10.0.10586.0
15 | 10.0.10240.0
16 | 14
17 | true
18 | 512
19 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
20 | False
21 | Always
22 | arm
23 |
24 |
25 | true
26 | bin\ARM\Debug\
27 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
28 | ;2008
29 | full
30 | ARM
31 | false
32 | prompt
33 | true
34 |
35 |
36 | bin\ARM\Release\
37 | TRACE;NETFX_CORE;WINDOWS_UWP
38 | true
39 | ;2008
40 | pdbonly
41 | ARM
42 | false
43 | prompt
44 | true
45 | true
46 |
47 |
48 | true
49 | bin\x64\Debug\
50 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
51 | ;2008
52 | full
53 | x64
54 | false
55 | prompt
56 | true
57 |
58 |
59 | bin\x64\Release\
60 | TRACE;NETFX_CORE;WINDOWS_UWP
61 | true
62 | ;2008
63 | pdbonly
64 | x64
65 | false
66 | prompt
67 | true
68 | true
69 |
70 |
71 | true
72 | bin\x86\Debug\
73 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
74 | ;2008
75 | full
76 | x86
77 | false
78 | prompt
79 | true
80 |
81 |
82 | bin\x86\Release\
83 | TRACE;NETFX_CORE;WINDOWS_UWP
84 | true
85 | ;2008
86 | pdbonly
87 | x86
88 | false
89 | prompt
90 | true
91 | true
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | AboutPage.xaml
102 |
103 |
104 | App.xaml
105 |
106 |
107 |
108 |
109 | MainPage.xaml
110 |
111 |
112 |
113 |
114 |
115 |
116 | Designer
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | MSBuild:Compile
131 | Designer
132 |
133 |
134 | Designer
135 | MSBuild:Compile
136 |
137 |
138 | MSBuild:Compile
139 | Designer
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | PreserveNewest
173 |
174 |
175 | PreserveNewest
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 | {086c4c13-0c8e-4275-a196-42cd28a4e523}
184 | BackgroundTasks
185 |
186 |
187 |
188 | 14.0
189 |
190 |
191 |
198 |
199 |
--------------------------------------------------------------------------------
/Steps/StepsEngine.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | * Copyright (c) 2015 Microsoft
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 |
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | using System;
22 | using System.Collections.Generic;
23 | using System.Threading.Tasks;
24 | using Windows.ApplicationModel.Resources;
25 | using Windows.Devices.Sensors;
26 | using Windows.Security.ExchangeActiveSyncProvisioning;
27 | using Windows.UI.Popups;
28 | using Windows.UI.Xaml;
29 | using Lumia.Sense;
30 |
31 | using BackgroundTasks.Converters;
32 |
33 | namespace Steps
34 | {
35 | ///
36 | /// Platform agnostic Steps Engine interface
37 | /// This interface is implementd by OSStepsEngine and LumiaStepsEngine.
38 | ///
39 | public interface IStepsEngine
40 | {
41 | ///
42 | /// Activates the step counter
43 | ///
44 | /// Asynchronous task
45 | Task ActivateAsync();
46 |
47 | ///
48 | /// Deactivates the step counter
49 | ///
50 | /// Asynchronous task
51 | Task DeactivateAsync();
52 |
53 | ///
54 | /// Returns steps for given day at given resolution
55 | ///
56 | /// Day to fetch data for
57 | /// Resolution in minutes. Minimum resolution is five minutes.
58 | /// List of steps counts for the given day at given resolution.
59 | Task>> GetStepsCountsForDay(DateTime day, uint resolution);
60 |
61 | ///
62 | /// Returns step count for given day
63 | ///
64 | /// Step count for given day
65 | Task GetTotalStepCountAsync(DateTime day);
66 | }
67 |
68 | ///
69 | /// Factory class for instantiating Step Engines.
70 | /// If a pedometer is surfaced through Windows.Devices.Sensors, the factory creates an instance of OSStepsEngine.
71 | /// Otherwise, the factory creates an instance of LumiaStepsEngine.
72 | ///
73 | public static class StepsEngineFactory
74 | {
75 | ///
76 | /// Static method to get the default steps engine present in the system.
77 | ///
78 | public static async Task GetDefaultAsync()
79 | {
80 | IStepsEngine stepsEngine = null;
81 |
82 | try
83 | {
84 | // Check if there is a pedometer in the system.
85 | // This also checks if the user has disabled motion data from Privacy settings
86 | Pedometer pedometer = await Pedometer.GetDefaultAsync();
87 |
88 | // If there is one then create OSStepsEngine.
89 | if (pedometer != null)
90 | {
91 | stepsEngine = new OSStepsEngine();
92 | }
93 | }
94 | catch (System.UnauthorizedAccessException)
95 | {
96 | // If there is a pedometer but the user has disabled motion data
97 | // then check if the user wants to open settngs and enable motion data.
98 | MessageDialog dialog = new MessageDialog("Motion access has been disabled in system settings. Do you want to open settings now?", "Information");
99 | dialog.Commands.Add(new UICommand("Yes", async cmd => await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-motion"))));
100 | dialog.Commands.Add(new UICommand("No"));
101 | await dialog.ShowAsync();
102 | new System.Threading.ManualResetEvent(false).WaitOne(500);
103 | return null;
104 | }
105 |
106 | // No Windows.Devices.Sensors.Pedometer exists, fall back to using Lumia Sensor Core.
107 | if (stepsEngine == null)
108 | {
109 | // Check if all the required settings have been configured correctly
110 | await LumiaStepsEngine.ValidateSettingsAsync();
111 |
112 | stepsEngine = new LumiaStepsEngine();
113 | }
114 | return stepsEngine;
115 | }
116 | }
117 |
118 | ///
119 | /// Steps engine that wraps the Windows.Devices.Sensors.Pedometer APIs
120 | ///
121 | public class OSStepsEngine : IStepsEngine
122 | {
123 | ///
124 | /// Constructor that receives a pedometer instance
125 | ///
126 | public OSStepsEngine()
127 | {
128 | }
129 |
130 | ///
131 | /// Activates the step counter when app goes to foreground
132 | ///
133 | /// Asynchronous task
134 | public Task ActivateAsync()
135 | {
136 | // This is where you can subscribe to Pedometer ReadingChanged events if needed.
137 | // Do nothing here because we are not using events.
138 | return Task.FromResult(false);
139 | }
140 |
141 | ///
142 | /// Deactivates the step counter when app goes to background
143 | ///
144 | /// Asynchronous task
145 | public Task DeactivateAsync()
146 | {
147 | // This is where you can unsubscribe from Pedometer ReadingChanged events if needed.
148 | // Do nothing here because we are not using events.
149 | return Task.FromResult(false);
150 | }
151 |
152 | ///
153 | /// Returns steps for given day at given resolution
154 | ///
155 | /// Day to fetch data for
156 | /// Resolution in minutes. Minimum resolution is five minutes.
157 | /// List of steps counts for the given day at given resolution.
158 | public async Task>> GetStepsCountsForDay(DateTime day, uint resolution)
159 | {
160 | List> steps = new List>();
161 | uint numIntervals = (((24 * 60) / resolution) + 1);
162 | if (day.Date.Equals(DateTime.Today))
163 | {
164 | numIntervals = (uint)((DateTime.Now - DateTime.Today).TotalMinutes / resolution) + 1;
165 | }
166 |
167 | uint totalSteps = 0;
168 | for (uint i = 0; i < numIntervals; i++)
169 | {
170 | TimeSpan ts = TimeSpan.FromMinutes(i * resolution);
171 | DateTime startTime = day.Date + ts;
172 | if (startTime < DateTime.Now)
173 | {
174 | // Get history from startTime to the resolution duration
175 | var readings = await Pedometer.GetSystemHistoryAsync(startTime, TimeSpan.FromMinutes(resolution));
176 |
177 | // Compute the deltas
178 | var stepsDelta = StepCountData.FromPedometerReadings(readings);
179 |
180 | // Add to the total count
181 | totalSteps += stepsDelta.TotalCount;
182 | steps.Add(new KeyValuePair(ts, totalSteps));
183 | }
184 | else
185 | {
186 | break;
187 | }
188 | }
189 | return steps;
190 | }
191 |
192 | ///
193 | /// Returns step count for given day
194 | ///
195 | /// Step count for given day
196 | public async Task GetTotalStepCountAsync(DateTime day)
197 | {
198 | // Get history from 1 day
199 | var readings = await Pedometer.GetSystemHistoryAsync(day.Date, TimeSpan.FromDays(1));
200 |
201 | return StepCountData.FromPedometerReadings(readings);
202 | }
203 | }
204 |
205 | ///
206 | /// Steps engine that wraps the Lumia SensorCore StepCounter APIs
207 | ///
208 | public class LumiaStepsEngine : IStepsEngine
209 | {
210 | #region Private members
211 | ///
212 | /// Step counter instance
213 | ///
214 | private IStepCounter _stepCounter;
215 |
216 | ///
217 | /// Is step counter currently active?
218 | ///
219 | private bool _sensorActive = false;
220 |
221 | ///
222 | /// Constructs a new ResourceLoader object.
223 | ///
224 | static protected readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView("Resources");
225 | #endregion
226 |
227 | ///
228 | /// Constructor
229 | ///
230 | public LumiaStepsEngine()
231 | {
232 | }
233 |
234 | ///
235 | /// Makes sure necessary settings are enabled in order to use SensorCore
236 | ///
237 | /// Asynchronous task
238 | public static async Task ValidateSettingsAsync()
239 | {
240 | if (await StepCounter.IsSupportedAsync())
241 | {
242 | // Starting from version 2 of Motion data settings Step counter and Acitivity monitor are always available. In earlier versions system
243 | // location setting and Motion data had to be enabled.
244 | MotionDataSettings settings = await SenseHelper.GetSettingsAsync();
245 | if (settings.Version < 2)
246 | {
247 | if (!settings.LocationEnabled)
248 | {
249 | MessageDialog dlg = new MessageDialog("In order to count steps you need to enable location in system settings. Do you want to open settings now? If not, application will exit.", "Information");
250 | dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(async (cmd) => await SenseHelper.LaunchLocationSettingsAsync())));
251 | dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler((cmd) => { Application.Current.Exit(); })));
252 | await dlg.ShowAsync();
253 | }
254 | if (!settings.PlacesVisited)
255 | {
256 | MessageDialog dlg = new MessageDialog("In order to count steps you need to enable Motion data in Motion data settings. Do you want to open settings now? If not, application will exit.", "Information");
257 | dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(async (cmd) => await SenseHelper.LaunchSenseSettingsAsync())));
258 | dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler((cmd) => { Application.Current.Exit(); })));
259 | await dlg.ShowAsync();
260 | }
261 | }
262 | }
263 | }
264 |
265 | ///
266 | /// SensorCore needs to be deactivated when app goes to background
267 | ///
268 | /// Asynchronous task
269 | public async Task DeactivateAsync()
270 | {
271 | _sensorActive = false;
272 | if (_stepCounter != null) await _stepCounter.DeactivateAsync();
273 | }
274 |
275 | ///
276 | /// SensorCore needs to be activated when app comes back to foreground
277 | ///
278 | public async Task ActivateAsync()
279 | {
280 | if (_sensorActive) return;
281 | if (_stepCounter != null)
282 | {
283 | await _stepCounter.ActivateAsync();
284 | }
285 | else
286 | {
287 | await InitializeAsync();
288 | }
289 | _sensorActive = true;
290 | }
291 |
292 | ///
293 | /// Returns steps for given day at given resolution
294 | ///
295 | /// Day to fetch data for
296 | /// Resolution in minutes. Minimum resolution is five minutes.
297 | /// List of steps counts for the given day at given resolution.
298 | public async Task>> GetStepsCountsForDay(DateTime day, uint resolution)
299 | {
300 | List> steps = new List>();
301 | uint totalSteps = 0;
302 | uint numIntervals = (((24 * 60) / resolution) + 1);
303 | if (day.Date.Equals(DateTime.Today))
304 | {
305 | numIntervals = (uint)((DateTime.Now - DateTime.Today).TotalMinutes / resolution) + 1;
306 | }
307 | for (int i = 0; i < numIntervals; i++)
308 | {
309 | TimeSpan ts = TimeSpan.FromMinutes(i * resolution);
310 | DateTime startTime = day.Date + ts;
311 | if (startTime < DateTime.Now)
312 | {
313 | try
314 | {
315 | var stepCount = await _stepCounter.GetStepCountForRangeAsync(startTime, TimeSpan.FromMinutes(resolution));
316 | if (stepCount != null)
317 | {
318 | totalSteps += (stepCount.WalkingStepCount + stepCount.RunningStepCount);
319 | steps.Add(new KeyValuePair(ts, totalSteps));
320 | }
321 | }
322 | catch (Exception)
323 | {
324 | }
325 | }
326 | else
327 | {
328 | break;
329 | }
330 | }
331 | return steps;
332 | }
333 |
334 | ///
335 | /// Returns step count for given day
336 | ///
337 | /// Step count for given day
338 | public async Task GetTotalStepCountAsync(DateTime day)
339 | {
340 | if (_stepCounter != null && _sensorActive)
341 | {
342 | StepCount steps = await _stepCounter.GetStepCountForRangeAsync(day.Date, TimeSpan.FromDays(1));
343 | return StepCountData.FromLumiaStepCount(steps);
344 | }
345 | else
346 | {
347 | return null;
348 | }
349 | }
350 |
351 | ///
352 | /// Initializes simulator if example runs on emulator otherwise initializes StepCounter
353 | ///
354 | private async Task InitializeAsync()
355 | {
356 | // Using this method to detect if the application runs in the emulator or on a real device. Later the *Simulator API is used to read fake sense data on emulator.
357 | // In production code you do not need this and in fact you should ensure that you do not include the Lumia.Sense.Testing reference in your project.
358 | EasClientDeviceInformation x = new EasClientDeviceInformation();
359 | if (x.SystemProductName.StartsWith("Virtual"))
360 | {
361 | //await InitializeSimulatorAsync();
362 | }
363 | else
364 | {
365 | await InitializeSensorAsync();
366 | }
367 | }
368 |
369 | ///
370 | /// Initializes the step counter
371 | ///
372 | private async Task InitializeSensorAsync()
373 | {
374 | if (_stepCounter == null)
375 | {
376 | await CallSensorCoreApiAsync(async () => { _stepCounter = await StepCounter.GetDefaultAsync(); });
377 | }
378 | else
379 | {
380 | await _stepCounter.ActivateAsync();
381 | }
382 | _sensorActive = true;
383 | }
384 |
385 | ///
386 | /// Initializes StepCounterSimulator (requires Lumia.Sense.Testing)
387 | ///
388 | //public async Task InitializeSimulatorAsync()
389 | //{
390 | // var obj = await SenseRecording.LoadFromFileAsync("Simulations\\short recording.txt");
391 | // if (!await CallSensorCoreApiAsync(async () => { _stepCounter = await StepCounterSimulator.GetDefaultAsync(obj, DateTime.Now - TimeSpan.FromHours(12)); }))
392 | // {
393 | // Application.Current.Exit();
394 | // }
395 | // _sensorActive = true;
396 | //}
397 |
398 | ///
399 | /// Performs asynchronous Sensorcore SDK operation and handles any exceptions
400 | ///
401 | /// Action for which the SensorCore will be activated.
402 | /// true if call was successful, false otherwise
403 | private async Task CallSensorCoreApiAsync(Func action)
404 | {
405 | Exception failure = null;
406 | try
407 | {
408 | await action();
409 | }
410 | catch (Exception e)
411 | {
412 | failure = e;
413 | }
414 | if (failure != null)
415 | {
416 | MessageDialog dlg = null;
417 | switch (SenseHelper.GetSenseError(failure.HResult))
418 | {
419 | case SenseError.LocationDisabled:
420 | {
421 | dlg = new MessageDialog(_resourceLoader.GetString("FeatureDisabled/Location"), _resourceLoader.GetString("FeatureDisabled/Title"));
422 | dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(async (cmd) => await SenseHelper.LaunchLocationSettingsAsync())));
423 | dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler((cmd) => { /* do nothing */ })));
424 | await dlg.ShowAsync();
425 | new System.Threading.ManualResetEvent(false).WaitOne(500);
426 | return false;
427 | }
428 | case SenseError.SenseDisabled:
429 | {
430 | dlg = new MessageDialog(_resourceLoader.GetString("FeatureDisabled/MotionData"), _resourceLoader.GetString("FeatureDisabled/Title"));
431 | dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(async (cmd) => await SenseHelper.LaunchSenseSettingsAsync())));
432 | dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler((cmd) => { /* do nothing */ })));
433 | await dlg.ShowAsync();
434 | return false;
435 | }
436 | case SenseError.SenseNotAvailable:
437 | {
438 | dlg = new MessageDialog(_resourceLoader.GetString("FeatureNotSupported/Message"), _resourceLoader.GetString("FeatureNotSupported/Title"));
439 | await dlg.ShowAsync();
440 | return false;
441 | }
442 | default:
443 | {
444 | dlg = new MessageDialog("Failure: " + SenseHelper.GetSenseError(failure.HResult), "");
445 | await dlg.ShowAsync();
446 | return false;
447 | }
448 | }
449 | }
450 | else
451 | {
452 | return true;
453 | }
454 | }
455 | }
456 | }
457 |
--------------------------------------------------------------------------------
/Steps/Strings/en-US/ActivateSensorCore.resw:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Later
122 |
123 |
124 | Switch on
125 |
126 |
127 | This application requires location data in order to work correctly
128 |
129 |
130 | Switch on location data
131 |
132 |
133 | Switch on
134 |
135 |
136 | This application requires motion data in order to work correctly
137 |
138 |
139 | Switch on motion data
140 |
141 |
142 | Do not ask again
143 |
144 |
--------------------------------------------------------------------------------
/Steps/Strings/en-US/Resources.resw:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | about
122 |
123 |
124 | The Steps developer sample application demonstrates the Pedometer APIs and Microsoft Lumia SensorCore SDK's Step Counter API functionality.
125 |
126 |
127 | This developer sample application has been created to provide tips and best practice guidance for software developers and app designers, and may not have all the features you would expect in a commercial product. This application is published in Store as a free software as it may also have value to regular phone users. The source code and more information of this sample can be from GitHub:
128 |
129 |
130 | Steps project in GitHub
131 |
132 |
133 | https://github.com/Microsoft/steps
134 |
135 |
136 | Learn more and get the latest version of this software from:
137 |
138 |
139 | about
140 |
141 |
142 | MICROSOFT SENSORCORE SAMPLE
143 |
144 |
145 | back
146 |
147 |
148 | To get more accurate data you need to enable detailed data collection in Motion data settings. Do you want to open settings now?
149 |
150 |
151 | Location has been disabled. Do you want to open Location settings now?
152 |
153 |
154 | Motion data has been disabled. Do you want to open Motion data settings now?
155 |
156 |
157 | Unfortunately this device does not support biking or moving in vehicle recognition
158 |
159 |
160 | Information
161 |
162 |
163 | Sorry, the features exemplified by this application are not available on your device. This application requires a Windows 10 device that supports either a Pedometer or Lumia SensorCore Motion.
164 |
165 |
166 | Microsoft SensorCore
167 |
168 |
169 | next
170 |
171 |
172 | This application does not function without location and motion data. The application will be closed.
173 |
174 |
175 | pin
176 |
177 |
178 | Today
179 |
180 |
181 | Yesterday
182 |
183 |
184 | unpin
185 |
186 |
187 | Steps version:
188 |
189 |
--------------------------------------------------------------------------------
/Steps/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "LumiaSensorCoreSDKUWP": "1.2.0.127",
4 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
5 | },
6 | "frameworks": {
7 | "uap10.0": {}
8 | },
9 | "runtimes": {
10 | "win10-arm": {},
11 | "win10-arm-aot": {},
12 | "win10-x86": {},
13 | "win10-x86-aot": {},
14 | "win10-x64": {},
15 | "win10-x64-aot": {}
16 | }
17 | }
--------------------------------------------------------------------------------