Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Windows 8 Metro declarations: User Tile Provider

This blog post is part of my Windows 8 metro-style application declarations series. Read more about declarations in the introductory post about application manifest.

User Tile Provider declaration allows you to register your application as a user tile provider. That means that user will be able to use your application to change her user tile.

One of many ways of changing the user tile can is by clicking your personal tile (avatar) on Windows 8 Start screen – four options are currently displayed, one of them is “Change user tile”:

image

Selecting the first option will take you to Control Panel’s Personalize page, set on User Tile:

image

2 options for changing the tile already available: the user can browse through her pictures and select the one that she likes or she can take a new one with the help of her web cam.

Your own application as a user tile provider

As with other declarations, you declare your application as a user tile provider in the application manifest. The easiest way to do that is through the manifest editor. You’ll see that when you add the User Tile Provider declaration to the Supported Declarations list, there are no declaration specific options to be set.

image

That’s good. After setting the declaration, run or just deploy your application and return to the Control Panel. You should now be looking at something like this:

image

Your application is now registered as the official user tile provider and by clicking on the application tile it will be launched.

And fail.

Of course, there is some wiring you have to do in your code to make this work properly.

Wiring the application logic

There isn’t a special kind of activation reserved for this type of activation, it’s activated through the special Protocol activation - I covered Protocol activation before – if you set up Protocol activation as described in that blog post, you can check for specific protocol in the OnProtocolActivated handler; you’ll see that Uri, passed in through provided arguments, looks something like UserTileProvider://, so you just have to check for a particular protocol to see how or why your application was invoked:

private void OnProtocolActivated(ProtocolActivatedEventArgs args)
{
    if (args.Uri.Scheme == "usertileprovider")
    {
        PhotoView page = new PhotoView();
        page.SetProfileImage();
        Window.Current.Content = page;
        Window.Current.Activate();
        return;
    }

    // ... other protocol handlers
}

Here I’m bringing up a new PhotoView page (also discussed in my previous blog post) whenever my application is invoked for choosing a user tile.

Changing the user tile

OK, so application now responds to the user tile change call. But how do we actually change the tile? Well, there’s an API for that. You can get and set current user tile through asynchronous GetUserImageAsync() and SetUserImageAsync() methods of the UserInformation object.

In my demo application, I get the user tile from her profile, rotate it by 90° and display it to the user:

image

After user taps (selects) the image, she is first prompted for confirmation:

image

And if user confirms that (she can opt out by clicking somewhere outside of the dialog), the new image is set as her new user tile.

image

Quick tip: if you're using your Windows Live ID as your Windows 8 login, changing your user tile will change your general Windows Live display picture as well (in Windows Live Messenger, Live Profile, etc.)

The code for dealing with images is a bit messy – I got it working but I suspect this will get easier as we progress towards the final runtime bits:

Read the user tile, rotate it by 90° and set as the Image source:

public async void SetProfileImage()
{
    StorageFile file = UserInformation.GetUserImage(UserImageKind.LargeBitmap);
    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(await file.OpenAsync(FileAccessMode.Read));
    BitmapTransform transform = new BitmapTransform();
    transform.Rotation = BitmapRotation.Clockwise90Degrees;
    PixelDataProvider pixelData = await decoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8, decoder.BitmapAlphaMode, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage);
    WriteableBitmap bitmap = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);
    pixelStream = bitmap.PixelBuffer.AsStream();
    pixelStream.Seek(0, SeekOrigin.Begin);
    pixelBuffer = pixelData.DetachPixelData();
    pixelStream.Write(pixelBuffer, 0, (int)pixelStream.Length);
    bitmap.Invalidate();

    Viewer.Source = bitmap;
}

Get the image from Image source, save it to a temporary file, set the user tile and delete the temporary file:

private async void SetUserTile()
{
    WriteableBitmap bitmap = Viewer.Source as WriteableBitmap;

    StorageFile file = await Windows.Storage.ApplicationData.Current.TemporaryFolder.CreateFileAsync("temp");
    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, await file.OpenAsync(FileAccessMode.ReadWrite));
    encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 72.0, 72.0, pixelBuffer);
    await encoder.FlushAsync();
    await Windows.System.UserProfile.UserInformation.SetUserImageAsync(file);
    await file.DeleteAsync();
}

Noticed a lot of asynchronous / await calls? Plenty of those in WinRT Winking smile

There’s still many quirks and missing bits around the User Tile Provider declaration implementation, it’s obviously not complete yet. But the ability to provide users with your own application to change their user tiles just feels overwhelming. I bet we’ll get some pretty creative applications in this space when Windows 8 marketplace ships.



Windows 8 Metro declarations: File Type Associations

This blog post is part of my Windows 8 metro-style application declarations series. Read more about declarations in the introductory post about application manifest.

File Type Associations Declaration is very similar to Protocol Declaration. Similar in a way that it defines an OS-wide declaration that’s used to launch your application. What this declaration does should be familiar to most Windows users as it’s been a part of the system from the very beginning.

Every file extension can be associated with a particular application that can handle the content of such file. Most text editors, for example, know how to handle files with .txt extension , file formats like .jpg, .png, and .bmp, are handled by graphics applications like Paint or PhotoShop, etc.

File Type Associations Declaration lets you declare specific file extension(s) that your application will be able to handle. It can be an existing, well-known extension such as .txt, or you can come up with your very own extension and/or file format and register that. For this example, I’ll declare two extensions – .jpg (well-known graphics format extension, and .jpgx – a made up extension that will serve just as an example for this blog post) - my sample application will display the same photo viewer for both extensions.

Setting up the photo viewer page

I’ve created a new blank page in my application and put the Image control on it. That’ll serve as my simple photo viewer.

I’ve also added a method that will help me set the image. The method takes a parameter of type StorageFile, which is a new class in windows runtime that takes care of wrapping file info and does basic file manipulation.

public async void SetPhoto(StorageFile storageFile)
{
    BitmapImage image = new BitmapImage();
    IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read);
    image.SetSource(stream);
    Viewer.Source = image;
}

The above snippet shows a very basic way to asynchronously open a file. The stream is set as an image source after the file contents are fully read.

Application activation

Similar to Protocol example from my last post, the application is notified when user launches a file with associated extension, but the API behaves a bit differently here. The OnProtocolActivated method is already built into the Application class and you only have to override it in App class derivate to handle the activation. This behavior is most likely to change in one of the future versions of WinRT, but I currently have no idea whether we’ll get a separate method (OnXXXActivated) for each activation kind, or will there be a single method OnActivated, that will provide the activation kind through one of its parameters. Currently, there’s a weird mixture of both approaches.

Here’s how the overridden OnFileActivated method looks like:

protected override void OnFileActivated(FileActivatedEventArgs args)
{
    PhotoView page = new PhotoView();
    page.SetPhoto(args.Files[0] as StorageFile);
    Window.Current.Content = page;
    Window.Current.Activate();
}

Interesting things to note about the provided FileActivatedEventArgs class are:

  • args.Files contains a collection of files that were used in activation. In this example, I’m only using the first one.
  • args.PreviousExecutionState will tell you the state the application was in before activation. It can be either NotRunning, Running, Suspended and Terminated.
  • args.Verb is the action that was used for activating the app. Should be set to Open.

And that’s it for the code. The last thing is setting up the Declaration in the application manifest.

Application Manifest

image

This is the first part of the File Type Association Declaration Page. DisplayName is a localizable string that will be displayed to the user as associated file a handler and the graphics can be changed by specifying a new Logo. Info Tip should contain the text that will be displayed in a tooltip when user hovers a mouse over the application’s associated file extension. Name is a unique name of the association.

Edit Flags specify what type of security prompt will be displayed to the user when she launches the associated file. OpenIsSafe will show a standard warning dialog, while AlwaysUnsafe will display a security warning dialog.

 image

The second part of the Declaration configuration lets you set the supported file types. You can add as many file extensions as you want your application to handle and you can specify an optional content type for each of them. In the above example, extensions .jpg and .jpgx are registered.

Application Settings section lets you configure application’s entry point settings.

Running the application

Run (or just deploy) your application, then launch a .jpg file of your choice that’s on your disk. The following dialog should appear, asking you to select the default application that will handle that file extension in the future:

image

After selecting your app as the default, it should be launched (or activated if already running) and display the image.

Renaming a .jpg file to (previously unassociated extension) .jpgx and launching that, for example, will give you the following dialog:

image

You can check (and change) the default application for each of the file extensions through the Control Panel. Both .jpg and .jpgx are associated with my demo application:

image

Congratulations, you’ve just created your first file extension handling Metro application Smile



Windows 8 Metro declarations: Protocol

I touched on the Metro-style application declarations in my previous blog entry where I wrote about application manifest. I’m continuing the series with exploring the currently available declarations, starting with Protocol. I’ll be using C# Windows Metro style application samples throughout the whole series.

I imagined an application that would respond to the specific URL requests. Let’s say that invoking a URL like “locx://aerial/47.639747~-122.129731” should show me an aerial map, centered to a geographical point of (47.639747, -122.129731).

Displaying a Map

Let’s first figure out how to display the map. There isn’t any native WinRT maps component yet, so the simplest way to display a map is using Bing maps in a WebView Xaml control. WebView is a control that can display HTML, either passed in by string or by navigating to actual web site. Think of it as a very lightweight WebBrowser control, without all the chrome and other clutter.

So I put a WebView control on the MainPage, made sure it fills the whole page and altered its default constructor a bit:

public MainPage()
{
    InitializeComponent();
    WebView.Navigate(new Uri("http://www.bing.com/maps"));
}

Run the application – it should display a nice map of the world. If you have a touch screen, try manipulating the map with your fingers – it' feels nice Winking smile

Metro-style application can be configured to handle any URL protocol

Back to the subject. Open the application manifest configuration screen and navigate to the Declarations tab. Open the Available Declarations dropdown and select Protocol. The protocol will be added to Supported Declarations list box when you click the Add button.

image

Handling declaration properties for Protocol is pretty simple. You’re only required to name the protocol you want your application to handle. For this example, I’m using “locx”.

An optional custom graphics can be used as an application icon whenever the protocol declaration association needs to be displayed to the user (e.g. Control Panel). If not set, application’s Logo image will be used.

Once configured, open App.xaml.cs and override the OnActivated method. This method will get called whenever application is activated. Because an application can be activated for the various reasons, you have to check against the passed arguments for the specific activation kind.

protected override void OnActivated(IActivatedEventArgs args)
{
    if (args.Kind == ActivationKind.Protocol)
    {
        OnProtocolActivated((ProtocolActivatedEventArgs)args);
    }
}

When application is Protocol-activated, the activation arguments should be of the ProtocolActivatedEventArgs type and it should be safe to cast to that. I’ve created the OnProtocolActivated method to handle those cases separately. Note that some other activation scenarios have their equivalent activation methods already built in.

In the OnProtocolActivated method, you’ll have to resolve the Uri that was used for activation. I declared the following Uri format: locx://[view]/[latitude]~[longitude], where view is either roads or aerial. Here’s the method that parses the Uri and calls a specific constructor of the MainPage. That latitude and longitude should be provided using the currently set culture format (commas vs. dots) so they could be parsed into doubles.

private void OnProtocolActivated(ProtocolActivatedEventArgs args)
{
    string type = args.Uri.Host;
    double lat;
    double lng;

    string[] latlng = args.Uri.LocalPath.Substring(1).Split(new[] { "~" }, StringSplitOptions.RemoveEmptyEntries);

    if (latlng.Length != 2 || !double.TryParse(latlng[0], out lat) || !double.TryParse(latlng[1], out lng))
    {
        Exit();
        return;
    }

    Window.Current.Content = new MainPage(type, lat, lng);
    Window.Current.Activate();
}

In overridden MainPage constructor, a Bing maps query is composed and navigated to. Invariant culture is used to convert latitude and longitude to the proper format.

public MainPage(string type, double lat, double lng)
{
    InitializeComponent();
    string uri = string.Format("http://www.bing.com/maps/default.aspx?cp={0}~{1}&lvl=10&style={2}", lat.ToString(CultureInfo.InvariantCulture), lng.ToString(CultureInfo.InvariantCulture), type.ToLower()[0]);
    WebView.Navigate(new Uri(uri));
}

Activation Registration

A very positive thing about activating declarations is that protocol registration will be done when you deploy the application to your computer. That means you don’t need to run the application (as in – the first time) to register the protocol. You can even choose that your application will only support activation and do nothing when launched the ordinary way.

After deploying, you can test your application by invoking the following link from the command line (or Run prompt):

image

image

Of course application will handle any subsequent protocol requests while it’s already running too.

Metro-style application declarations promise a simple integration with the OS through predefined contracts, Protocol is just one of those extensibility points. I’ll look into others in my next posts.



Windows 8 Metro-style application manifest

When you create a new Windows Metro style application, Visual Studio will automatically create the application manifest for you. The file will be called Package.appxmanifest and will be included in the root of the project. Looking at it closer reveals that it’s a plain XML file that can be generated manually or with the help of some other tool as well.

Visual Studio, however, offers a nice GUI editor for editing the application manifest file. This is a quick walk through its tab pages. To invoke the editor, simply double-click on the manifest file or choose Store | Edit App Manifest from the menu.

Application UI

image

The tab for application menu hosts the basic info about your application.

Display Name is the title of your application. It will appear on the start screen, search page, etc., wherever the user can see. It can be localized.

Entry Point should point to the application’s activatable class id. It should be set to project’s App class, but in current build of Visual Studio, changing it to invalid value doesn’t currently seem to affect anything.

Description contains a longer description of your application, but it shouldn’t exceed 2048 characters. It can be localized as well.

Tiles (Logo, Wide Logo and Small Logo) represent the graphics you want to present your application with. The logo is also used as the main tile and the Small Logo is used for lists, etc. The Wide Logo is used when the app requires the wide format tile. Valid format for all graphics are .png and .jpg.

Further down, there are even more options…

image

Show Name and Short Name work in together with the above Display Name. Setting Show Name to Yes and leaving Short Name empty, the Display Name will be displayed on the application tile as an overlay. Set Short name to a custom name and Short Name will be displayed as the overlay.

Foreground Text sets the color of the text displayed on the application tile. In can be set to Light or Dark, for  best fit with the tile graphics.

Background Color specifies the tile’s background color. Can be either named or the ‘#’ color.

Notifications control how the notifications look and work.

Badge Logo points to the graphics that will be displayed on the lock screen as a notification from your application.

Lock Screen Notifications specify what kind of notifications your application will support when the system is locked. Can be set to Tile Text, Badge or both.

Toast Capable should be set to true when you want to send alerts from your application.

Splash Screen options (Splash Screen and Background Color) control the appearance of the splash screen. Splash Screen should point to the splash screen graphics and Background Color specifies the background color for that screen (transparency effects).

Initial Rotation specifies the initial rotation when the application starts. Can be set to all four possible rotations (Portrait, Landscape, Portrait and Flipped, Landscape and Flipped.

Capabilities

The next tab in application manifest editor allows you to set the protected resources you want to allow your application to access. Your application will not have the access to those capabilities if you don’t explicitly set them here, nor they won’t be accessible in cases when hardware does not support it, are blocked through other security policies, or when explicitly denied access by the user herself. Note that the user is prompted about those capability requirements when she is installing your application and can deny those requests. Even later…

Here’s the current list of those capabilities:

image

Declarations

Declarations are your application’s extensibility points, for better integration with the system and/or other installed applications. Some of those extensibility points include:

  • Contact Picker (your application serves as a contact picker for other applications),
  • File Type Associations (registers your app as a (default) handler for a specific file type),
  • File Picker (your app serves as a content picker for other apps; think choosers in Windows Phone),
  • Protocol (your app registers as a URL Protocol handler),
  • Search (provides searching functionality),
  • ShareTarget (for your next social networking application Smile),

… and a few more. All declarations have their own options and settings.

image

Packaging

The Packaging tab holds the info, relevant to deploying and publishing your application.

image

Package Name uniquely identifies the package and therefore your application too. It’s a GUID.

Package Display Name is a localizable package title that is displayed to the users.

Logo points to the application store logo.

Publisher describes the application publisher and matches the publisher subject information from the certificate that is used for signing the application manifest. The value is set automatically when choosing an existing certificate or create a new test certificate.

Publisher Display Name and Package Family Name are also derived from the chosen certificate. Publisher Display Name can be changed and even localized.



Windows 8 applications and JSON data

For anyone that wants to call various JSON data service endpoints in a Windows 8 (Metro style?) application, there’s a couple of changes in “.NET APIs for Metro style apps” (using MSDN terminology here) that needs to be looked into. For this blog post I’m using flickr API as an example of how to fetch and parse JSON data.

Where’s my WebClient?

No, there is no WebClient class in the new API. But…

There’s a HttpClient class that works similar, or even better, by providing an asynchronous method to fetch data. If you’ve looked into the Async CTP bits, the new method should look very familiar.

The new HttpClient class itself resides into the System.Net.Http namespace. Jumping right into the code:

public async Task<string> GetPhotosStream()
{
    HttpClient client = new HttpClient();
    string url = "http://www.flickr.com/services/rest/?method=flickr.photos.search&format=json&nojsoncallback=1&api_key=<yourkey>&text=buildwindows";
    HttpResponseMessage response = await client.GetAsync(url);
    return response.Content.ReadAsString();
}

Shall anyone need it, there is also a synchronous method called Get() that will block until full response message is returned and read on the client.

Other than Get(Async), there are three method pairs more – Get(Async), together with Put(Async), Post(Async) and Delete(Async) forms the full set of verbs supported by REST (Representational state transfer) to manipulate data.

GetAsync() will return a HttpResponseMessage, which contains the returned status code, response headers and returned content, which can be read in a variety of ways.

Parsing JSON

I have rarely used native framework JSON classes (I prefer using JSON.Net), but looking at the new API it looks like there’s quite a few changes here as well.

A returned string can be fed to the JsonObject in its constructor or using Parse() method on its instance. Either way will result in an exception if the JSON string is invalid and couldn’t be parsed.

Once parsed, you’ve got full access to it’s structure. Before I show the code to access it, let’s look at snippet of the returned JSON string:

{
  "photos":
  {
    "page":1, 
    "pages":1, 
    "perpage":100, 
    "total":"13", 
    "photo":
    [
      {"id":"6146549133", ..., "title":"20 Microsoft interns (three from Olin) at this week's BUILD conference", ...},
      {"id":"6146244616", ..., "title":"Internet Explorer", ...},
      ...
      ...
    ]
  },
  "stat":"ok"
}

And this is how you would read the titles of returned photos:

private static List<string> titles = new List<string>();

public static async void ExaminePhotos()
{
    string responseText = await GetPhotosStream();
    JsonObject root = new JsonObject(responseText);
    bool isSuccess = root.GetNamedString("stat") == "ok";
    JsonObject info = root.GetNamedObject("photos");
    int page = (int)info.GetNamedNumber("page");
    int totalPages = (int)info.GetNamedNumber("pages");
    JsonArray photos = info.GetNamedArray("photo");
    for (uint i = 0; i < photos.Count; i++)
    {
        string title = photos.GetObjectAt(i).GetNamedString("title");
        titles.Add(title);
    }
}

While the “Named*" methods return typed values (GetNamedString() returns a string, GetNamedNumber() a double, etc.), it’s also possible to get the JSON value by string indexer and later call to its typed value, e.g. json[“stat”].GetString(), which gets useful if you want to check for its type first.

The second part deals with a JsonArray named photo, which gets enumerated and read in a similar manner.

Wait, isn’t this supposed to be simpler?

Of course, the DataContractJsonSerializer is still here. In fact, it appears to be the same class, just moved into a separate assembly.

To use it, create appropriate classes from the JSON structure (one of utilities that can help) and deserialize JSON string with the help of DataContractJsonSerializer:

string responseText = await GetPhotosStream();

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(RootObject));
RootObject root;
using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(responseText)))
{
    root = serializer.ReadObject(stream) as RootObject;
}

The result is a full object tree that was deserialized from the flickr API JSON string.



First look at Windows 8 application as a developer

It’s been a couple of days since I installed the //build/ preview version of Windows 8 and in this short time I’ve grown to quite like it. It’s an interesting mix of the new Metro style and the “old” Windows 7-like style.

There were two things I’ve just had to install though, to make my life easier while working with Windows 8. The first thing was Total Commander, a file navigation alternative to Windows Explorer, and shortly after that, I installed “Mouse without borders”, the software KVM-like solution that lets you control multiple computers with a single set of keyboard and mouse, share clipboard etc. (for that I had to manually install .NET Framework 2.0 first, though).

The most confusing part about Windows 8 was the mixture of touch and mouse input. I installed Windows 8 on a touch-enabled notebook and was surprised that I could pan, zoom and drag things around, but couldn’t select apps. Tiles responded to tap, but apps just didn’t start and I had to use the mouse to click on them. I’m blaming the missing/incomplete drivers for that and expect it to be fixed by the time Windows 8 gets released. Once I got comfortable working around those issues, I started exploring the new Metro UI, mostly exploring my options for creating my own Metro application.

I took the default Weather application as the example. Funny thing is that at first I couldn’t find a way to change the temperature display to show Celsius instead of Fahrenheit. I started the app and started clicking all over it and eventually found out that right clicking anywhere on the screen (a Metro application takes up the whole screen unless it shares that space with other apps) brings up the Application bar (in touch world, the app bar is displayed by swiping up your finger from the bottom of screen).

image

Application bar

Similar to Windows Phone, Application bar is reserved for command and status buttons. One difference is that buttons are aligned to left and right edges instead of centered horizontally. This makes them easier to reach by your thumb fingers when holding a tablet.

Application bar hosts your command buttons that may change depending on the context - the state your application is in. You can also choose to include more system level commands such as the option to pin the application to the Start screen. Buttons you shouldn’t include in the Application bar are the ones for displaying application's settings and / or search pages. More on that later.

While application bar revealed some helpful options, there was no settings button to be found. Running around with the mouse I found a hot-spot on the bottom-left of the screen (where you’d expect the Start button to be on older Windows). Dragging my mouse to that corner revealed a Start-like menu with the “charm” options: Settings, Devices, Share, Search and Start (in touch world, charms are displayed when you swipe from the right edge towards center).

image   image

Great! Settings!

Settings and preferences

Turned out that settings charm took me to the settings pane that appeared on the right-hand side of the screen, offering me the following options:

  • Rate and Review the application (doesn’t currently work because Windows Store is not available yet),
  • Control system access for Weather (allows user to enable or disable the capabilities required by your application),
  • Weather preferences. That last one was key and the most difficult to find because it looked like some kind of group header. When I discovered that it was selectable, I got into the preferences page that allowed me to change application’s preferences.

image image

Preferences is also one of the custom Settings pages you can implement in your own application. There are a few settings commands you can add to the Settings pane that you map to specific pages, some of those being the About page, Preferences, Help and Privacy statement. From what I found out, only for Settings commands can be displayed in the Settings pane at once, but I’m not sure if that can change depending on your display resolution.

image

You don't need to worry when and how the Settings pane will be displayed, that all is handled by the OS, which means some less work for the developer and, perhaps more importantly, a unified experience across all Metro applications. You only need to implement the way Setting commands display application-specific pages (Preferences, About, etc.)

Search and Share


Search and Sharing contracts are implemented similar to Settings, but go additional step forward. If your application is going to support searching, you can hook up a Search pane, implement required event handlers and provide a custom results page. For Sharing, that would mean to implement the sharing logic. It looks like all application can share their screenshot by default (even if you don’t implement the sharing contract).

image    image

One bonus that Search and Sharing contract provide over Settings is that other applications can use your application as a search or share target. That means that from whichever other application user is currently using, she can search your application (or share her content through it) just by choosing it as a target from her current Search (or Share) pane.

There seems to be quite a few system hooks in Windows 8 that your Metro apps can connect to. Those mentioned above only happen to be the most exposed and accessible in the short run. Clearly it will take some time to get fully familiar with the new Runtime and OS integration and let’s not forget, we’re playing with the preview bits – anything can change in future versions.



Windows 8 geolocation API: First run

Microsoft Windows 8 OS was finally revealed this week at Microsoft’s //build/ conference. It looks like a promising OS, with Metro style theme showing all over it.

image

If you want to install it, look it up on the MSDN subscriptions site or head over here (limited set of SKUs). If you’re a developer, pick the one that includes the Visual Studio 11 Developer preview (or install tools – available also as a separate download – later).

A lot is about to be said of WinRT, the new Windows Runtime and how it relates to .NET and how developing Windows applications will going to be (dis)similar to developing WPF or Silverlight applications. Skipping that discussion for later, I jumped right into developing tools to see how familiar the new API would look to me and whether my past experience with developing XAML based applications in the past few years would help or not.

Starting with the geolocation API

Having developed a couple of Windows Phone application that used my location as a crucial piece of information, I was curious how the same would be done in a Windows 8 application. I’m posting this as a walkthrough (assuming you installed the Visual Studio 11 Express for Windows Developer Preview):

[A short note before you start: the following is based on the //build/ Developer Preview bits and will most likely change in future versions]

1. Open Visual Studio 11 Express.

2. Create a New Project. A few project templates are available, but let’s start simple and choose a basic C# Application.

image

3. If you’re a XAML developer, you’ll find yourself into a very familiar environment. A big plus on that is that Window designer is loading in the background and not blocking you to fiddle with other things while it loads [yes!]

image

[I’ll look into various settings to control you application’s look and feel in one of my future posts]

4. Similarly to Windows Phone, using a location requires you as a developer, to explicitly declare that your application will require access to the location API. This is set in the application manifest. In a Solution explorer, look for Package.appmanifest item and double click on it to open – the manifest properties window will open.

5. Click on the Capabilities tab. Uncheck the Internet (Client) capability and check Location capability (just under it).

image

You’ve just declared that the application will require the Location capability. Had you not enabled this item, anything access to the location API in the application would have no effect. No errors or exceptions would bi risen, it just wouldn’t work.

6. Go back to the MainPage.Xaml and add a TextBlock named Status into the main Grid (LayoutRoot). This is where you’re going to display the current location.

7. Switch to the code view (quick heads up: the F7 keyboard shortcut is not a default for this one anymore).

8. The core class you’re going to use is called Geolocator. It’s very similar to GeoCoordinateWatcher class from Windows Phone, so working with it should be fairly familiar:

public sealed class Geolocator : IGeolocator
{
  public Geolocator();
  public PositionAccuracy DesiredAccuracy { get; set; }
  public PositionStatus LocationStatus { get; }
  public double MovementThreshold { get; set; }
  public uint ReportInterval { get; set; }

  public event TypedEventHandler<Geolocator, PositionChangedEventArgs> PositionChanged;
  public event TypedEventHandler<Geolocator, StatusChangedEventArgs> StatusChanged;
  public GetGeopositionOperation GetGeopositionAsync();
}

Similar to GeoCoordinateWatcher, it has

  • DesiredAccuracy (Default, High),
  • LocationStatus (Ready, Initializing, NoData, Disabled, NotInitialized, NotAvailable) – with two new values,
  • MovementTreshold,
  • PositionChanged and StatusChanged events,

New in Geolocator are:

  • ReportInterval – the requested minimum time interval between location updates,
  • GetGeopositionAsync() – single call method for asynchronous request for location data.

Noticed the TypedEventHandler event declarations above? What are those? Let’s continue with the example…

9. Set up the Loaded event handler and paste the following code into it:

Geolocator locator = new Geolocator();
locator.PositionChanged +=
new TypedEventHandler<Geolocator, PositionChangedEventArgs>(OnPositionChanged);

OnPositionChanged event handler signature is as follows:

void OnPositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
}

To reflect the TypedEventHandler, you can see that sender is no more a plain object, it’s typed! That means no more unnecessary casting and your code is a tad more error-prone.

10. PositionChangedEventArgs holds a reference to a Geoposition, which is declared as:

public sealed class Geoposition : IGeoposition
{
    public CivicAddress CivicAddress { get; }
    public Geocoordinate Coordinate { get; }
}

While Geocoordinate is similar to GeoCoordinate from Windows Phone (Latitude, Longitude, Altitude, Speed, Heading, Accuracy, etc.), the CivicAddress should contain address data, associated with the reported Geocoordinate. I’m saying “should” because from all address properties (City, Country, PostalCode, State) for my current location (Ljubljana, Slovenia), the API only returns my country code (SI). I’m interested to hear how the same API behaves in other locations around the world so if you’re using it, please let me know.

11. If you try setting the Status label text in the OnPositionChanged event handler, you’ll get the invalid cross-thread exception and that’s because the event gets kicked on the background thread. In order to set the text, you have to invoke that on the UI thread, using the dispatcher. This is the part where things seems to differ the most. There’s a new dispatcher called CoreDispatcher. Declare it on the class level and set to page’s Dispatcher property in page’s constructor. That will guarantee you you can use it from the background thread.

So here’s the full MainPage code:

partial class MainPage
{
    CoreDispatcher dispatcher;

    public MainPage()
    {
        InitializeComponent();
        dispatcher = Dispatcher;
        Loaded += new RoutedEventHandler(OnLoaded);
    }

    void OnLoaded(object sender, RoutedEventArgs e)
    {
        Geolocator locator = new Geolocator();
        locator.PositionChanged += 
            new TypedEventHandler<Geolocator, PositionChangedEventArgs>(OnPositionChanged);
    }

    void OnPositionChanged(Geolocator sender, PositionChangedEventArgs args)
    {
        dispatcher.InvokeAsync(CoreDispatcherPriority.Normal, DisplayLocation, this, args);
    }

    void DisplayLocation(object sender, InvokedHandlerArgs e)
    {
        IPositionChangedEventArgs args = e.Context as IPositionChangedEventArgs;
        Status.Text = string.Format("Country:{0} Lat: {1} Lng: {2}", 
            args.Position.CivicAddress.Country, args.Position.Coordinate.Latitude, 
            args.Position.Coordinate.Longitude);
    }
}

12. You can simplify the InvokeAsync code by using a lambda expression, though it may be a bit harder to read and/or debug:

void OnPositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
    dispatcher.InvokeAsync(CoreDispatcherPriority.Normal,
        (s, a) =>
        {
            Status.Text = string.Format("Country:{0} Lat: {1} Lng: {2}", 
                args.Position.CivicAddress.Country, 
                args.Position.Coordinate.Latitude, 
                args.Position.Coordinate.Longitude);
        }
        , this, args);
}

13. Now try to run the project. This is what you should see:

image

Windows is asking you if this application can use your Location. If user chooses Block, application’s request to access the location is denied. No errors or exceptions would be thrown, it just wouldn’t work. If user allows the access, the app will work as expected.

Note: the user can change this permission any time through the Settings charm: When application is running, move your mouse to the bottom left corner – the menu, similar to start screen should appear.

image

Click Settings and notice the right side bar. Click on the “Control system access for [YourAppName]” – you can change the access settings from there

image         image

If you want to test for access availability status from within the app, check Geolocator’s LocationStatus. In case the location access is disabled, it should be set to NotInitialized (although I expected Disabled).

Another fun fact is that Geolocator is not initialized on it’s instantiation, but only when you actually do something with it. In this case, it initializes when you subscribe to the PositionChanged event. This is also the same code line that will cause application (or Windows RunTime) to pop up that permissions dialog from above. After that line, the LocationStatus should be set to a valid status (Ready if access to location is enabled and NotInitialized if it’s not).

Note: Windows will only ask you for permission the first time it’s required. After that, it’s on user to change this permission. But if you want to test this, go to the Application manifest, Capabilities tab, and re-check the Location capability – that should reset the prompt.

But we’re not done yet.

Subscribing to PositionChanged event will ensure the event handler will be called each time Position is “changed” (that actually depends on your Geolocator’s MovementTreshold and ReportInterval property settings). To stop listening to position changes, you can simply unsubscribe from the PositionChanged event.

But… In a lot of cases, we only want to determine the current location once, instead of continuously tracking it. Fortunately, GetGeopositionAsync method does just that – retrieves the current position and it does it in the asynchronous manner (as suggested by Async method suffix by proposed convention).

And guess what? Async methods are unbelievable easy to handle with the new async / await keyword pair. Let’s give it a try.

14. Change the OnLoaded event handler too look like this:

async void OnLoaded(object sender, RoutedEventArgs e)
{
    Geolocator locator = new Geolocator();
    Geoposition position = await locator.GetGeopositionAsync();
    Status.Text = string.Format("Country:{0} Lat: {1} Lng: {2}",
        position.CivicAddress.Country, 
        position.Coordinate.Latitude, 
        position.Coordinate.Longitude);
}

Geolocator is instantiated as before, but the current position is accessed through the GetGeoPositionAsync() method. And notice how that method is decorated with the await keyword and the whole OnLoaded method with async. The principle will also guarantee you that your code, after that async call, can safely call into the UI thread. No dispatcher needed. And from what I know, there are many async method scattered around the new runtime, it will just make coding so much easier, not to mention the new responsive UI.

Wrapping up

That’s it! My first experience with the new API. So far I love it but porting existing and building new applications will eventually show its real value.

And to just briefly touch on the current hot topic – I really think that desktop application development has just shifted gears, although it’ll take some time to lift off the ground. What we’re looking at is an early preview and it will take some time till release, and event more to a broad Windows 8 adoption.

If you have any comments, questions, suggestions for future posts on the subject, any feedback at all, do not hesitate to contact me.



Bikes, a Windows Phone application for bike sharing systems

My latest Windows Phone application found its way to the Microsoft marketplace.

Bikes is designed to help bicyclists that use city bicycle sharing systems across Europe to find nearest stations, provide some basic info about available bikes and free parking slots for each of those stations.

Here’s a short video:

[Short note: the video about shows how the next version will look like (v1.0.1), current marketplace version is v1.0.0]

The main purpose I’ve decided to create this app was to support the new bicycle sharing system in my city (started May this year), but since the same system is use in other (mostly) European cities as well, I added some of those as well. I’m planning to support other systems and adding more cities in future releases.

You can follow the following twitter account – bikeswp7 – for latest news regarding the app, send suggestions, bug reports and any comments you have.

You can download application directly from the marketplace. If you can’t access the Marketplace link with your desktop browser, here’s another link.



Localizing the August 2011 Windows Phone Toolkit

Great news! A new version of Windows Phone Toolkit was released today. These bits target the “Mango” OS (which translates to SDK v7.1). The “pre-Mango” version (7.0) will follow in a short-while.

Download the Toolkit from Codeplex. Available also on NuGet.

One of the new features coming with this release is localization support. Localized strings are there mostly to support brand new Date and Time converters, but they also include a few strings used by Date and Time picker controls that were available in the previous release.

The strings are localized to 22 languages that are the languages, available the “Mango” OS. Chances are you’re going to be writing an application localized to a “non-Mango” language (yes, there are us who are still waiting!), so here’s a tip how to extend the toolkit localization features to your “unsupported” language. I’ll be using the Slovenian (my native) language as the example.

1. Download the toolkit binaries and source code from Codeplex:

2. Unzip the source code package and open the solution (PhoneToolkit.sln).

3. In Solution Explorer, locate the LocalizedResources folder. Copy the neutral language (US English) control resources file and rename it by appending target culture code to the filename (sl-SI is for Slovenian language):

loc1

4. Open the new ControlResources file by double clicking on it in Solution Explorer. Managed Resources Editor should appear, listing original strings.

5. Take some time and translate all strings into the target language. It will probably take an iteration or two to get it right (have to test it in a real case example). In case of Slovenian language, there’s also a slight problem with missing dual  forms (e.g. there are singular and plural, like 1 hour and >1 hours, but I can’t specify the string for 2 hours), plus some other language specifics I have yet to figure out how to work around them.

loc2

6. Build the project. It should compile (make sure you’re using tools for v7.1).

7. Go to the Bin\Debug folder (or Bin\Release, depending on your build configuration) and locate the sl-SI folder (or the one that matches your culture code). In it, there should be a Microsoft.Phone.Controls.Toolkit.resources.dll file. Copy folder to the safe place on your disk. You’ll need it whenever you start a new project leveraging the Windows Phone Toolkit..

8. You’re done with the Toolkit. Start a new Windows Phone project, add a reference to the new Toolkit, add resource files, etc., and start developing your localized application.

9. Because you’re targeting the unsupported language, don’t forget to add the following line to the application start:

Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

That’s usually the first line in my App constructor. The other usual localization steps apply: Edit .csproj file to add supported cultures, set the neutral language, …

10. After building your application, you’ve got the application package (.Xap file). Before deploying it on your device or marketplace, copy the culture-specific folder containing the new localized dll (from step 7) into it. If you’ve chosen English as the neutral language, the folder with your culture code (sl-SI in my case) should already be in place.

Note: I didn’t have to change the AppManifest.xml file in Xap to include the new localized resource dll, but perhaps it’s a good idea to do so. You may also choose a more convenient method of including the resource file at design time to avoid file copying and changing the manifest file after each build.

11. That’s it! With localized resource file in place, your application should now display Toolkit’s resources in your own language.

loc3

This is a screen shot from the Sample application that comes with the new Toolkit.



On a path to a generic About page

Since every Windows Phone application should have some kind of About page, I wanted to see if I could build a generic page that I would reuse in my other apps. These are a few tips I picked up during building such a page:

1. The About page is rarely accessed so I put it in a separate assembly. This way I took some initial load off the main assembly and the About assembly can now easily be shared with other apps.

2. If you want to display the application icon on your About page, there is no need to create new graphics. Depending on your target size, you can choose from either ApplicationIcon.png (62x62) or Background.png (173x173) icons. To put the icon on your About page, use:

<Image Source="/ApplicationIcon.png" Stretch="None" />

And of course you can specify your own size and adjust the stretching attribute.

But don’t worry about the ApplicationIcon.png not being included in the About page project. With application icons being marked as Content, the contents of a Xap should look something like this:

image

By specifying an external link reference to the ApplicationIcon.png, the icon will be displayed regardless of it not being part of the project that contains it.

3. Static text. This includes titles, labels and text that will likely be the same across every application. If you’re not localizing your apps, you may as be well hard-coding strings into your XAML. But if you are, you would most definitely want to pull them from your resource files. In latter case, the standard localization guidelines apply. Again, don’t worry if your if your localization files are in your main assembly. The application will pick them up correctly regardless (even at design time).

<TextBlock x:Name="PageTitle" 
           Text="{Binding Strings.AboutTitle, 
                  Source={StaticResource LanguageResources}}" 
           Margin="9,-7,0,0" 
           Style="{StaticResource PhoneTextTitle1Style}"/>

4. Dynamic text. This includes the version number, application title and other text that will be unique to every application or its version. Some of these texts could be stored in resource files as well, but let’s look at the alternative options.

If you take a look at the AssemblyInfo.cs file of your main project (you’ll find it in the Properties folder), you’ll see it’s populated with some weird assembly attributes you don’t even care about (that’s because you’re setting and changing them from Visual Studio’s dedicated project properties page, but that’s not the point).
The point is that you can access all of these strings from code. All you have to do is get to the main assembly and read its custom attributes (which is what those lines from the AssemblyInfo file really). Here’s how:

Getting the main / entry assembly

The first thing is getting access to the correct – main (or entry) assembly. There are many ways to do that. At least one of those listed below should play nice with your your application architecture :

Assembly.GetExecutingAssembly() will get a reference to an assembly that’s executing that same code.

Assembly.GetCallingAssembly()will get a reference to an assembly of the method that called into this code.

The above methods don’t work well if the call is originating from the same dll. Exploring further…

Deployment.Current.EntryPointAssembly returns a name of the main assembly in pure string. You can use that to load the assembly with Assembly.Load(System.Windows.Deployment.Current.EntryPointAssembly). This will get you the main assembly, but it doesn’t feel right, so I finally settled with:

Application.Current.GetType().Assembly depends on using the Application static class, but since this is only used for a simple About page, that shouldn’t be  a significant problem.

Reading the attributes

I created the following helper method to read the attributes off an assembly:

private string GetAttribute<T>(Func<T, string> selector)
    where T: Attribute
{
    object[] attributes = assembly.GetCustomAttributes(typeof(T), true);
    if (attributes.Length == 0)
    {
        return "N/A";
    }
    T attribute = attributes[0] as T;
    return attribute == null ? "N/A" : selector(attribute);
}

GetCustomAttributes method overload above will return the only specified type of attribute you’re requesting, and the selector Func will read the value off of it. In the example of getting the Version attribute, here’s how you would use the function:

private string version;
public string Version
{
  get 
  {
    return version ?? 
      (version = GetAttribute<AssemblyFileVersionAttribute>(a => a.Version)); 
  }
}

For the application title, you would use the AssemblyTitle attribute:

private string title;
public string Title
{
  get 
  {
    return title ?? 
       (title = GetAttribute<AssemblyTitleAttribute>(a => a.Title)); 
  }
}

And so on…

And if you’d like, you can even create your own attributes, for example:

[AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
[ComVisible(true)]
public class AssemblyContactAttribute : Attribute
{
    public string Email { get; private set; }
    public AssemblyContactAttribute(string email)
    {
        Email = email;
    }
}

Put that into the AssemblyInfo.cs file, as seen with other assembly attributes:

[assembly: AssemblyContact("myapp@tozon.info")]

and use the GetAttribute method similar to above examples.

You have just decorated your assembly with a new custom attribute that you can pull out at runtime.

By following those four points I was able to completely isolate my About page from main app(s) and adding the About page in my new apps is a matter of seconds. There is some convention involved of course (like the name of resources reference holding class), but I don’t see this as a problem. What do you think?