Friday 17 December 2010

'Verkeer' Windows Phone 7 application is now Live

After working on for over two months I can finally announce that my 'Verkeer' application is now globally available in the Windows Phone Market Place for free. And given Dutch traffic conditions today I'd say not a day to soon.


Summary of the 'Verkeer'application

The Verkeer application offers an up-to-date map based view of current traffic jams and speed camera's in the Netherlands. You can zoom and pan to specific locations of interest and store those as favorites for quick access. Additionally the application supports a Live-Tile allowing you to view current traffic conditions right in the home screen.


You can find the app in the WP7 Market place under the name 'Verkeer' or you can follow this Zune store link. Finally a few screen shots to give you an Idea of what the app looks like.





Saturday 4 December 2010

Creating an application installation and usage tracker for Windows Phone 7



As an application developer you are generally interested in knowing how many times your application has been installed and how often it's really being used. Unfortunately WP7 and its market place don't offer this capabilities (yet?) so I decided to leverage a good old fashion website tracker.
My first idea was to use Google analytics because it has excellent reporting capabilities but unfortunately analytics only works if you integrate it with something that that runs JavaScript. It works with the WP7 Browser control but that control only works if it is visible. So to use Google analytics I had to include (two) visible browser controls in my application and suffer their overhead.
Instead I turned to http://www.statcounter.com/. They are free and offer the ability for tracking through a downloadable image that you can set to be 1x1 Pixel. I configured two counters, 1 for first start up and one for repeated startup and use the following code to call them:
private
static
void LoadUrl(string url)
{
   ThreadStart tStart = new
   ThreadStart(() =>
   {
   try
     
         HttpWebRequest trafficInfoRequest = WebRequest.CreateHttp(url);

         IAsyncResult result = (IAsyncResult)trafficInfoRequest.BeginGetResponse(new
         AsyncCallback((asynchronousResult) =>
         {
         try
            {
               HttpWebResponse trafficInforResponse = (HttpWebResponse)trafficInfoRequest.EndGetResponse(asynchronousResult);
               StreamReader counter = new
               StreamReader(trafficInforResponse.GetResponseStream());

               counter.ReadToEnd();
            }
         catch { };
      }), null);
   }
   catch { }
   });

   Thread solo = new
   Thread(tStart);
   solo.Start();
}


Nice and asynchronous.
These are the stats so far

Wednesday 1 December 2010

Why does my Map Zoom property keep being reset to 1?


While working on my phone application I encountered an odd problem, after loading and setting my Map's ZoomLevel it promptly got set to 1 instead.
My setup was simple, in line with the MVVM pattern I had a MapControl's Zoom and Center properties databound to my View Model object. At the start of my application I loaded the View Models Zoom and Center values from a file on disk and this worked fine. But when my application resumed and I loaded these from the application state object instead they would be loaded and set correctly but immediately afterwards the Zoom would be overridden by the value 1.
Turns out the problem is caused by the order in which I set the two properties.
Apparently if you set the Center first and the Zoomlevel second the databinding circle sets the Zoom to a previous version (in my case 1). Do it the other way around and it works perfectly. Feels counterintuitive but it probably has to do with the fact that internally Zoom level and Center are converted into a Bounding box and that box is then databound back at the Zoom value of the control. So:
Wrong:
this.Center = (GeoCoordinate)PhoneApplicationService.Current.State["Center"];
this.ZoomLevel = (double)PhoneApplicationService.Current.State["ZoomLevel"];

Right:
this.ZoomLevel = (double)PhoneApplicationService.Current.State["ZoomLevel"];
this.Center = (GeoCoordinate)PhoneApplicationService.Current.State["Center"];