├── .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 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 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 | {"DataPollHistory":[],"CurrentReadingHistory":[{"Timestamp":"130388991511551096","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991531471764","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991551507200","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991571357111","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991591717237","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991611756001","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991631805429","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991651842011","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991671791988","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991692051253","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991712102335","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991732149179","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991752166256","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991772224996","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991792496693","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991812543525","RunSteps":"0","RunTime":"0","WalkSteps":"24","WalkTime":"160000000"},{"Timestamp":"130388991832579196","RunSteps":"0","RunTime":"0","WalkSteps":"44","WalkTime":"270000000"},{"Timestamp":"130388991852571664","RunSteps":"0","RunTime":"0","WalkSteps":"48","WalkTime":"290000000"},{"Timestamp":"130388991872591307","RunSteps":"0","RunTime":"0","WalkSteps":"51","WalkTime":"310000000"},{"Timestamp":"130388991892520132","RunSteps":"0","RunTime":"0","WalkSteps":"55","WalkTime":"330000000"},{"Timestamp":"130388991912550902","RunSteps":"0","RunTime":"0","WalkSteps":"58","WalkTime":"350000000"},{"Timestamp":"130388991932571370","RunSteps":"0","RunTime":"0","WalkSteps":"61","WalkTime":"370000000"},{"Timestamp":"130388991952560846","RunSteps":"0","RunTime":"0","WalkSteps":"65","WalkTime":"390000000"},{"Timestamp":"130388991972576127","RunSteps":"0","RunTime":"0","WalkSteps":"68","WalkTime":"410000000"},{"Timestamp":"130388991992570359","RunSteps":"0","RunTime":"0","WalkSteps":"71","WalkTime":"430000000"},{"Timestamp":"130388992012575999","RunSteps":"0","RunTime":"0","WalkSteps":"74","WalkTime":"450000000"},{"Timestamp":"130388992032576174","RunSteps":"0","RunTime":"0","WalkSteps":"78","WalkTime":"470000000"},{"Timestamp":"130388992051284021","RunSteps":"0","RunTime":"0","WalkSteps":"81","WalkTime":"490000000"},{"Timestamp":"130388992071559948","RunSteps":"0","RunTime":"0","WalkSteps":"84","WalkTime":"510000000"},{"Timestamp":"130388992091597875","RunSteps":"0","RunTime":"0","WalkSteps":"87","WalkTime":"530000000"},{"Timestamp":"130388992111639351","RunSteps":"0","RunTime":"0","WalkSteps":"91","WalkTime":"550000000"},{"Timestamp":"130388992131678748","RunSteps":"0","RunTime":"0","WalkSteps":"94","WalkTime":"570000000"},{"Timestamp":"130388992151716968","RunSteps":"0","RunTime":"0","WalkSteps":"97","WalkTime":"590000000"},{"Timestamp":"130388992171757406","RunSteps":"0","RunTime":"0","WalkSteps":"100","WalkTime":"610000000"},{"Timestamp":"130388992191578937","RunSteps":"0","RunTime":"0","WalkSteps":"103","WalkTime":"630000000"},{"Timestamp":"130388992211933015","RunSteps":"0","RunTime":"0","WalkSteps":"106","WalkTime":"650000000"},{"Timestamp":"130388992232095718","RunSteps":"0","RunTime":"0","WalkSteps":"109","WalkTime":"670000000"},{"Timestamp":"130388992251504235","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992271674693","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992291754134","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992311066614","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992331082331","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992351080608","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992372519378","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992391167416","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992412036534","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992432148621","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992452519349","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992471269286","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992492572606","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992512036515","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992532572745","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992552519366","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992572571833","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992592576266","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992612036525","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992631260400","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992651714247","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992672573849","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992692574865","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992712036766","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992732573967","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992751724419","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992772575563","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992792574357","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992812195223","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992832519315","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"},{"Timestamp":"130388992852519291","RunSteps":"0","RunTime":"0","WalkSteps":"113","WalkTime":"690000000"}],"RecordingInfo":{"Version":"1000","Type":"1","Description":"","Start":"130388991490946631","Length":"1368066990"}} -------------------------------------------------------------------------------- /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 | } --------------------------------------------------------------------------------