Permalink
Browse files

Fit and finish for when-to-go-home feature

  • Loading branch information...
1 parent cbf5b2e commit a934c5c2643be662662eea75ba9caec68cabe6b7 @meirtsvi committed Feb 5, 2012
@@ -0,0 +1,2 @@
+Bin/
+obj/
@@ -0,0 +1,156 @@
+using System;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Device.Location;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace WazeScheduledTaskAgent
+{
+ public class BackgroundNavigator
+ {
+
+ /// <summary>
+ /// Returns the current cached location from GPS
+ /// </summary>
+ /// <returns></returns>
+ public static GeoCoordinate GetCurrentLocation()
+ {
+ //// Simulate location in debugger:
+ //if (System.Diagnostics.Debugger.IsAttached)
+ //{
+ // return new GeoCoordinate((double)32095676 / (double)1000000, (double)34798484 / (double)1000000);
+ //}
+
+ GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
+ watcher.TryStart(true,TimeSpan.FromSeconds(13));
+
+ return watcher.Position.Location;
+ }
+
+ /// <summary>
+ /// Return the Home location from favorites
+ /// </summary>
+ /// <param name="homeName"></param>
+ /// <returns></returns>
+ public static GeoCoordinate GetHomeLocation(string homeName)
+ {
+ FileStream historyFile = null;
+ try
+ {
+ var store = IsolatedStorageFile.GetUserStoreForApplication();
+
+ historyFile = store.OpenFile("/history", FileMode.Open);
+ }
+ catch (FileNotFoundException)
+ {
+ System.Diagnostics.Debug.WriteLine("Can't find history file");
+ return GeoCoordinate.Unknown;
+
+ }
+ catch (Exception)
+ {
+ return GeoCoordinate.Unknown;
+ }
+
+ StreamReader sr = new StreamReader(historyFile);
+
+ while (!sr.EndOfStream)
+ {
+ string line = sr.ReadLine();
+ string[] tokens = line.Split(new[] { ',' }, StringSplitOptions.None);
+ string placeName = tokens[5];
+ if ((placeName.ToLower() == homeName) || (placeName == "home"))
+ {
+
+ double destLongitude = double.Parse(tokens[7]) / 1000000;
+ double destLatitude = double.Parse(tokens[6]) / 1000000;
+ sr.Dispose();
+
+ return new GeoCoordinate(destLatitude, destLongitude);
+ }
+ }
+
+ return GeoCoordinate.Unknown;
+ }
+
+
+ /// <summary>
+ /// Gets the estimated route time in minutes
+ /// </summary>
+ /// <param name="from"></param>
+ /// <param name="to"></param>
+ /// <returns>Route time in minutes</returns>
+ public static int GetRouteTime(GeoCoordinate from, GeoCoordinate to)
+ {
+ string requestStr = string.Format("http://www.waze.co.il/RoutingManager/routingRequest?from=x%3A{0}+y%3A{1}&to=x%3A{2}+y%3A{3}&returnJSON=false&returnGeometries=false&returnInstructions=false&timeout=60000&nPaths=1",
+ from.Longitude, from.Latitude, to.Longitude, to.Latitude);
+
+ try
+ {
+ HttpWebResponse resp = null;
+ ManualResetEvent mre = new ManualResetEvent(false);
+ HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(requestStr);
+ req.BeginGetResponse(delegate(IAsyncResult result)
+ {
+ try
+ {
+ resp = (HttpWebResponse)req.EndGetResponse(result);
+ mre.Set();
+ }
+ catch (Exception we)
+ {
+ System.Diagnostics.Debug.WriteLine(we.ToString());
+
+ resp = null;
+ mre.Set();
+ }
+ }, null);
+
+ // we can't wait more then 14 seconds or else the OS will kill us.
+ if (!mre.WaitOne(14000))
+ return -1;
+
+ StreamReader sr = new StreamReader(resp.GetResponseStream());
+ string respString = sr.ReadToEnd();
+
+ System.Diagnostics.Debug.WriteLine("Response String:" + Environment.NewLine + respString);
+
+ int arrivingTime = 0;
+ Regex regex = new Regex("\"crossTime\":([0-9]+)");
+ MatchCollection matchCol = regex.Matches(respString);
+ foreach (Match match in matchCol)
+ {
+ int crossTime = int.Parse(match.Groups[1].Value);
+ arrivingTime += crossTime;
+ }
+
+ sr.Dispose();
+
+ return arrivingTime / 60;
+ }
+ catch (Exception exc)
+ {
+
+ System.Diagnostics.Debug.WriteLine(exc.ToString());
+
+ if (System.Diagnostics.Debugger.IsAttached)
+ {
+ // An unhandled exception has occurred; break into the debugger
+ System.Diagnostics.Debugger.Break();
+ }
+
+ return -1;
+ }
+ }
+ }
+}
@@ -0,0 +1,37 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Resources;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WazeScheduledTaskAgent")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("WazeScheduledTaskAgent")]
+[assembly: AssemblyCopyright("Copyright 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e465278b-e963-4436-b385-21f882188220")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: NeutralResourcesLanguageAttribute("en-US")]
@@ -0,0 +1,181 @@
+using System;
+using System.Threading;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Linq;
+using System.Windows;
+using Microsoft.Phone.Scheduler;
+using Microsoft.Phone.Shell;
+using Microsoft.Phone.Controls;
+using System.Windows.Resources;
+using System.Device.Location;
+
+namespace WazeScheduledTaskAgent
+{
+ public class ScheduledAgent : ScheduledTaskAgent
+ {
+ private static volatile bool _classInitialized;
+
+ /// <remarks>
+ /// ScheduledAgent constructor, initializes the UnhandledException handler
+ /// </remarks>
+ public ScheduledAgent()
+ {
+ if (!_classInitialized)
+ {
+ _classInitialized = true;
+ // Subscribe to the managed exception handler
+ Deployment.Current.Dispatcher.BeginInvoke(delegate
+ {
+ Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
+ });
+ }
+ }
+
+ /// Code to execute on Unhandled Exceptions
+ private void ScheduledAgent_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
+ {
+ if (System.Diagnostics.Debugger.IsAttached)
+ {
+ // An unhandled exception has occurred; break into the debugger
+ System.Diagnostics.Debugger.Break();
+ }
+ }
+
+ /// <summary>
+ /// Agent that runs a scheduled task
+ /// </summary>
+ /// <param name="task">
+ /// The invoked task
+ /// </param>
+ /// <remarks>
+ /// This method is called when a periodic or resource intensive task is invoked
+ /// </remarks>
+ protected override void OnInvoke(ScheduledTask task)
+ {
+ string langHomeName = string.Empty;
+ string interval = string.Empty;
+
+ try
+ {
+ // Get data from storage:
+ //
+
+ Mutex mLiveTileStorageMutex = new Mutex(true,"LiveTileStorageMutex");
+
+ try
+ {
+
+ mLiveTileStorageMutex.WaitOne();
+
+ // Save the home name in selected language so the task can search for it later on.
+ using (IsolatedStorageFileStream fsHomeName = IsolatedStorageFile.GetUserStoreForApplication().OpenFile("LiveTile\\HomeName",FileMode.Open,FileAccess.Read))
+ {
+ using (StreamReader sr = new StreamReader(fsHomeName))
+ {
+ langHomeName = sr.ReadLine();
+ }
+
+ }
+
+ // Save the refresh interval so the task can search for it later on.
+ using (IsolatedStorageFileStream fsInterval = IsolatedStorageFile.GetUserStoreForApplication().OpenFile("LiveTile\\Interval",FileMode.Open,FileAccess.Read))
+ {
+ using (StreamReader sr = new StreamReader(fsInterval))
+ {
+ interval = sr.ReadLine();
+ }
+
+ }
+ }
+ finally
+ {
+ mLiveTileStorageMutex.ReleaseMutex();
+ }
+
+
+ string tileData = string.Empty;
+
+ // Get current location:
+ GeoCoordinate from = BackgroundNavigator.GetCurrentLocation();
+
+ // Find home location:
+
+ GeoCoordinate to = BackgroundNavigator.GetHomeLocation(langHomeName);
+
+ // Calculate time to home:
+
+ int etaMin = 0;
+
+ if (from == GeoCoordinate.Unknown)
+ {
+ tileData = "No GPS available";
+ }
+ else if (to == GeoCoordinate.Unknown)
+ {
+ // default back message in case user did not set home:
+ tileData = "Please set 'Home' favorite";
+ }
+ else
+ {
+ etaMin = BackgroundNavigator.GetRouteTime(from, to);
+
+ // Prepare data for tile:
+ if (etaMin >= 0)
+ {
+ tileData = etaMin + " min" + Environment.NewLine + "Last Update:" + Environment.NewLine + DateTime.Now.ToShortTimeString();
+ }
+ else
+ {
+ etaMin = 0;
+ tileData = "Failed to find route";
+ }
+
+ }
+
+ // Update Tile:
+
+ // On the front tile we can show a max of 99 min.
+ int frontETA = (etaMin < 100) ? etaMin : 99;
+
+ string taskName = "Waze Periodic Task";
+
+ ShellTile currentTiles = ShellTile.ActiveTiles.First();
+ StandardTileData tilesUpdatedData = new StandardTileData
+ {
+ Title = "Waze",
+ BackgroundImage = new Uri("waze_logo.png", UriKind.Relative),
+ Count = frontETA,
+ BackTitle = "Home ETA",
+ BackContent = tileData
+
+ };
+
+ currentTiles.Update(tilesUpdatedData);
+
+ int userInterval = int.Parse(interval);
+
+ if (userInterval < 30)
+ {
+ // Update the Tile again in selected interval min (Won't work for marketplace app) if less than 30:
+ ScheduledActionService.LaunchForTest(taskName, TimeSpan.FromMinutes(userInterval));
+ }
+
+ }
+ catch (Exception exc)
+ {
+ System.Diagnostics.Debug.WriteLine(exc.ToString());
+
+ if (System.Diagnostics.Debugger.IsAttached)
+ {
+ // An unhandled exception has occurred; break into the debugger
+ System.Diagnostics.Debugger.Break();
+ }
+ }
+ finally
+ {
+ NotifyComplete();
+ }
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit a934c5c

Please sign in to comment.