works-on-my-machine-starburst Well, for the brave, criminally insane, curious, or otherwise bored I have a alpha version of Historical Buildings – download the APK if you want to try it out.  This is just, at this time, the application just shows a simple list of historical buildings in Edmonton (according to the City of Edmonton’s Open Data Catalogue).  Click on a building, and it will show you on Google Maps where the building is in the city.  The code for this is, in my opinion (and to say the least) – rough.  But it is a start.  Definitely needs some improvement.  Or maybe I just need to change my thinking to more of a Android/Java mindset.  Anyway the usual caveats apply:  use at your own risk / batteries not include / do not eat / void where prohibited by law, etc, etc, etc

Anyway, if you use it let me know.  There are bound to be bugs, but hey it “Works for me!”.  Time to work on some other stuff for it.  I think the next neat thing is would be to show the closest building to you.  Either that, or handle some of the seedy code issues and infrastructure stuff that bugs me. 

Screen shot of the list of historical buildings   Clicking on a build shows you where the building is

 

MapList

Thanks to the MapView, it’s drop dead easy to put Google Maps into your application.  There are lots of posts out there how to do it.  Interestingly (to me anyway), when I did a quick search of the Android developers mailing list, I was surprised to see that a lot of people had the same problem:  basically, when you look at your MapView, you end up with a grid of white squares.  It kind of sucks.  There are a lot of blog posts and articles out there on how to fix this problem, but this one is for me, and to help me remember it.

The trick to fixing this is setting your Google Maps API key.  Note the layout below:

   1: <?xml version="1.0" encoding="utf-8"?>


   2: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"


   3:     android:id="@+id/mainlayout"


   4:     android:orientation="vertical"


   5:     android:layout_width="fill_parent"


   6:     android:layout_height="fill_parent" >


   7:


   8:     <com.google.android.maps.MapView


   9:         android:id="@+id/mapview"


  10:         android:layout_width="fill_parent"


  11:         android:layout_height="fill_parent"


  12:         android:clickable="true"


  13:         android:apiKey="Your Maps API Key"


  14:     />


  15:


  16: </RelativeLayout>

hotel-key

In particular, pay attention to line #13.  What you have to do is create a Google Maps API key, and then paste it in there.  That’s simple.  How do you do that?  Well it’s simple too, but not as simple as it could be.  The first thing you need to do is to sign your application.  This isn’t a big deal, you have to sign your application before you can publish it anyway.  Android will NOT install an application otherwise.

So, it seems we have two steps here:

  1. Sign your application
  2. Use your signed application to get a Google Maps apiKey.

Generate a private key.  Keep this safer, as if it were the Holy Grail.  Lose this, and as far as the public is concerned, you’re locked out from your own application – you will not be able to update it.  The image below will show you the steps to go through

    "C:\Program Files (x86)\Java\jdk1.6.0_19\bin\keytool" -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -validity 10000

keytoolsample

Once you have that done, build your application (in release mode).  I leave this as an exercise for the reader.

Now that you have your application built, you need to sign it.  This is where jarsigner comes in:

jarsignerAnd the final step is to zipalign your  APK.  You have to do zipalign last.  Basically, you do zipalign for performance reasons.  If you want to know more, RTFM.

C:\android-sdk-windows\tools\zipalign -v 4 HistoricalBuildings-unalign.apk HistoricalBuildings.apk

zipalign

Now, of course, both Eclipse and IntelliJ will handle these steps for you.  But where is the fun in that?

I guess I forgot to mention this:  On April 1, 2010, I received an e-mail from Microsoft that my MVP in C# was renewed for the third year.  This makes me a happy, because with Resharper 5 (and therefore Visual Studio 2010) and Windows Mobile 7, I’m hoping that this will be an exciting year for the .NET crowd. 

Well, okay, perhaps I didn’t forget.  Given that it was April 1st when I got the e-mail, I like to give things a few days to settle down.  I am acquainted with some mischievous pranksters who would think it was a funny April Fools joke.

MVP_Horizontal_FullColor

YegDataListNot that long ago, the City of Edmonton announced it’s Open Data Catalogue.  I noticed that one of the data catalogues was a list of historical buildings in the city.  Yeah, I know that some people in other cities might consider this a pretty weak list.  I mean, the oldest building in Edmonton isn’t even 150 years old.  I’d wager that some parts of the world consider 150 year old buildings to be “new construction”.  Anyway, as I’ve been dabbling with Android now for about the past year, I thought a handy little project to try out would be to write an app for Android that would show me where the historical buildings are in the city.

I’ve got the foundation of a simple application started over a GitHub called, not surprisingly, Historical Buildings (if you pull the source code, then just a heads up that I use IntelliJ for my Android development).  This application currently works in the emulator, my next step is to installing it on my phone and trying it out for real.  Right now all the application does is present you with a list of buildings.  You click on one, and you’ll see on Google Maps where the building.

Some other ideas for features that may or may not happen:

  • Figure out the whole unit testing story in Android.  Then setup a build script.  Then a build server.  CI rocks, but as I’m trying to learn the Android framework and figure out what all the parts are, I’m not to focused on that at the moment.
  • Don’t always fetch the data – store it locally
    • I don’t think the way I’m parsing the JSON result is very efficient or “proper”, but it does get the job done.
  • Notify the user when they are within a certain distance of a historical building.
  • Currently YEG has a PDF explaining the significance of the building.  Not very friendly/convenient for mobile devices.  Need something better.
    • One thought would be to create Wikipedia entries and link to that.
    • Another thought is to petition the City of Edmonton to convert their PDF’s to a more neutral format (HTML anyone)?
    • The Edmonton Public Library has some information about the “Lost Building of Edmonton”.  Maybe incorporate that somehow – perhaps showing what buildings used to exist at a given address?
  • Perhaps allow the user to update their coordinates for YEG’s historical buildings.  I’ve notice (on the emulator) that sometimes the lat/long isn’t exactly accurate.  If you look at the image below for the old Arlington Apartments, you notice that the marker should be over the pile of rubble slightly to the left of where it currently is.
  • Maybe include buildings that aren’t necessarily designated as historical, but are interesting architecturally or otherwise.
  • Instead of using YEG OpenData, perhaps an independent cloud based data store (Azure maybe?)

If you’ve got any other suggestions, I’m happy to hear them.

MapList

Just sitting here at Legoland in Carlsbad, CA waiting for my kids to get off Coastersaurus. Just thought I’d make a mention about my presentation on SOLID to the Inland Empire .NET User Group. This is my third year in a row as their March speaker. I’m glad to say that for the third year in a row they haven’t chased me away with pitch-forks and torches. Largely based on that reason, I’ll say the presentation went well. Well, that and the fact that the concepts did seem to be understood and there were no technical glitches.

Thanks James and his crew for agreeing to shift from the 2nd Tuesday to the 3rd Tuesday to accommodate my travel.

Here is a zip of the code and slide deck.

Given that I haven’t blogged while I was at home, I figured that I should be obtuse and do so while on vacation.  Currently hanging out in sunny Palm Springs, California for a few days.  On Tuesday, March 16th, I’ll be making my way down to the Inland Empire .NET User Group for a quick talk about SOLID.  Then it’s off to Legoland and the San Diego Zoo.  Oh, and somewhere in there I have to work in a trip to the Palm Springs Air Museum.  As a history buff, it’s really cool to see all the WW2 aircraft they have there – some of which are still in working order.

Note:  I am in no way, shape, or form affiliated with HarvestApp.com.

I’ve been an independent consultant in IT for four years now.  One of the biggest things in my day-to-day activities is keeping track of my time.  Timekeeping has become a bit of a thing for me, even when I was an employee.  It probably stems back to about 1996 or so, when my first web application ever was a timesheet application I wrote while working at Alberta Transportation & Utilities (now Alberta Infrastructure).   It was in C++, using Netscape Commerce Server and CGI.  I even had to write my own libraries to parse the HTTP requests and came up with my own crude templating engine.  Yes I’m old.  Yes, it was interesting.  Yes, we have it better now.  No, I would not like to repeat that experience.

Anyway, over the years, I’ve tried many different things, from a VBA solution based on Outlook, Excel spreadsheets, to Timesheet.PHP, to a WebForms app based on the Timesheet.PHP database which I ported over to ASP.NET MVC when I wanted to expand my jQuery and ASP.NET MVC knowledge.  My little home-grown web app was good for what I needed it to do, but it wasn’t anything fancy.  If it was, I’d have sold it and become rich beyond the dreams of avarice.

In the early fall, a friend of mine told me about HarvestApp – a subscription based, online time-tracking application.  Thought I would give it a try.  My thinking at the time was that I’m not really in the business of writing a timesheet application, and I really need to keep track of time – as a consultant, billable hours are pretty important.  So, here I am now, almost six months later, and I will say that I like HarvestApp.  I find it quick, and easy to use.  I get easy to see reports.  You can create invoices (I don’t use HarvestApp to create my invoices, but you could).  You can track expenses.  It’s mobile friendly.  It’s moderately priced (IMHO – YMMV).  It has a public API so you can write your own applications against it. 

Anyway, don’t take my word on it, try it for yourself.

tumbleweedYeah, I’ve been kind of quiet as of late.  So quiet, I suspect that some people might be wondering if something happened.  I was a bit surprised to see that the last time I had blogged was after TechDays in Calgary.  Well, nothing significant has happened – just a bit of laziness augmented by a touch of tech-burnout compounded by the odd bit of single malt scotch.

So, now that one month is almost up on 2010, I figured that it was time to start blogging about something again.  The first trick to this, of course, was to figure out what I wanted to do in 2010.  It does seem like there will be a lot of interesting things, technically speaking, coming up this year.

A couple of new things I want to look at over the remaining 11 months:

Mobile development, particularly with a focus on Androidandroid-robot-logo1.  For the latter half of 2009 I have been dabbling in Android.  I believe that it’s time to go out on a bender, and in a drunken stupor get some embarrassing tattoo and join the Android Army.  So far, I’m at two out of three.  Not bad, huh?

AndroidArmy 

Ruby is another technology I’d like to explore – particularly Rails.  I can help but think that the opinionated view that Rails development has taken is the way to go for the bulk of web development.  A lot of websites are basically just forms over data, and Rails seems to address that concern rather well.  To bad nobody around here in Edmonton does much Rails development.

.NET 4.0 and ASP.NET MVC2.  I know there is a lot of debate between Web Forms and ASP.NET MVC.  Personally, I think MVC is the better way.  Probably best to keep abreast of what is going on in the ASP.NET MVC world.  And, of course, the DLR in .NET will come to maturity soon.  By maturity I mean widespread acceptance.  If this happens, then maybe developers won’t get so hung up on languages:  i.e. “I’m a C# guy so VB.NET sucks”.

And finally, a guy needs hobbies.  Now granted, my past hobbies of alcohol and guns (no, not together at the same time) have served me well for the past 20 years or so. However, they are hard hobbies to share with my sons at this point in time.  So, at the start of winter I expanded the geek factor of my sons (and myself) by getting back into Warhammer.  Now the last time I played was about 20 years ago, with the 3rd edition rules.  In fact, I still have some of the books in my basement from back then.  Anyway, picked up The Battle for Skull Pass boxed set.  My son rather likes the Dwarfs.  I suspect it’s because he’s similar in stature/height to the stunties.  Myself, while I find the Greenskins amusing, I suspect I might have to move on and get serious with Dark Elves.

Anyway, enough for tonight.

Yesterday I was at TechDays 2009 in Calgary for the day (well, the morning really).  I wasn’t there as an attendee, but as a speaker.  Thanks to everybody who came out to my two talks, the first one on an Introduction to ASP.NET MVC and the second one on SOLIDifying your ASP.NET MVC Application.  There were a few hiccups along the way:  as usual, I fell victim to the Technical Presentation Time Dilation Syndrome (i.e. ran out of time) on both talks.  I guess I’m just to long-winded for my own good.  As well, because I was running a EAP of Resharper 5, I had some Visual Studio 2008 issues – namely VS2008 would hang on me from time to time.  Note to self: maybe don’t use the bleeding edge tools in a talk.  And I really should break myself of wanting to type all the code – using snippets would really save me time.

Two things that suprised me:

  1. That there was still that much interest in ASP.NET MVC intro talks.  I just figured that everybody knew/knows about it.  Or maybe I just spend to much time with guys who have drunk the ASP.NET MVC Flavor Aid.  Either way, I think that there were some in the crowd that will convert from WebForms to ASP.NET MVC.
  2. I asked how many people wrote unit tests or developing their software using Test Driven Development was the number of people who didn’t raise their hands.  While I didn’t expect the majority of the crowd, I did expect a lot more people than I saw.  Maybe it was a quiet crowd, and people didn’t feel like saying they wrote unit tests.  Maybe I live in a bubble, and my perception of what is actually going on in the .NET world is skewed (that is to say, perhaps writing tests is the exception rather than the rule).  It did kind of make me a bit concerned, as I truly believe that TDD does help one write better software overall.

Anyway, here’s to hoping that TechDays 2010 will stop off in Edmonton.  And hopefully have a track that will focus on developer fundamentals, like TechDays had in Toronto and Vancouver.

Out of intellectual curiosity, I sparked up MonoDevelop and decided to see what would happen when I tried to compile the ASP.NET MVC source code. I figured that it would Just Work.  After all, I can use the .NET compiled assembly with no problems on Mono, so there really shouldn’t be any problems trying to compile the code.  Bad news is that there is one minor glitch.  Good news is the glitch is easy to work around and has already been fixed so it shouldn’t be a problem for future version of Mono.

When you compile, here is what you get:

Compilation failed: 1 error(s), 0 warnings

/home/tom/Projects/MVC-MS-Pl-original/MVC-MS-Pl/Mvc/FormCollection.cs(25,6): error CS0246: The type or namespace name `FormCollectionBinder’ could not be found. Are you missing a using directive or an assembly reference?

Build complete — 1 error, 0 warnings

So, this kind of surprised me.  Looking at the code, I did see the FormCollectionBinder in the code, it’s an embedded class within System.Web.Mvc.FormCollection, check out lines 68-88 below:

   1: /* **************************************************************************** 
   2:  * 
   3:  * Copyright (c) Microsoft Corporation. All rights reserved. 
   4:  * 
   5:  * This software is subject to the Microsoft Public License (Ms-PL).  
   6:  * A copy of the license can be found in the license.htm file included  
   7:  * in this distribution. 
   8:  * 
   9:  * You must not remove this notice, or any other, from this software. 
  10:  * 
  11:  * ***************************************************************************/ 
  12:  
  13: namespace System.Web.Mvc { 
  14:     using System; 
  15:     using System.Collections.Generic; 
  16:     using System.Collections.Specialized; 
  17:     using System.Diagnostics.CodeAnalysis; 
  18:     using System.Globalization; 
  19:     using System.Web.Mvc.Resources; 
  20:  
  21:     [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable", 
  22:         Justification = "It is not anticipated that users will need to serialize this type.")] 
  23:     [SuppressMessage("Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers", 
  24:         Justification = "It is not anticipated that users will call FormCollection.CopyTo().")] 
  25:     [FormCollectionBinder] 
  26:     public class FormCollection : NameValueCollection { 
  27:  
  28:         public FormCollection() { 
  29:         } 
  30:  
  31:         public FormCollection(NameValueCollection collection) { 
  32:             if (collection == null) { 
  33:                 throw new ArgumentNullException("collection"); 
  34:             } 
  35:  
  36:             Add(collection); 
  37:         } 
  38:  
  39:         public IDictionary<string, ValueProviderResult> ToValueProvider() { 
  40:             CultureInfo currentCulture = CultureInfo.CurrentCulture; 
  41:  
  42:             Dictionary<string, ValueProviderResult> dict = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase); 
  43:             string[] keys = AllKeys; 
  44:             foreach (string key in keys) { 
  45:                 string[] rawValue = GetValues(key); 
  46:                 string attemptedValue = this[key]; 
  47:                 ValueProviderResult vpResult = new ValueProviderResult(rawValue, attemptedValue, currentCulture); 
  48:                 dict[key] = vpResult; 
  49:             } 
  50:  
  51:             return dict; 
  52:         } 
  53:  
  54:         public virtual ValueProviderResult GetValue(string name) { 
  55:             if (String.IsNullOrEmpty(name)) { 
  56:                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name"); 
  57:             } 
  58:  
  59:             string[] rawValue = GetValues(name); 
  60:             if (rawValue == null) { 
  61:                 return null; 
  62:             } 
  63:  
  64:             string attemptedValue = this[name]; 
  65:             return new ValueProviderResult(rawValue, attemptedValue, CultureInfo.CurrentCulture); 
  66:         } 
  67:  
  68:         private sealed class FormCollectionBinderAttribute : CustomModelBinderAttribute { 
  69:  
  70:             // since the FormCollectionModelBinder.BindModel() method is thread-safe, we only need to keep 
  71:             // a single instance of the binder around 
  72:             private static readonly FormCollectionModelBinder _binder = new FormCollectionModelBinder(); 
  73:  
  74:             public override IModelBinder GetBinder() { 
  75:                 return _binder; 
  76:             } 
  77:  
  78:             // this class is used for generating a FormCollection object 
  79:             private sealed class FormCollectionModelBinder : IModelBinder { 
  80:                 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
  81:                     if (controllerContext == null) { 
  82:                         throw new ArgumentNullException("controllerContext"); 
  83:                     } 
  84:  
  85:                     return new FormCollection(controllerContext.HttpContext.Request.Form); 
  86:                 } 
  87:             } 
  88:         } 
  89:  
  90:     } 
  91: }

The version of Mono 2.4.3 I have doesn’t compile the class FormCollection because the FormCollectionBinderAttribute is inside the FormCollection class.  This is the bug, and it has since been fixed.  Easy ways to get around this:

  1. Just use the binary assembly from Microsoft for ASP.NET MVC.
  2. Build your own Mono with the fix included
  3. Move the code for FormCollectionBinderAttribute class outside of the code for the FormCollection class.