PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/geolocation/cs/geolocationcs/scenario4_foregroundgeofencehelpers.cs

https://gitlab.com/Rockyspade/Windows-universal-samples
C# | 466 lines | 348 code | 59 blank | 59 comment | 43 complexity | c9fbb9ff3e19788e46e156e715291c45 MD5 | raw file
  1. //*********************************************************
  2. //
  3. // Copyright (c) Microsoft. All rights reserved.
  4. // This code is licensed under the MIT License (MIT).
  5. // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
  6. // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
  7. // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
  8. // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
  9. //
  10. //*********************************************************
  11. using SDKTemplate;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. using Windows.Data.Json;
  17. using Windows.Devices.Geolocation;
  18. using Windows.Devices.Geolocation.Geofencing;
  19. using Windows.Storage;
  20. using Windows.UI.Xaml;
  21. using Windows.UI.Xaml.Controls;
  22. namespace GeolocationCS
  23. {
  24. public sealed partial class Scenario4 : Page
  25. {
  26. void OnRadiusTextChanged(object sender, TextChangedEventArgs e)
  27. {
  28. radiusSet = TextChangedHandlerDouble(false, "Radius", Radius);
  29. DetermineCreateGeofenceButtonEnableState();
  30. }
  31. void OnLongitudeTextChanged(object sender, TextChangedEventArgs e)
  32. {
  33. longitudeSet = TextChangedHandlerDouble(false, "Longitude", Longitude);
  34. DetermineCreateGeofenceButtonEnableState();
  35. }
  36. void OnLatitudeTextChanged(object sender, TextChangedEventArgs e)
  37. {
  38. latitudeSet = TextChangedHandlerDouble(false, "Latitude", Latitude);
  39. DetermineCreateGeofenceButtonEnableState();
  40. }
  41. void OnIdTextChanged(object sender, TextChangedEventArgs e)
  42. {
  43. // get number of characters
  44. int charCount = Id.Text.Length;
  45. nameSet = (0 != charCount);
  46. CharCount.Text = charCount.ToString() + " characters";
  47. DetermineCreateGeofenceButtonEnableState();
  48. }
  49. void OnRegisteredGeofenceListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
  50. {
  51. IList<object> list = e.AddedItems;
  52. if (0 == list.Count)
  53. {
  54. // disable the remove button
  55. RemoveGeofenceItem.IsEnabled = false;
  56. }
  57. else
  58. {
  59. // enable the remove button
  60. RemoveGeofenceItem.IsEnabled = true;
  61. // update controls with the values from this geofence item
  62. // get selected item
  63. GeofenceItem item = RegisteredGeofenceListBox.SelectedItem as GeofenceItem;
  64. RefreshControlsFromGeofenceItem(item);
  65. DetermineCreateGeofenceButtonEnableState();
  66. }
  67. }
  68. private void RefreshControlsFromGeofenceItem(GeofenceItem item)
  69. {
  70. if (null != item)
  71. {
  72. Id.Text = item.Id;
  73. Latitude.Text = item.Latitude.ToString();
  74. Longitude.Text = item.Longitude.ToString();
  75. Radius.Text = item.Radius.ToString();
  76. SingleUse.IsChecked = item.SingleUse;
  77. if (0 != item.DwellTime.Ticks)
  78. {
  79. DwellTime.Text = item.DwellTime.ToString();
  80. }
  81. else
  82. {
  83. DwellTime.Text = "";
  84. }
  85. if (0 != item.Duration.Ticks)
  86. {
  87. Duration.Text = item.Duration.ToString();
  88. }
  89. else
  90. {
  91. Duration.Text = "";
  92. }
  93. if (0 != item.StartTime.Ticks)
  94. {
  95. DateTimeOffset dt = item.StartTime;
  96. StartTime.Text = formatterShortDateLongTime.Format(dt);
  97. }
  98. else
  99. {
  100. StartTime.Text = "";
  101. }
  102. // Update flags used to enable Create Geofence button
  103. OnIdTextChanged(null, null);
  104. OnLongitudeTextChanged(null, null);
  105. OnLatitudeTextChanged(null, null);
  106. OnRadiusTextChanged(null, null);
  107. }
  108. }
  109. private bool TextChangedHandlerDouble(bool nullAllowed, string name, TextBox e)
  110. {
  111. bool valueSet = false;
  112. try
  113. {
  114. double value = Double.Parse(e.Text);
  115. valueSet = true;
  116. // clear out status message
  117. _rootPage.NotifyUser("", NotifyType.StatusMessage);
  118. }
  119. catch (ArgumentNullException)
  120. {
  121. if (false == nullAllowed)
  122. {
  123. if (null != name)
  124. {
  125. _rootPage.NotifyUser(name + " needs a value", NotifyType.StatusMessage);
  126. }
  127. }
  128. }
  129. catch (FormatException)
  130. {
  131. if (null != name)
  132. {
  133. _rootPage.NotifyUser(name + " must be a number", NotifyType.StatusMessage);
  134. }
  135. }
  136. catch (OverflowException)
  137. {
  138. if (null != name)
  139. {
  140. _rootPage.NotifyUser(name + " is out of bounds", NotifyType.StatusMessage);
  141. }
  142. }
  143. return valueSet;
  144. }
  145. private bool TextChangedHandlerInt(bool nullAllowed, string name, TextBox e)
  146. {
  147. bool valueSet = false;
  148. try
  149. {
  150. int value = int.Parse(e.Text);
  151. valueSet = true;
  152. // clear out status message
  153. _rootPage.NotifyUser("", NotifyType.StatusMessage);
  154. }
  155. catch (ArgumentNullException)
  156. {
  157. if (false == nullAllowed)
  158. {
  159. if (null != name)
  160. {
  161. _rootPage.NotifyUser(name + " needs a value", NotifyType.StatusMessage);
  162. }
  163. }
  164. }
  165. catch (FormatException)
  166. {
  167. if (null != name)
  168. {
  169. _rootPage.NotifyUser(name + " must be a number", NotifyType.StatusMessage);
  170. }
  171. }
  172. catch (OverflowException)
  173. {
  174. if (null != name)
  175. {
  176. _rootPage.NotifyUser(name + " is out of bounds", NotifyType.StatusMessage);
  177. }
  178. }
  179. return valueSet;
  180. }
  181. private void SetStartTimeToNowFunction()
  182. {
  183. try
  184. {
  185. calendar.SetToNow();
  186. DateTimeOffset dt = calendar.GetDateTime();
  187. StartTime.Text = formatterShortDateLongTime.Format(dt);
  188. }
  189. catch (Exception ex)
  190. {
  191. _rootPage.NotifyUser(ex.ToString(), NotifyType.ErrorMessage);
  192. }
  193. }
  194. private string GetTimeStampedMessage(string eventCalled)
  195. {
  196. calendar.SetToNow();
  197. return eventCalled + " " + formatterLongTime.Format(calendar.GetDateTime());
  198. }
  199. // are settings available so a geofence can be created?
  200. private bool SettingsAvailable()
  201. {
  202. bool fSettingsAvailable = false;
  203. if (true == nameSet &&
  204. true == latitudeSet &&
  205. true == longitudeSet &&
  206. true == radiusSet)
  207. {
  208. // also need to test if data is good
  209. fSettingsAvailable = true;
  210. }
  211. return fSettingsAvailable;
  212. }
  213. private void DetermineCreateGeofenceButtonEnableState()
  214. {
  215. CreateGeofenceButton.IsEnabled = SettingsAvailable();
  216. }
  217. // add geofence to listbox
  218. private void AddGeofenceToRegisteredGeofenceListBox(Geofence geofence)
  219. {
  220. GeofenceItem item = new GeofenceItem(geofence);
  221. // the registered geofence listbox is data bound
  222. // to the collection stored in the root page
  223. geofenceCollection.Insert(0, item);
  224. }
  225. /// <summary>
  226. /// This is the click handler for the 'Set Start Time to Now' button.
  227. /// </summary>
  228. /// <param name="sender"></param>
  229. /// <param name="e"></param>
  230. private void OnSetStartTimeToNow(object sender, RoutedEventArgs e)
  231. {
  232. SetStartTimeToNowFunction();
  233. }
  234. /// <summary>
  235. /// This is the click handler for the 'Set Lat/Long to current position' button.
  236. /// </summary>
  237. /// <param name="sender"></param>
  238. /// <param name="e"></param>
  239. async private void OnSetPositionToHere(object sender, RoutedEventArgs e)
  240. {
  241. SetPositionProgressBar.Visibility = Visibility.Visible;
  242. SetPositionToHereButton.IsEnabled = false;
  243. Latitude.IsEnabled = false;
  244. Longitude.IsEnabled = false;
  245. try
  246. {
  247. // Get cancellation token
  248. _cts = new CancellationTokenSource();
  249. CancellationToken token = _cts.Token;
  250. // Carry out the operation
  251. // geolocator and location permissions are initialized and checked on page creation.
  252. var geolocator = new Geolocator();
  253. // Request a high accuracy position for better accuracy locating the geofence
  254. geolocator.DesiredAccuracy = PositionAccuracy.High;
  255. Geoposition pos = await geolocator.GetGeopositionAsync().AsTask(token);
  256. Latitude.Text = pos.Coordinate.Point.Position.Latitude.ToString();
  257. Longitude.Text = pos.Coordinate.Point.Position.Longitude.ToString();
  258. // clear status
  259. _rootPage.NotifyUser("", NotifyType.StatusMessage);
  260. }
  261. catch (TaskCanceledException)
  262. {
  263. _rootPage.NotifyUser("Task canceled", NotifyType.StatusMessage);
  264. }
  265. catch (Exception ex)
  266. {
  267. _rootPage.NotifyUser(ex.ToString(), NotifyType.ErrorMessage);
  268. }
  269. finally
  270. {
  271. _cts = null;
  272. }
  273. SetPositionProgressBar.Visibility = Visibility.Collapsed;
  274. SetPositionToHereButton.IsEnabled = true;
  275. Latitude.IsEnabled = true;
  276. Longitude.IsEnabled = true;
  277. }
  278. /// <summary>
  279. /// This is the click handler for the 'Create Geofence' button.
  280. /// </summary>
  281. /// <param name="sender"></param>
  282. /// <param name="e"></param>
  283. private void OnCreateGeofence(object sender, RoutedEventArgs e)
  284. {
  285. try
  286. {
  287. // get lat/long/radius, the fence name (fenceKey),
  288. // and other properties from controls,
  289. // depending on data in controls for activation time
  290. // and duration the appropriate
  291. // constructor will be used.
  292. Geofence geofence = GenerateGeofence();
  293. // Add the geofence to the GeofenceMonitor's
  294. // collection of fences
  295. geofences.Add(geofence);
  296. // add geofence to listbox
  297. AddGeofenceToRegisteredGeofenceListBox(geofence);
  298. }
  299. catch (TaskCanceledException)
  300. {
  301. _rootPage.NotifyUser("Canceled", NotifyType.StatusMessage);
  302. }
  303. catch (Exception ex)
  304. {
  305. // GeofenceMonitor failed in adding a geofence
  306. // exceptions could be from out of memory, lat/long out of range,
  307. // too long a name, not a unique name, specifying an activation
  308. // time + duration that is still in the past
  309. _rootPage.NotifyUser(ex.ToString(), NotifyType.ErrorMessage);
  310. }
  311. }
  312. private void FillRegisteredGeofenceListBoxWithExistingGeofences()
  313. {
  314. foreach (Geofence geofence in geofences)
  315. {
  316. AddGeofenceToRegisteredGeofenceListBox(geofence);
  317. }
  318. }
  319. private void FillEventListBoxWithExistingEvents()
  320. {
  321. var settings = ApplicationData.Current.LocalSettings;
  322. if (settings.Values.ContainsKey("ForegroundGeofenceEventCollection"))
  323. {
  324. string geofenceEvent = settings.Values["ForegroundGeofenceEventCollection"].ToString();
  325. if (0 != geofenceEvent.Length)
  326. {
  327. var events = JsonValue.Parse(geofenceEvent).GetArray();
  328. // NOTE: the events are accessed in reverse order
  329. // because the events were added to JSON from
  330. // newer to older. AddEventDescription() adds
  331. // each new entry to the beginning of the collection.
  332. for (int pos = events.Count - 1; pos >= 0; pos--)
  333. {
  334. var element = events.GetStringAt((uint)pos);
  335. AddEventDescription(element);
  336. }
  337. }
  338. settings.Values["ForegroundGeofenceEventCollection"] = null;
  339. }
  340. }
  341. private void SaveExistingEvents()
  342. {
  343. JsonArray jsonArray = new JsonArray();
  344. foreach (var eventDescriptor in eventCollection)
  345. {
  346. jsonArray.Add(JsonValue.CreateStringValue(eventDescriptor.ToString()));
  347. }
  348. string jsonString = jsonArray.Stringify();
  349. var settings = ApplicationData.Current.LocalSettings;
  350. settings.Values["ForegroundGeofenceEventCollection"] = jsonString;
  351. }
  352. private void AddEventDescription(string eventDescription)
  353. {
  354. if (eventCollection.Count == maxEventDescriptors)
  355. {
  356. eventCollection.RemoveAt(maxEventDescriptors - 1);
  357. }
  358. eventCollection.Insert(0, eventDescription);
  359. }
  360. private enum TimeComponent
  361. {
  362. day,
  363. hour,
  364. minute,
  365. second
  366. }
  367. private long ParseTimeSpan(string field, int defaultValue)
  368. {
  369. long timeSpanValue = 0;
  370. char[] delimiterChars = { ':' };
  371. string[] timeComponents = field.Split(delimiterChars);
  372. int start = 4 - timeComponents.Length;
  373. if (start >= 0)
  374. {
  375. int loop = 0;
  376. int index = start;
  377. for (; loop < timeComponents.Length; loop++, index++)
  378. {
  379. TimeComponent tc = (TimeComponent)index;
  380. switch (tc)
  381. {
  382. case TimeComponent.day:
  383. timeSpanValue += (long)decimalFormatter.ParseInt(timeComponents[loop]) * secondsPerDay;
  384. break;
  385. case TimeComponent.hour:
  386. timeSpanValue += (long)decimalFormatter.ParseInt(timeComponents[loop]) * secondsPerHour;
  387. break;
  388. case TimeComponent.minute:
  389. timeSpanValue += (long)decimalFormatter.ParseInt(timeComponents[loop]) * secondsPerMinute;
  390. break;
  391. case TimeComponent.second:
  392. timeSpanValue += (long)decimalFormatter.ParseInt(timeComponents[loop]);
  393. break;
  394. default:
  395. break;
  396. }
  397. }
  398. }
  399. if (0 == timeSpanValue)
  400. {
  401. timeSpanValue = defaultValue;
  402. }
  403. timeSpanValue *= oneHundredNanosecondsPerSecond;
  404. return timeSpanValue;
  405. }
  406. }
  407. }