kwiQR Application: Retargeting to Windows 8.1

A second app that I have in the Windows 8.0 store is the kwiQR app which is a QR code scanner. I thought that I’d migrate this app to Windows 8.1 as well while I’m away from work and see how common the experience was between migrating the Tile A File app and this app.

The first thing I did was to create a branch off main in TFS so that I could have a Windows8.0 code base to go back to and fix bugs in should I want to maintain that Windows 8.0 code in the future.

The next thing was to retarget the projects to Windows 8.1. The kwiQR app is built out of 2 projects;

image

with one being a variant of the Zebra Crossing library for QR codes that Google builds. I’m not 100% sure I can trace which variant of Zebra Crossing this library is but, regardless, it’s here as a pure .NET library that my main application uses.

Versions

The current Windows 8.0 version of the kwiQR app is a 2.x.x.x version so I moved the Windows 8.1 version to be 3.0.0.0 so that there were quite a few version numbers between Windows 8.0 and Windows 8.1 just in case I want to squeeze in some more Windows 8.0 versions in the future.

The SettingsFlyout

I retargeted those two projects to Windows 8.1 and the only minor problem that I hit was that the app has a dependency on Callisto;

image

for its use of a SettingsFlyout which is exactly the same situation as I found in my previous migration. This time around I decided to bite the bullet and switch my Callisto.Controls.SettingsFlyout to be a Windows.UI.Xaml.Controls.SettingsFlyout and this involved changing a few properties, specifically in my code;

  • SettingsFlyout.IsOpen = True becomes SettingsFlyout.Show()
  • SettingsFlyout.HeaderText becomes SettingsFlyout.Title

With that done, I managed to get a successful compilation but I hit quite a lot of deprecated code. This isn’t a very big code base but I hit;

  • 'Windows.UI.Notifications.TileTemplateType.TileWideImageAndText02' is obsolete: 'TileWideImageAndText02 may be altered or unavailable for releases after Windows 8.1. Instead, use TileWide310x150ImageAndText02.'
    '
  • Windows.UI.ViewManagement.ApplicationView.Value' is obsolete: 'Value may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.UI.ViewManagement.ApplicationViewState' is obsolete: 'ApplicationViewState may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.UI.ViewManagement.ApplicationView.Value' is obsolete: 'Value may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.UI.ViewManagement.ApplicationViewState' is obsolete: 'ApplicationViewState may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.UI.ViewManagement.ApplicationViewState' is obsolete: 'ApplicationViewState may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.UI.ViewManagement.ApplicationViewState' is obsolete: 'ApplicationViewState may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.UI.ViewManagement.ApplicationView.Value' is obsolete: 'Value may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.UI.StartScreen.SecondaryTile.SecondaryTile(string, string, string, string, Windows.UI.StartScreen.TileOptions, System.Uri, System.Uri)' is obsolete: 'SecondaryTile(string, string, string, string, Windows.UI.StartScreen.TileOptions, Windows.Foundation.Uri, Windows.Foundation.Uri) may be altered or unavailable for releases after Windows 8.1. Instead, use SecondaryTile(string, string, string, Windows.Foundation.Uri, Windows.UI.StartScreen.TileSize).
  • '
    'Windows.UI.StartScreen.TileOptions.ShowNameOnLogo' is obsolete: 'TileOptions.ShowNameOnLogo may be altered or unavailable for releases after Windows 8.1. Instead, use SecondaryTile.VisualElements.ShowNameOnSquare150x150Logo.
  • '
    'Windows.UI.StartScreen.TileOptions.ShowNameOnWideLogo' is obsolete: 'TileOptions.ShowNameWideOnLogo may be altered or unavailable for releases after Windows 8.1. Instead, use SecondaryTile.VisualElements.ShowNameOnWide310x150Logo.
  • '
    'Windows.UI.ViewManagement.ApplicationViewState' is obsolete: 'ApplicationViewState may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.UI.ViewManagement.ApplicationView.Value' is obsolete: 'Value may be altered or unavailable for releases after Windows 8.1. Instead, query for window layout sizes directly.
  • '
    'Windows.ApplicationModel.DataTransfer.DataPackage.SetUri(System.Uri)' is obsolete: 'SetUri may be altered or unavailable for releases after Windows 8.1. Instead, use SetWebLink or SetApplicationLink.'

Ok – so in short this sounds to me like 3 things – snapped views, creating secondary tiles and the share contract. Looks like I have a little bit of work to do there.

On the SettingsFlyout I also found that I needed to set the Background color of the flyout and also its RequestedTheme in order to get it to line up with the way that the Callisto version of the SettingsFlyout used to work. Other than that, settings seemed to be resolved.

Icons/Logos/Tiles

It didn’t seem that I’d been quite as lazy with this kwiQR app in terms of providing scaled logos at the point when I’d built the application package but, as you’d expect, because Windows 8.1 introduces the new 70×70 and 310×310 tile sizes I didn’t have specific imagery in my project to cope with that.

image

and nor did I have all the right imagery to deal with the small 30×30 logo at its 4 target sizes;

image

and so I had 12 new images to create for the 70×70, 310×310 and then the 30×30 at 4 target sizes. This takes a little time but it’s not too hard.

Dealing with Snapped View

The idea of kwiQR is that the user can scan a QR code which might contain a web URL, a telephone number, an email address, a contact card and then they can “action” that scanned content either immediately or at a later point. For example, “actioning” might mean launching a web browser to view a web URL or launching an email client to email the address from the code.

To help with this the app did support a snapped view which felt like a useful thing to have in that the app can be positioned on the left hand side of the screen and then used to “launch” multiple pieces of content.

Unlike the previous Tile-A-File app then I wanted to preserve this idea of a snapped view for kwiQR and so I set the minimum app size down to 320px.

image

This “sort of works” in that for a page like the application’s main page I have the regular view which is GridView based;

image

and then if I size that down to 320px then the old Windows 8.0 APIs are still doing their thing and my UI changes to be more ListView based;

image

However, I need to move away from the APIs that the app is currently using to drive these state transitions and this app is different from the Tile-A-File app in that I made use of the LayoutAwarePage base class which used to ship in the Windows 8.0 templates. There’s nothing wrong with using that but it means that I’m going to have to rework that base class a bit so that it no longer relies on Windows.UI.ViewManagement.ApplicationView.Value which is deprecated.

Instead of relying on that value and having four possible states – FullScreenLandscape, FullScreenPortrait, Snapped, Filled I made modifications to that base class.

I also have code in this app which is querying Windows.UI.ViewManagement.ApplicationView.Value in order to figure out (probably incorrectly) whether the device is portrait. It is doing this in order to decide whether an image from the camera needs rotating to display properly. Interestingly, under Windows 8.0 this worked fine but under 8.1 that Value property returns FullScreenPortrait for the situation shown below which doesn’t seem quite ‘right’ to me;

image

and it breaks my code because the app thinks the camera is being held at a 90 degree rotation when it’s not – the app would override this by querying the SimpleOrientationSensor but on the particular PC I’m developing on there is no sensor so the app gets the rotation wrong.

Instead of relying on ApplicationView.Value I switched that code to try and rely on DisplayInformation.CurrentOrientation and DisplayInformation.NativeOrientation although it would be nice if that class could give me an angle representing to what extent it thinks the device is rotated from its natural orientation.

Launching Apps

When the kwiQR app has captured a QR code (containing a web URL, a phone number, a contact card, an email) it has an option to either automatically launch the system’s default application for that item that it has captured.

In the case of all but a contact card, this is done via the Launcher.LaunchUriAsync() method whereas for a contact card the app builds a VCARD file and then uses Launcher.LaunchFileAsync() to launch the system’s default app to handle the contact card.

Either way, the likelihood is that the user would want the kwiQR app to get out of the way and let the launched app take over a good portion of the screen so the new feature that comes with Windows 8.1 whereby a launching app can hint as to how much screen space it needs once it has launched a second app makes sense here. In both cases, I changed the code such that when the app uses the Launcher it specifies LauncherOptions such that it asks for the minimum amount of the screen to be given to itself when it launches an app.

That means that the user has an experience like;

image

and then when they launch a URI they get;

image

Pinning Tiles

One of the features that kwiQR has is an ability to pin a second tile to the Start Screen such that the user can launch straight into the “capture a QR code” page which uses the camera.

If the user just wants to capture a QR code quickly then rather than having to run the app and get the first page;

image

and then tape on the “Add” button highlighted to jump to the camera page;

image

they can pin the camera page to their Start Screen using the “Pin Tile” button highlight in the picture above.

The way in which the app actually pins the tile is to use the constructor for the SecondaryTile class which takes TileOptions to control whether the tile should show the name on the logo and the wide logo.

That constructor is now deprecated as part of Windows 8.1 and so I replaced it with a call to the constructor which takes 5 arguments and added some additional code to set the various properties of the VisualElements property to sensible values. As part of that work I also added a 30×30 logo and a 310×310 logo in case the user wanted to make a small/large secondary tile and so if the user was really nuts about the app (it seems unlikely Smile) then they can have two big tiles on their start screen;

image

Tile Notifications

One of the slightly spurious things that kwiQR does is that if the user has captured N QR codes then it attempts to cycle the last 5 codes captured through its wide tile in order to have that feeling of being “alive” and being “aware” of what the user has been doing. The idea here was that if the user was mobile and captured 3 QR codes for URLs from magazines or similar then the tile would at least be active enough to show the user that they had captured 3 codes and the details of what those codes were. The tile also displays that number 3 as a badge;

image

As above, the user can see that they scanned a QR code which was a hyperlink to www.microsoft.com and they scanned it on the 18th March 2013 (or at least that’s what the test data says!).

There are two problems with doing this now that the app is building for Windows 8.1;

  1. The app only displays this information on a wide tile. It was probably “ok” to not attempt to display the info on a 150×150 tile (and certainly not on a 30×30!) but it’s probably not ok to omit this information from the newly added 310×310 tile.
  2. The app is using the TileTemplateType.TileWideImageAndText02 type of tile and, once again, this has been deprecated in Windows 8.1.

As the MSDN page details, because of the addition of 310×310 tiles in Windows 8.1 the XML schema used for tile notifications has changed. There are now 2 versions of the schema – V1 and V2 and my code (which uses its own helper class to generate tile XML) is generating a V1 schema. The older templates have now been renamed and hence the deprecation of TileWideImageAndText02 which is now TileWide310x150ImageAndText02. Naturally, the OS maintains backwards compatibility by picking up the use of a V1 schema notification and translating it into a V2 version automatically but a V1 notification schema can’t update a large (310×310) tile.

I moved my use of TileWideImageAndText02 to use TileWide310x150ImageAndText02.

Alongside doing that I also wanted to build up code that added these notifications to a 310×310 tile – specifically the TileSquare310x310SmallImagesAndTextList01 seemed to fit well but this involved some additional logic. For the original wide tile I select up to the top 5 most recent QR codes scanned by the app and submit up to 5 tile notifications into the wide tile which has queueing enabled so that it will simply roll around those (up to) 5 notifications.

However, for the 310×310 tile I can potentially show the details of 3 QR codes on each tile update so that means (with queueing) there’s room for up to 15 QR codes across 5 tile updates and so the logic had to change a little there – it wasn’t too difficult to do but it added a little code to that part of the app to handle up to 15 QR codes across 5 queued tile notifications.

Sharing Web URLs

The last piece of deprecated code that Visual Studio showed to me was a call to DataPackage.SetUri. In my app, this happens if a user has scanned a QR code that represents a URL and then wants to share it with some other app as below;

image

this API is now deprecated having been replaced by DataPackage.SetWebLink so that was a pretty easy change to make.

Submitting to the Store

I have a few more tests to do on this app and then I’ll submit it back to the Store. My recent submission of the updated ‘Tile a File’ app took about half a day or so to get certified so I’m hoping that the Store guys can keep up that rapid response and I should have a new version of this kwiQR app for Windows 8.1 pretty quickly.