New Windows Phone 7 Marketplace icons

We are all familiar with the app store and marketplace icons for apps in the Apple app store.

iosappstore

Well now finally Windows Phone 7 has one too and it comes in 2 different styles and 3 different colours no less.

wp7_278x92_blue

wp7_480x80_blue

wp7_278x92_green

wp7_480x80_green

wp7_278x92_red

wp7_480x80_red

You can download the full set of icons including the license agreement for using them here.

Bear in mind that in order to use these icons you must agree to Microsoft’s license which essentially means:

  • You cannot alter them in anyway (including changing the colours, wording, size or dimensions).
  • They must be used in relation to an app that is published in the Marketplace.
  • The images must only link directly to the app in the Marketplace.  Eg:
    http://social.zune.net/redirect?type=phoneApp&id=c14e93aa-27d7-df11-a844-00237de2db9e
  • You must leave a border of at least 1/4 the height of the logo between it and any surrounding content.
Advertisements

How to implement Basic HTTP Authentication in WCF on Windows Phone 7

Unfortunately the version 1.0 of the Windows Phone 7 SDK is missing a few essentials.  One of which is that the Phone’s WCF implementation doesn’t support basic authentication for non-WCF services. So if you need to supply a user name and password to access a remote service, you’re on your own.  Setting the Security mode in your binding config as you normally would doesn’t work.

Fortunately basic HTTP authentication is easy enough to implement yourself.

As the name suggests Basic Authentication is basic.  It is simply an “Authorization” header which is added to the HTTP call which contains the base64 encoded user name and password.

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

The good news is that implementing basic authentication means simply adding this header to your going calls.  Here’s how.

Firstly we need a method to encode the credentials:

private string EncodeBasicAuthenticationCredentials(string username, string password)
{
  //first concatenate the user name and password, separated with :
  string credentials = username + ":" + password;

  //Http uses ascii character encoding, WP7 doesn’t include
  // support for ascii encoding but it is easy enough to convert
  // since the first 128 characters of unicode are equivalent to ascii.
  // Any characters over 128 can’t be expressed in ascii so are replaced
  // by ?
  var asciiCredentials = (from c in credentials
                     select c <= 0x7f ? (byte)c : (byte)'?').ToArray();

  //finally Base64 encode the result
  return Convert.ToBase64String(asciiCredentials);
}

Now that we have a means of encoding our credentials we just need to add them to the headers of our WCF request.  We can easily do this by wrapping the call in an OperationContextScope:

var credentials = EncodeBasicAuthenticationCredentials("username", "password");

using (OperationContextScope scope =
          new OperationContextScope(service.InnerChannel))
{
  HttpRequestMessageProperty request = new HttpRequestMessageProperty();
  request.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " + credentials;

  OperationContext.Current.OutgoingMessageProperties.Add(
                                     HttpRequestMessageProperty.Name, request);

  service.DoSomethingAsync();
}

This easily adds basic HTTP authentication for your WCF call on the fly.  Unfortunately using the OperationContext like this means you have to remember to add the header each time you make a call. If you are going to regularly be needing to do this you might want to consider creating a custom Channel, which automatically adds the header to all outgoing requests.  The technique would essentially be the same, it’s just that it would code it once for the channel rather than for each individual call. [Update 08/12/2010: There is no centralised way to do this in Silverlight 3.0]

Also it is always worth mentioning that basic authentication is not secure.  Encoding the username and password does not encrypt them.  They are transmitted over the internet in the clear for anyone to read.

WP7 URI’s need to be encoded just like on the web

I found a little gotcha with the way WP7 handles the encoding of uri’s which could trip you up when passing string values through to pages via query strings.

I was trying to pass this ID through to a second page via a parameter on the uri.

var id = “HxmyKn0F+Y8XbksplmTzFQ==”;
NavigationContext.Navigate(new Uri(“MyPage.xaml?id=” + id, UriKind.Relative));

Only thing is, when I pulled the value out of the QueryStrings collection the ID had changed to:

“HxmyKn0F Y8XbksplmTzFQ==”

Silverlight had changed the “+” sign into a space.  But why?

Although it is a little counter intuitive in this context, this actually is the expected behaviour.  The spec for URL encoding (RFC 1738 if you feel the urge to read up) attaches special significance to the “+” sign as part of the URL (along with other special characters – see below).  We can’t include these characters in our data so we need to escape it as described in the spec.

Obviously this is nothing new.  It is one of the first things you learn when you start developing for the web.  In fact we can use the same HttpUtility.UrlEncode() utility that we would on the web. 

var encodedUri = “/MySecondPage.xaml?myID=” + HttpUtility.UrlEncode(“HxmyKn0F+Y8XbksplmTzFQ==”); 

Lesson: Unless you can absolutely guarantee that your string parameters won’t contain reserved URL characters, they must be encoded using UrlEncode() first.  This is actually quite important and is often left out of most tutorials about navigation on Windows Phone7.

For the record here is a list of the all of the reserved characters:

$ ? }
& @ |
+ SPACE \
, < ^
/ > ~
: # [
; % ]
= { `

Better way to check for an network connection on WP7

Last month I described a method for determining whether or not you have a network connection from your Windows Phone 7 app:

bool hasNetworkConnection =
              NetworkInterface.NetworkInterfaceType != NetworkInterfaceType.None;

Unfortunately there is a serious problem with this approach.

It turns out that accessing the NetworkInterface.NetworkInterfaceType property is a blocking call.  The property will not return until is has a result and this can take some time.  It might be a second or two when you have a connection available, however it can take up to 20 seconds (in my experience) when you don’t have any connection at all.  All this time the UI thread is blocked.  Not good!

As a side note this is a bad piece of API design on Microsoft’s part.  A property should always return immediately. Not doing so breaks two of Microsoft’s own usage rules regarding properties:

  1. functionality should not be implemented as a property if it “has an observable side-effect” – blocking the UI for up to 20 seconds is certainly an observable side effect.
  2. and should not be a property if “the operation is expensive enough that you want to communicate to the user that they should consider caching the result.”

Nevertheless, like it or not, accessing NetworkInterface.NetworkInterfaceType is a blocking call.  We have to just deal with it.  Fortunately its not too hard to fix – we just need to make sure that if we ever access NetworkInterface.NetworkInterfaceType we do it asynchronously on a background thread.  Here is a simple example which does this:

public static void GetNetworkInterfaceType(Action callback)
{
   ThreadPool.QueueUserWorkItem(o =>
             {
                 var interfaceType = NetworkInterface.NetworkInterfaceType;
                 ((Action)o)(interfaceType);
             }, callback);
}

Bear in mind with this code that your callback will be executed on a background thread so you will need to marshal back to the UI thread if you are doing anything that isn’t thread-safe – like updating the UI.

A more fully featured wrapper around this idea has been created by Gabor Dolhai, if you really need to get serious about network connection detection.

Another option to bear in mind is the NetworkInterface.GetIsNetworkAvailable() method.  If you just need to detect if you are connected to any network and don’t really care what kind of connection you have you can use GetIsNetworkAvailable().

bool hasNetworkConnection = NetworkInterface.GetIsNetworkAvailable();

The method does return immediately and does not block the UI so can be called safely on the UI thread.   Beware however that this method will always return true in the emulator regardless of your actual connectivity.

Warning: Beware of color banding on SuperAMOLED phones

We all know that Microsoft has taken a leaf out of Apple’s book with their attempts to tie down the hardware specs for Windows Phone 7.  It can be argued whether this is a good thing or not for users, but it certainly makes life easier for us developers.  We know we can target a minimum common platform and know that our software should run the same way on all devices…

Well that is the theory anyway!

Unfortunately the reality is slightly different.  There are still subtle differences between devices that developers need to be aware of.

The Super AMOLED problem

Samsung has come to market with its very impressive Super AMOLED screens in the Focus and the Omnia 7. Unfortunately these screens have rather different display characteristics than normal LED screens.  In particular they have a real problem with colour gradients.  They exhibit very bad colour banding.  MobileTechWorld.com has posted a comparison with of the same image displayed on a LG Optimus 7 (left) and a Samsung Omnia 7 (right).

You can see that the Omnia 7 (right) looks very different.  It exhibits rather bad colour banding and even has a different hue altogether – it looks more purple than blue.

I have just run foul of this problem when testing one of my apps on an Omnia 7.  At first I thought it was a problem with the image file I was using but it looks this is just a general problem with AMOLED screens in general (including on Android).  My problem was not quite as bad as the example above but it was still noticeable and off putting.

The problem here is actually to do with the fact that the screen is 16-bit.  All of the 16-bit screens have this problem to some – its just that it is dramatically more apparent on the SuperAMOLED screens than on others.

There are two points that come out of this for developers:

1) Avoid images with gradients in your apps.  They won’t show up well on AMOLED screens. If you must use a gradient in an image you can try and use a dithering function to smooth over the gradient, sometimes this can help.  But my advice is that you’re better off steering clear of them altogether if you can.

2) Don’t be lulled in to a false sense of security in thinking that all Windows Phone 7 devices are equivalent.  They are not.  Test your apps on as many devices as you possibly can before releasing it or showing it to clients.  It  is not the case that your app will necessarily look the same on all devices.

The simple truth is that however much Microsoft tries to constrain the hardware these kinds of variations are inevitable.  It is the curse of smartphone development as Android developers well know and now with some 7 iOS devices (11 if you count discontinued hardware) some iPhone dev’s are now beginning to it feel too.

Update 21/11:

There is a way you can test for this to some degree using the emulator.  By default the emulator runs with a 32-bit color depth, but this can be changed by changing the following:

C:\Program Files (x86)\Microsoft XDE\1.0\WM7_Skin.xml

Change displayDepth="32" to displayDepth="16"

Problems with any images or colors will now become more apparent.

The easiest way to calculate a distance between to GeoCoordinates on Windows Phone 7

I was hunting around for how to calculate the distance between two GeoCoordinates on Windows Phone 7.  Currently if you do a Google search to find how to accomplish this you will find a number of blogs talking about the need to use a Haversine formula that takes into account the curvature of the earth.

This is all well and good and the code for the Haversine formula isn’t that hard (okay the maths is beyond me, but copy and paste is within my skill level)

Anyway despite what a Google search will tell you there is a much easier way to do this.  There is already support for it built right into the phone’s location API.  The GeoCoordinate class itself has a GetDistanceTo() method right on it.

GeoCoordinate.GetDistanceTo()

Returns the distance between the latitude and longitude coordinates that are specified by this GeoCoordinate and another specified GeoCoordinate.

var myLocation = new GeoCoordinate(-51.39792, -0.12084);

var yourLocation = new GeoCoordinate(-29.83245, 31.04034);

double distance = myLocation.GetDistanceTo(yourLocation);

Doesn’t come much easier than that.

There is one gotcha however.  The GetDistanceTo() method always returns the result in kilometers meters.  If you need a result in miles I would suggest you use Dragos Manolescu’s Haversine implementation.

Navigating to Pages in different assembly in Windows Phone 7

The navigation system allows you to easily navigate to other XAML pages in your project:

NavigationService.Navigate(new Uri(“MyOtherPage.xaml”, UriKind.Relative));

But what if you want to navigate to a page that isn’t in the same project?

Fortunately this is easy enough once you understand the syntax of a URI path.

URI’s in Silverlight are a very limited subset of the pack syntax in WPF.  The generalised format of a URI in silverlight is:

/{assemblyName};component/{pathToResource}

Where {assemblyName} is the name of the assembly containing the XAML page (just the name without the .dll extension) and {pathToResource} is the path to the XAML file.  Note: The assembly name you provide must an be assembly referenced by your project.

So if the external assembly called External.dll contains a page called MyOtherPage in a folder called Pages the URI would be /external;component/Pages/MyOtherPage.xaml.  Thus the code would be:

NavigationService.Navigate(new Uri(“/external;component/Pages/MyOtherPage.xaml”, UriKind.Relative));

This type of URI format doesn’t just work for navigation.  It can be used for any type of resource that exists in an external assembly.  To load an image from another assembly you could use:

<image source=”/otherAssembly;component/Images/myImage.jpg”/>