Lessons Learned in Windows 8 App Certification

Today, I finally got my first Windows 8 app into the marketplace.  It was certainly not for a lack of trying, however.  I actually failed my first FIVE attempts, but I chalk most of that up to inexperience more than anything else.  This post is meant to shed some light on the issues I faced, so that you might be lucky enough to avoid them.

1. Use the WACK (Windows App Certification Kit)

The first time I was denied, most of it was completely avoidable.  There is an amazing tool called the WACK (Windows App Certification Kit) baked in to Visual Studio 2012 that will analyze your app package for all of the computer-verifiable issues your app may have.  This includes things like:

  • Forgetting to provide all of the appropriate icons.
  • Accurately checking your capabilities vs. functionality.
  • Performance metrics.
  • Many more (the entire list can be found here.)

2. Don’t advertise outside of your app.

In my Settings charm menu, I included an About page.  On this about page, I included a way to get a hold of me if you have comments, suggestions, requests, or discover a bug.  I also included a mention that this same app exists in the Windows Phone marketplace, if you’re interested in that.

THIS IS APPARENTLY A BIG NO-NO.

2.3 Your app must not use its description, tiles, notifications, app bar, or the swipe-from-edge interactions to display ads

The elements of your app’s description, such as screenshots, text, and promotional images must describe your app and not contain additional advertising.

This means that you cannot provide links to your other apps, because this is considered “advertising,” which I guess in its truest definition is accurate.

3. Be prepared for the challenge that Taiwan, South Africa, Korea, and Brazil will present.

More accurately, those four countries require a game to have an age rating verification, and the Windows Store doesn’t do a great job of warning you about this before you submit your app.  (They also don’t offer any guidance on how to accomplish it.)  On one screen, you have the ability to choose from well over 80 countries.

image

On a completely separate screen related to game ratings, they subtly mention that there are four countries that require a game rating:

image

If you don’t put two and two together to make four, you’ll likely get denied for this, so take one of two approaches here:

1)  Take the time to wait for the official ratings boards to get you a certificate that verifies your rating.

2) Submit your app without these four countries initially, and then update the app to support them once you receive your ratings.

Here’s where you can submit an application for each country:

Brazil – DJCTQ

Korea – GRB

South Africa – FPB

Taiwan – CSRR

Summary

So, those are my simple lessons learned from my first Windows 8 app submission.  I hope to have many more in the near future, and I’ll be sure to announce them here when it happens.  If you would like to check out this app I’ve made, you can check it out here:

414x180Promotional

It’s an authentic re-creation of the video poker machines you find in every casino.  I’d love your feedback, your requests for more features, and especially your positive reviews.

Let me know what you think!

Windows 8 Office Hours, Design Help, and Funding

In my time working with software developers on their apps, I’ve found three things to generally be true:

  1. Their app is making great progress, but they’ve hit a technical hurdle that they can’t solve.
  2. Their app is nearly done, but it really needs some UX help and some design sense.
  3. In order to accomplish the goals of the app, they need some funding to buy data, developers, time, resources, etc.

To that end, I’ve constructed a way to try and help you in each of these regards.

Technical Office Hours – I am dedicating every Thursday to helping you with your apps.  Have technical questions?  Bring them (and your code), and we’ll work our way through it.  To sign up for a slot, I’ve started using OHours at http://bit.ly/blankenhours.  You can attend in-person at TechColumbus, or join me via Skype, Lync, or Google Hangout.

Design & UX – I will help guide your app design to the best of my ability, but I’m also partnering with some of the top designers in Columbus to help you take a good app to great.

Funding – I am working directly with TechColumbus, and if you have an idea that interests them (and you’re based in Columbus), they might just be interested in investing in you.  Come talk to me.  I think you’ll be surprised what you can do.

Finally, if you haven’t found it already, check out Generation App.  You’ll find free technical and design support via phone, as well as contests and giveaways just for building apps.

31 Days of Windows 8 | Day #31: Design

This article is Day #29 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.

advertisementsample

Today is the last day of this series, and we’re going to focus on designing Windows 8 applications today.  You might be asking yourself:

I’m a developer…why would I want to read an article about design?

I’ll tell you why.  Because we developers have been making user interfaces that look like this for decades:

 

The point of this article is to get you to think differently about you user interface, not just the colors and shapes that are user, but the ENTIRE EXPERIENCE.  The way pages show content.  The navigation experience.  Even page transitions.  It all matters now. Here’s more proof, if you need it.  Think, for a moment, about what an app running in Windows 7 looks like.  Any app.  Picture it in your mind.  It probably looks like this:

31-XAML-Win7

If you take a closer look at this diagram, there’s no indication whatsoever about what this app does.  We’ve tended to focus on how we use the app, not what the content is.  Windows 8 fundamentally shifts that idea.  Now think about a Windows 8 application in your mind.  It probably looks more like this:

31-XAML-Win8

In this illustration, the ENTIRE image shows content.  This means that instead of remembering how to use your app, users are far more focused on the content of your app.  This is part of the conversation we’re going to have today.  This article will be divided into several sections, and each section talks about a different part of user interface creation.  Here’s the topics we’ll cover:

  • Content Before Chrome
  • Using The Windows 8 Silhouette
  • Navigation Patterns
  • Fluid Motion
  • Make Touch a Priority

That’s a ton of topics, so let’s get right to it.

Content Before Chrome

In this section, I want to focus on one of the most important lessons in this entire article:

STOP MAKING BUTTONS.

The focus of every screen of your application should be about the content.  If you’re adding buttons, you’re likely doing it wrong.  Here’s a very common scenario:

31-XAML-WithButtons

We have several sections to our application, and we want to provide an interface for our users to get to each section.  In general, most people would say that there’s absolutely nothing wrong with this interface (except that maybe those giant gray boxes should have photos in them.)  The key lesson to remember is that the entire colored block IS the button.  There’s no reason to add the circled arrow icons.  Instead, consider this:

31-XAML-WithoutButtons

By removing the circled arrows, we’ve made the interface cleaner by removing the clutter, we’ve provided the user with a larger touch target for their fingers on touch devices, and given ourselves less to worry about on the page.  “One button to rule them all",” if you will.

When you desperately feel the need to add a button to the screen, ask yourself:

Could this live in an application bar?

If it can, do it.  For more on the application bar, check out Day #4.  In short, let the user tap the content instead of creating another button for them to click.  If an action can be taken on more than one item at a time, use the App Bar to provide contextual actions when multiple items are selected.

Using the Windows 8 Silhouette

It would be a dreary, boring world if every app looked exactly the same.  That considered, it is also difficult for users to learn a new interface with every application that they use.  This is where the idea of a silhouette comes into play.  Take a look at the four different application examples below.  They all present very different content in very different ways, but there’s a uniform experience about them that makes it very obvious to the user where the important content lives.

31-XAML-Silhouette

There are many ways to utilize this familiar silhouette, here are just a few examples:

31-XAML-Silhouette1

31-XAML-Silhouette2

31-XAML-Silhouette3

31-XAML-Silhouette4

All of the previous images follow a familiar format, which makes it easy for the user to figure out how to use your application, while still looking diverse enough to make your app visually unique.  The reason for all of this is because there will be learned behaviors your users will acquire simply from using Windows 8.  They’ll start to rely on the Charms bar.  They’ll start to expect that right-clicking brings up an AppBar with more options.  They’ll try pinching the screen to zoom.  Taking advantage of these silhouettes is another example of the expectations users will have about your application.

Navigation Patterns

As developers, we have a tendency to try to accommodate our users’ needs, almost to a fault.  One example of this that is rampant in both desktop applications as well as the web is this idea:

We need to allow the user to get TO any page, FROM any page.

You do NOT need to do this.  When we provide this type of functionality, we limit the amount of space that can actually be used for the purpose of the app.  Here’s an example of an RSS reader app that practices the “everywhere navigation” pattern (click to enlarge).

31-XAML-RSS

As you can see, an app that is dedicated to reading only uses about 30% of the screen for actual content.  We need to think about our application in a navigational scheme that makes sense for our content, which will almost always be hierarchical or flat.

Hierarchical Navigation

In this style of navigation, we work in a hub-and-spokes model, where the users’ choices move them further and futher from the home page, and using the back button allows them to return backwards through their path before choosing another branch of the tree to travel down.  Like this: 31-XAML-Hierarchical

We build pages with a master/detail structure so that navigation is intuitive and simple to use.  The user should always know where they are in the app, without having to lay an elaborate trail of breadcrumbs for them.  They should be diving into deeper and deeper detail about the original choice they made.  The default News application in Windows 8 is a great example of this hierarchy.

On the home page of the app, I can scroll to the right to see a few articles from each section (Entertainment and Sports are currently shown):

31-XAML-News1

Using Semantic Zoom, the user can easily see all of the categories, and jump to the one they want to read more about.

31-XAML-News2

If I tap on one of the section headers on the main page (like the word Entertainment above the large photo of the woman, Lynn Shelton), I am taken to a new page that contains only Entertainment news.

31-XAML-News3

Finally, and this can be done from anywhere in the app that I see an article, when I tap on a specific article, I am taken to a detail page for that item.

31-XAML-News4

In each instance, there is the presence of a back button which will take me back through my previous choices.  What you don’t see, however, is the ability to jump from an Entertainment news article over to a Sports article.  In fact, there’s not even a way to get to the Sports category without using the back button.  That is, until you take a look at the AppBar for this app.

31-XAML-News5

There, you’ll see that they succumbed to the need to let the user navigate quickly between sections without cluttering up the screen with all of this navigation.  The AppBar is a great way to provide some of these navigation mechanisms without taking away from the visual appearance of your application.

This is a hierarchical navigation pattern.  Learn to use it.  It will be your friend, and clear your screen of all of the navigation elements you would need otherwise.

Flat Navigation

Flat navigation is something that you see every day in your web browser.  You also see it in instant messaging apps, and other places that have similarly formatted, but somewhat unrelated content.  A picture would look like this:

31-XAML-Flat

When we navigate a website, we’re using this flat navigation style.  We can move forwards and backwards, but there is really no concept of branches in this format.  Since you’re likely using a web browser to view this article, I’m going to assume you know what I’m talking about.

Fluid Motion

Motion is one of those things that we never think about as developers.  We tend to focus on the important topics, like data, and never really consider how much nicer our app would look if it incorporated a little animation.

When I talk about animation, however, I’m not talking about it for visual adornment.  It’s not a decoration that you slap on your page.  Animation should be purposeful.  If you can use animation to transition between screens of your app, your user will perceive load times to be shorter, and feel that your app is faster and more responsive than it actually is.

In addition, there are a bunch of animations available to you with minimal effort.  Check out this article on Animating Your UI from MSDN.

Make Touch A Priority

A “tap” and a “click” in Windows 8 are the same thing.  It requires no effort on your part to make touch happen.  Making your click targets big enough for a finger, however, does.  Always, always, always make anything on your page that is clickable larger than 48 x 48 pixels.

Incorporate gestures where possible.  Your users will expect them.  It requires minimal extra effort, and it lets your users interact with your app the way they expect to:

31-XAML-Touch

In addition, it’s important to remember that because your users will be touching the screen, this also means that there are optimal places to put your buttons and content.  Generally, a user will hold a tablet horizontally, with their thumbs hovering over the two sides of the tablet.  This means your primary buttons should probably live in these regions as well.  What shouldn’t live there is your content.  If the user’s thumbs are hovering over this region of the screen, this also means they can’t see what is happening on that region of the screen.  Here’s a good rule of thumb:

 31-XAML-Occlusion

Summary

In this article, we covered some of the important things you should be thinking about when you start building, and more specifically designing, your Windows 8 applications.  There are tons of additional resources at

http://design.windows.com

and you should definitely make a trip over to the site to check them out.  There are additional design patterns, UX guidelines, Adobe Photoshop templates and much more.

This article also puts the finishing touches on this lengthy series, and we want to sincerely thank each of you that have taken the time to read our words.  There are many reasons to write an article series like this, but our primary reason is that it’s an amazing excuse to dive deep into a technology stack and really understand it.  My second reason, however, is you, the reader.  Clark and I have made our best effort to understand each of these topics thoroughly, and explain them in a “no assumptions, start from the beginning” manner.  You, our readers, bring us comments and questions that we hadn’t anticipated, and for that, we truly are thankful.

Please leave comments and questions on our articles.  These will continue to live on as excellent learning resources for developers looking to build Windows 8 apps, and your contributions only make them that much better.

Thanks.

31 Days of Windows 8 | Day #30: Store

This article is Day #30 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.WindowsStore

Wow, here we are finally talking about the Store. This is really our last step ( and a very exciting one no less ) in your development process. Today we’re going to share with you some of our steps and experience in not only helping others get their apps into the store, but also submitting our own.

If you’ve gotten to this point, then no doubt, these are exciting times. Whether you’re a few code slingers at Rovio making Angry Birds or someone like me who was building an app on the nights and weekends, it’s exciting. If you’ve have an app in the Store, I would also invite you to share in the comments the things that have worked well for you, and not so well.

Microsoft announced just a few short days ago, that they’ve sold 40 million licenses of Windows 8 in it’s first month of life. I don’t know about you, but that’s a pretty big audience for some indie developer like me. The Store is our new platform for us to ship our software to.

For purposes of today, we are only going to talk about the public facing Microsoft Store. If you feel you fall outside of that scenario, say you’re an enterprise developer and might like to deploy through group policy, I would suggest start by reading the Managing Client Access to the Windows Store.

To the Store

Now to get in the store, you have to have to first be signed up as a individual developer ($49 USD) or a company ($99 USD). Once signed up, you can then start reserving app names. Now I know this might sound a bit like duh, of course, but maybe you already have an idea but just haven’t started it. Nothing is stopping you from creating your account and reserving those application names now. Now unlike all of those domain names you’ve been buying over the years and just parking until you get time, you have 1 year from the time of reservation to shipping. If you don’t release anything, then that reserved name goes back into the pool. As someone who has a few apps reserved, it’s a pretty good incentive program for me.

Pre-Certification

If for some reason you’re new to this notion of a “store” or “marketplace” concept, as developers once we finish our app we have to go through a certification process before our application will be officially published. While this may seem somewhat cumbersome, this certification process is really there for everyone’s benefit. Having been through it, the first time you submit your app the minutes can feel like hours but in the end it’s the right thing.

Of course the certification process is both automated and manual. For the Microsoft Store you as the developer have access to the same automated tools (WACK) which are used once you’ve submitted to the store. This allows you to go through the process before you’ve ever submitted addressing any potential issues.

The Windows App Certification Kit or WACK is really two different kits; one kit for Intel based processors and another one for ARM based processors. These kits are tools that you would of course install on a test system which will run through the same automated process that the Microsoft Store would do from it’s servers. The beauty about these kits you can run them on yourself before you ever submit your application to the marketplace. As I said this really helps to ensure you’ve cut down any issues long before submitting to the store, ultimately cutting down your certification time if you we’re to have any issues.

After starting the Windows App Certification Kit you have 3 different categories of apps that you can select. For our apps we would select the validate Windows Store App option. Once selected, you’ll be asked as to what application you want to validate.

SNAGHTML2a9a1b2d

Once you pick out your application, the WACK tool will start running. It will start to run a variety of tests against your application and even do things like open it, to see how long wait times are. After it’s completed, you will get a detailed report as to what was validated. Of course just like in TDD, green is good and red is bad. Below is just a snip from a failed event report.

image

The WACK tool provides a very detailed report as to its findings. Having said you should run it across all of the platforms you expect to run on, as your load times on a low power ARM device might be a lot longer than that of a multicore Intel machine. It’s also not a replacement for hard core testing, both manual and automated. Just saying…

It’s also true, when you submit there is still a potential for failing the certification. Now Microsoft has released a pretty good document which details a number of the most common certification failures but make sure you have read through the certification requirements such that you’re not surprised.

One of the biggest reason apps fail is certification requirement 4.1. 4.1 states that an app with the Internet Access capability checked must provide a policy policy to the Store. Of course this means you might have to setup a simple website just to contain the privacy policy required. If you’re not using the internet, just uncheck it.

TIP

All of the Visual Studio templates for the Windows Store create the shell of an app but with the internet capability.enabled. If you’re *not* using the internet – uncheck it and save yourself the hassle.

App Images

Like it or not, the first thing your potential customer will see is an image of your application  in the store. In fact, there are a number of different images your user might see depending on where the store app has placed your application.image Now mind you, this is all before your potential customer has even installed it, so make sure you have some great store appeal is a good thing.

During day 1 when we talked about the blank application, we discussed a number of different images you needed to include in your application. These were things like the store logo, small tile, wide tile and so on.

As it turns out, when you try and submit your application, you’re not done with the image creation process. At the time of submission you will be asked for a number of new logos that will be used by the store specifically. They are not part of your app’s package, they are images uploaded directly to the store. Specifically these images are your billboard images as well as screenshots of your application.

Making logos is clearly an art form. To help make things a bit easier, a friend of mine build a number of Photoshop templates around these Store submission graphics. I would encourage you to check them out as they could save you a number of hours.

Whatever you do, please, please, PLEASE replace all of the default images. Now I do not know who wrote Backgammon Gold nor am I not trying to place a dig on all the hard work they’ve done. But, I would never spend $4.99 on something where someone hasn’t even taken the time to replace the default Visual Studio images. I’m not saying, but I’m saying. Clearly their rating proves my point.

image

Making Money

Your monetization model is clearly something that only you can determine. While charging outright for the application is one way, there are many creative ways as well. The minimum price someone can charge for an application is $1.49 USD with increments starting at .50 USD.

While charging upfront is a clearly an easy way to make some coin, it’s not the only and it might not be the best depending on your scenario. What about offering the user a time-limited trial, or a feature-limited trial? Remember the goal is to make money and getting user to test drive your app isn’t a bad thing. There are a number of studies written about how trials have a much higher conversion rate that ones without trials. You don’t buy a car without driving it first, why not test drive an app?

Another very popular mechanism for making money is an ad supported model. This is nothing more than putting some ad container in your applications such that you’re displaying ads to your customers. While you can use any ad platform you wish (assuming they adhere to Microsoft’s certification requirements ) Microsoft offers an ad sdk from Microsoft Advertising which will get you easily up and running on Microsoft’s platform.

Lastly offering the ability for an in app purchase shouldn’t be out of your reach either. Using a game app example, one could offer more levels once the user got to a particular point in their journey just for a bit more money. I personally think this is a pretty interesting scenario as it gives you the ability to get people using your app, but offers them the ability to purchase something more full featured.

Now when you’re making most of the money, the Microsoft Store is doing all of this legwork for you, hosting the bits, transitions, currency conversions etc.  As you might expect there is a cut that Microsoft needs to take just to offer such support. For your first $25k Microsoft will charge you a 30% fee, but after your app makes $25k, that fee will drop to 20%. These are just a few of the items you will find in the app developer agreement.

Creating the package(s)

Creating the packages for the store is a painless process. There is basically two reasons to create a package, sideloading or WACK testing OR to upload to the store. The difference between the two different packages is really one is signed with your developer account whereas the other isn’t.

To get started, Project –> Store –> Create App Packages… As you can see, the first dialog box you’re presented with is in fact the two different options we just mentioned.

SNAGHTML1006b5c3

If we’re building a package for the Store. Then our next step is to select what our app name was in the store such that we can associate things correctly.

image

Regardless of what direction we choose first the next step in the process is picking what platform we want to build for. These will be the packages we will later either sideload or upload to the store.

SNAGHTML100afd09

And once created all of your glory should look something like:

image

For more information about sideloading please see this article: http://technet.microsoft.com/en-us/library/hh852635.aspx

Ready to submit

Submitting your application is mostly just a one page web form you’re required to fill out. These are things like, description, search keywords, release date and so on. The Windows Store team has done an excellent job of documenting everything, so I won’t rehash that here but rather ask you to please read their article.

App Update(s)

You’ve pushed and now you need to fix up a bug. Well, thankfully you’ve already been through the entire process already. Now it’s just a matter of creating a new release and changing anything that might be now applicable. Oh yea, of course you would need to update the new package too.

Summary

Honestly submitting your app into the store is the easy part. All of the planning and development that’s been done to this point has really been the hard part. While you have a plan in mind about how you may make money, don’t be afraid to think outside of the box and try a few different things. You never know what will net you the best results.

Tomorrow, we’re going to talk about our last day in this series which is focused on design.

downloadTheTools

31 Days of Windows 8 | Day #29: Application Lifecycle

This article is Day #29 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.

advertisementsample

Today, we’re going to talk about Application Lifecycle.  I wish there were a cooler word for this topic, but ultimately we’re looking at the management of the different states our application can be in on a user’s device.  Here’s an illustration (image from MSDN):

29-XAML-LifecycleDiagram

The reason that this is important to us as developers of Windows 8 applications is because we want to provide a seamless user experience in our apps.  When a user presses the Windows key on their machine, and leaves your app, you want to make sure you save or preserve their data in some way, so that when they come back, it’s all still there.

I Thought Windows Handled This Automatically??

Yes and no.  By default, if you run a Windows 8 application, leave it, and come back, it will automatically be exactly where you left it.  However, if you leave it, and then open 6 or 7 more applications, it’s likely that the operating system is going to suspend your application, or even terminate it.  Thankfully, there’s a couple of great mechanisms we can use to manage this.

Recognizing Your App Has Been Suspended

According to Microsoft, “an app can be suspended when the user switches away from it, or when Windows enters a low power state.  Most app stop running when the user switches away from them.”  There’s a few things you need to know about how your app will end up in a suspended state:

  • Your app “might” be suspended.  For the simple app I’ve built for this article, I’ve never seen it enter a suspended state on its own.
  • Generally, when the system runs out of resources, this is the time your app will enter a suspended state.
  • When you leave an app to use another, Windows will wait a few seconds before suspending it, just in case you were planning to return to it quickly.
  • If you need to execute any code before your application is suspended (we’ll talk about how next), you get a total of 5 seconds before your app is assumed to be unresponsive and terminated instead.  Keep this in mind…web service calls are probably not the thing to do.

So, if you’re anything like me, you’re probably wondering how we are going to write and test some code that only occurs when Windows feels like making it happen. Thankfully, there’s some tools for that.

First, let’s write some code.  On each page that a user might provide some input (whatever type of data), we can add an event handler that gets called when our app is suspended.  In the code below, I have created this event handler, and saved two values to local storage when it is called.

using System;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
 
namespace Day29_ApplicationLifecycle
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        ApplicationDataContainer settings;
 
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            Application.Current.Suspending += Current_Suspending;
            settings = ApplicationData.Current.LocalSettings;
        }
 
        void Current_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
        {
            settings.Values["suspendedDateTime"] = DateTime.Now.ToString();
            settings.Values["customTextValue"] = CustomText.Text;
        }
 
        protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
            Application.Current.Suspending += Current_Suspending;
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

You’ll notice, that like with all event handlers we create, I also remove it when the OnNavigatingFrom event is called.  We covered saving data on Day #8, so I won’t spend any time explaining that, other than to say that we are saving the time our app was suspended, as well as any text that was currently entered into a TextBox that I have on my MainPage.xaml page.  In order to verify this information has been saved, let’s add the Resuming event next.

Recognizing That Your App Is Resuming

In this case, we’re going to add a Resuming event, just like we did with the Suspending one.  When the method is called, I’m going to write the date and TextBox content back to the screen, so that the user can continue working on their data.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
 
namespace Day29_ApplicationLifecycle
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        ApplicationDataContainer settings;
 
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            Application.Current.Suspending += Current_Suspending;
            Application.Current.Resuming += Current_Resuming;
            settings = ApplicationData.Current.LocalSettings;
        }
 
        void Current_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
        {
            settings.Values["suspendedDateTime"] = DateTime.Now.ToString();
            settings.Values["customTextValue"] = CustomText.Text;
        }
 
        void Current_Resuming(object sender, object e)
        {
            Message.Text = "Resumed.  Was suspended atnn" + settings.Values["suspendedDateTime"];
            CustomText.Text = settings.Values["customTextValue"].ToString();
        }
 
        protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
            Application.Current.Resuming -= Current_Resuming;
            Application.Current.Suspending += Current_Suspending;
        }
 
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

How In The World Do I Test This Scenario?

Because this is a tough scenario to make happen automatically, there are tools inside Visual Studio that allow us to simulate these states in our application.  First, make sure that you’ve opened the Debug Location toolbar in Visual Studio.

29-XAML-DebugLocation

Once you’ve added that toolbar, it’s as simple as choosing one of these three options:

29-XAML-Suspend

  • Suspend will immediately put your application in a suspended state.  This will also fire your suspended event handler before it stops running.
  • Resume will obviously resume your app from a suspended state.  If your app is not suspended, nothing will happen.
  • Suspend and shutdown will simulate what happens when Windows terminates your application.  The suspended state will happen first, followed by a complete shutdown of your app.

If we use these buttons on the application we’ve created in this article, you’ll get an experience similar to the one in this short video:

 

In short, this is how we manage data on a page-by-page basis.  If you’re looking to do things at the overarching application level, you can take a look at your App.xaml.cs file.

Using App.xaml.cs to Manage the Lifecycle

There are already two methods sitting in your App.xaml.cs file, and you’ve already used them in previous days of this series.

  • OnLaunched is called when your application is launched normally.  This will not be called when your application is resumed, as the user will be taken directly to the page they were on previously.
  • OnSuspending is called AFTER your page event is called, but is also called when the application is suspended by Windows 8.  Saving any of your application-level data should be done here.

These methods provide you a little more power on a global level, but you’re still going to need to rely on your page level events for most of the state preservation you’re going to attempt.

Summary

In short, we want to provide a seamless experience for our users, so keep the lessons in this article in mind.  Don’t overdo it, though.  Saving unsaved data for a user is a convenience, so unless you think it will be important, don’t exhaust yourself trying to anticipate everything the user might need.

In games, if the user leaves, and they have to replay a level, so be it.  You don’t have to remember that they were jumping over that block to make it a great experience.  Remember which level they were on is probably enough.

If you would like to download the sample app that uses the code from this article, click the icon below:

downloadXAML

 

Tomorrow, we’re going to dive into the Windows Store, and give you all of the information you’re going to need to get your app available for sale.  See you then!

downloadTheTools

31 Days of Windows 8 | Day #28: Push Notifications

This article is Day #28 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.

advertisementsample

Today, we are talking about Push Notifications.  In the previous 27 days, Clark Sell and I have generally approached each problem the same way, but from a different technology stack.  Today, he has followed a pretty traditional development path, where I am going to introduce you to some of the amazing services that are available from Windows Azure.  Neither approach is right or wrong, and if you read both articles, you might even find that you like parts of each.  With that, let me introduce you to Windows Azure Mobile Services.

There are several steps we’re going to have to take here to get everything set up, so let’s start with setting up a free Windows Azure account at http://www.windowsazure.com.

Click the “try it free” button, and register for an account.

28-XAML-FreeTrial

I’m not going to take you through every step of signing up for a free trial account, we’re going to make the leap and assume you can figure it out.

For those of you that are MSDN subscribers, you get Azure for free already!  Head over to http://msdn.microsoft.com and click the “Access Benefits” link.

28-XAML-MSDN

In your Subscription Benefits, you will find access to Windows Store developer account access, Windows Azure access, and several other great benefits.  Click the “Activate Windows Azure” link on the Benefits page, and follow the instructions to register.

Now That You Have A Windows Azure Account…

You’ll also need to add Mobile Services to your account (again, it’s free.)  Head over to https://account.windowsazure.com/PreviewFeatures to activate the Mobile Services Preview.  It looks like this:

28-XAML-MobileServices

You’ll notice that mine has already been activated, but your button will say “try it now” and one click will get the ball rolling.

Now That You Can Use Azure Mobile Services…

Let’s actually create a new mobile service to use with our eventual app.  Go to http://manage.windowsazure.com and log in.  Click the giant “New +” button at the bottom of the screen:

28-XAML-NewMobileService

Make a couple of choices, so that you’re setting up a new Compute > Mobile Services item.

28-XAML-Create

In the first step of the creation process, you need to give your service a name.  I’ve named mine “day28-pushnotifications”, and specified that I will use a new SQL database instance.  If you’ve already been using Windows Azure before, you can choose one of your existing databases instead.

28-XAML-CreateAMobileService

Next, we need to specify our database settings, like database name, username, and password.

28-XAML-SpecifyDatabaseSettings

Once you’ve completed these steps, we’ll need to set up our database.

Now That You Have A Database & Mobile Service…

We now need to configure our data source, so that we have a database table to use.  Open your mobile service from the Windows Azure Portal, and choose the DATA tab.  It should look like this:

28-XAML-AddTable

Click the “ADD A TABLE” link, and give your table a name.  In my case, I’ve named the table Element:

28-XAML-CreateNewTable

Once you create your table, open it, and click on the COLUMNS tab, like this:

28-XAML-ColumnView

You’ll notice that this table only has an ID column.  I just want you to make a note of that…we’ll address it later.

Now That You Have a Database Table Set Up…

We’re finally going to start building our Windows 8 application.  You could certainly do this in either order, but I started with Azure just to mix it up.  Our next step is to register our application with Windows Live, so that it can take advantage of the Notification Services.   (You do not need a Windows Store developer account to do this.) Head over to:

http://manage.dev.live.com

and create a new application in the system, like this:

28-XAML-CreateApplication

The name of your app in this system isn’t terribly important, but it should be meaningful so that you remember which is which.  Once your new app is created, click on it in the dashboard (like above), and choose “Edit Settings.”

28-XAML-EditSettings

In your settings, choose API Settings, and you will be shown two important values: “client secret” and “Package SID.”  Keep these open in a seperate browser tab, or write them down, because you’re going to need them to make this all work.

Now That You Have Your Secret and SID…

It’s probably time to actually start building our actual Windows 8 application.  Create a new blank project in Visual Studio 2012, and then right-click on the project name, looking for the “Store” menu option.  Click the “Associate app with the Store…” option, and follow along with these screens:

28-XAML-Associate1

28-XAML-Associate2

Once you log in with your Windows Live ID, you will see a list of the apps you created earlier, at http://manage.dev.live.com.  I’m choosing the Day28 one that I created there.

28-XAML-Associate3

28-XAML-Associate4

Finally, click the Associate button, and you’re done.  You’ve now associated your Windows 8 app with the app listing on http://manage.dev.live.com.

Now That You’ve Associated Your App With Store…

It’s time to update our Mobile Service, so that it has the credentials necessary to talk with this app via Push Notifications.  Jump back to http://manage.windowsazure.com, open your Mobile Service, and choose the PUSH tab, like this:

28-XAML-WindowsApplicationCredentials

Take the “client secret” and “package SID” values from earlier, and enter them into these two boxes.  I’ve blurred my values out, but you should get the idea.  This allows us to then talk directly to the application without any other necessary steps.

Now That Everything Is Finally Configured…

We can return to our application, and actually start writing some code.  Since all of this setup actually made it possible to use Azure as our remote database as well, we’ll start there.  Open your App.xaml.cs file, where you need to add a few lines of code:

public static MobileServiceClient MobileService =
new MobileServiceClient("https://day28.azure-mobile.net/", "VbUeYTHISISFAKESRRlKSRLqfqXQBmhVqq54");

public static PushNotificationChannel channel { get; private set; }

private async void GetPushChannel()
{
    channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
}

That first line of code references the name of your service that you created, as well as your “application key.”  This can be found by opening your service in the Azure portal, and clicking the “manage keys” button at the bottom of the screen, like this:

28-XAML-Dashboard

And then grabbing your Application Key from this dialog box:

28-XAML-ManageAccessKeys

Obviously, I haven’t shown you my keys, but yours should be a jumble of letters and numbers.  Finally, you’ll want to call your new GetPushChannel() method from our App.xaml.cs file’s OnNavigatedTo event handler.

Now That You’ve Opened A Push Notification Channel…

We’re nearly home free.  To stick with the “elements” theme that many of the articles in this series used, we’ll be storing Element objects in our database that we created earlier. First, I need a new Element class.  Mine looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Day28_PushNotifications
{
    class Element
    {
        public int Id { get; set; }
        public double AtomicWeight { get; set; }
        public int AtomicNumber { get; set; }
        public string Symbol { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public string State { get; set; }

        [DataMember(Name = "channel")]
        public string Channel { get; set; }
    }
}

You can see that I have added a bunch of properties, but there’s only two that are really important to our mission in this article: Id and Channel.  The ID value is meant to match the Id field we already have in our new database by default, and the Channel value will hold the Channel URI that gets set up when our application executes the code that we added to our App.xaml.cs file earlier.

Now That You’ve Set Up A Custom Class…

One last step before we can write the last bit of code in our project.  You need to download the Mobile Services SDK, and install it as part of Visual Studio 2012.  Download the Mobile Services SDK by clicking here.  I really feel like I should have had you do this earlier, but I couldn’t find a good place to add it in the flow.  I’m using lazy loading in my writing as well.  We’re adding this so that we have a simple client-side mechanism for communicating with our service.

Now That You’ve Installed the Mobile Services SDK…

To keep it simple, I’ll just tell you that I’ve added a simple Button control to my MainPage.xaml file, and added a click event to it that calls AddElementButton_Click().  I’ve also needed to add a new reference to my project that was a part of the Mobile Services SDK.

Right-click on your References folder in your project, and choose “Add Reference…”

28-XAML-AddReference

In the window that opens, choose the Windows Azure Mobile Services Managed Client, and click OK.  This will add the reference to your project, and allow us to add a new using statement to our MainPage.xaml.cs file:

using Microsoft.WindowsAzure.MobileServices;

 

By adding this namespace, we’re able to interact directly with our data tables in Windows Azure.  To make a simple insert into the Element table that we created so long ago, here is the syntax we can use:

Element element = new Element { AtomicNumber = 1,
                                AtomicWeight = 1.01,
                                Category = "Alkali Metals",
                                Name = "Hydrogen",
                                Symbol = "H",
                                State = "Gas",
                                Channel = App.channel.Uri };
await App.MobileService.GetTable<Element>().InsertAsync(element);

 

 

As you can see, it takes two lines of code to make an insert into our database.  In fact, if you open your Windows Azure Portal to your Mobile Service’s DATA tab, you can see the records appear dynamically.  Here’s a quick video to illustrate that:

 

So at this point, we now have a very simple application that inserts data into our Azure database.  But wasn’t this article about Push Notifications?  Where are we headed?  Before we get there, here’s the entirety of my MainPage.xaml.cs file, so you can see exactly what’s happening in the code in the video:

using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Day28_PushNotifications
{
    public sealed partial class MainPage : Page
    {
        int counter = 0;
        List<Element> elements;

 

        public MainPage()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            CreateElementList();
        }

 

        private async void AddElementButton_Click(object sender, RoutedEventArgs e)
        {
            Element element = elements[counter];
            element.Channel = App.channel.Uri;
            await App.MobileService.GetTable<Element>().InsertAsync(element);
            counter++;

            if (counter >= elements.Count)
                counter = 0;
        }

        private void CreateElementList()
        {
            elements = new List<Element>();
            elements.Add(new Element { AtomicNumber = 1, AtomicWeight = 1.01, Category = "Alkali Metals", Name = "Hydrogen", Symbol = "H", State = "Gas" });
            elements.Add(new Element { AtomicNumber = 2, AtomicWeight = 4.003, Category = "Noble Gases", Name = "Helium", Symbol = "He", State = "Gas" });
            elements.Add(new Element { AtomicNumber = 3, AtomicWeight = 6.94, Category = "Alkali Metals", Name = "Lithium", Symbol = "Li", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 4, AtomicWeight = 9.01, Category = "Alkaline Earth Metals", Name = "Beryllium", Symbol = "Be", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 5, AtomicWeight = 10.81, Category = "Non Metals", Name = "Boron", Symbol = "B", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 6, AtomicWeight = 12.01, Category = "Non Metals", Name = "Carbon", Symbol = "C", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 7, AtomicWeight = 14.01, Category = "Non Metals", Name = "Nitrogen", Symbol = "N", State = "Gas" });
            elements.Add(new Element { AtomicNumber = 8, AtomicWeight = 15.999, Category = "Non Metals", Name = "Oxygen", Symbol = "O", State = "Gas" });
            elements.Add(new Element { AtomicNumber = 9, AtomicWeight = 18.998, Category = "Non Metals", Name = "Fluorine", Symbol = "F", State = "Gas" });
            elements.Add(new Element { AtomicNumber = 10, AtomicWeight = 20.18, Category = "Noble Gases", Name = "Neon", Symbol = "Ne", State = "Gas" });
            elements.Add(new Element { AtomicNumber = 11, AtomicWeight = 22.99, Category = "Alkali Metals", Name = "Sodium", Symbol = "Na", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 12, AtomicWeight = 24.31, Category = "Alkaline Earth Metals", Name = "Magnesium", Symbol = "Mg", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 13, AtomicWeight = 26.98, Category = "Other Metals", Name = "Aluminum", Symbol = "Al", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 14, AtomicWeight = 28.09, Category = "Non Metals", Name = "Silicon", Symbol = "Si", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 15, AtomicWeight = 30.97, Category = "Non Metals", Name = "Phosphorus", Symbol = "P", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 16, AtomicWeight = 32.06, Category = "Non Metals", Name = "Sulfur", Symbol = "S", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 17, AtomicWeight = 35.45, Category = "Non Metals", Name = "Chlorine", Symbol = "Cl", State = "Gas" });
            elements.Add(new Element { AtomicNumber = 18, AtomicWeight = 39.95, Category = "Noble Gases", Name = "Argon", Symbol = "Ar", State = "Gas" });
            elements.Add(new Element { AtomicNumber = 19, AtomicWeight = 39.10, Category = "Alkali Metals", Name = "Potassium", Symbol = "K", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 20, AtomicWeight = 40.08, Category = "Alkaline Earth Metals", Name = "Calcium", Symbol = "Ca", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 21, AtomicWeight = 44.96, Category = "Transitional Metals", Name = "Scandium", Symbol = "Sc", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 22, AtomicWeight = 47.90, Category = "Transitional Metals", Name = "Titanium", Symbol = "Ti", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 23, AtomicWeight = 50.94, Category = "Transitional Metals", Name = "Vanadium", Symbol = "V", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 24, AtomicWeight = 51.996, Category = "Transitional Metals", Name = "Chromium", Symbol = "Cr", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 25, AtomicWeight = 54.94, Category = "Transitional Metals", Name = "Manganese", Symbol = "Mn", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 26, AtomicWeight = 55.85, Category = "Transitional Metals", Name = "Iron", Symbol = "Fe", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 27, AtomicWeight = 58.93, Category = "Transitional Metals", Name = "Cobalt", Symbol = "Co", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 28, AtomicWeight = 58.70, Category = "Transitional Metals", Name = "Nickel", Symbol = "Ni", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 29, AtomicWeight = 63.55, Category = "Transitional Metals", Name = "Copper", Symbol = "Cu", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 30, AtomicWeight = 65.37, Category = "Transitional Metals", Name = "Zinc", Symbol = "Zn", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 31, AtomicWeight = 69.72, Category = "Other Metals", Name = "Gallium", Symbol = "Ga", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 32, AtomicWeight = 72.59, Category = "Other Metals", Name = "Germanium", Symbol = "Ge", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 33, AtomicWeight = 74.92, Category = "Non Metals", Name = "Arsenic", Symbol = "As", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 34, AtomicWeight = 78.96, Category = "Non Metals", Name = "Selenium", Symbol = "Se", State = "Solid" });
            elements.Add(new Element { AtomicNumber = 35, AtomicWeight = 79.90, Category = "Non Metals", Name = "Bromine", Symbol = "Br", State = "Liquid" });
            elements.Add(new Element { AtomicNumber = 36, AtomicWeight = 83.80, Category = "Noble Gases", Name = "Krypton", Symbol = "Kr", State = "Gas" });
        }
    }
}

Now That You Have Database Transactions…

We can test out the old Push Notifications.  For this example, we are going to send a toast notification that shows the name of the element we inserted.  There are millions of ways we could handle this, but ultimately, we’re building something that is triggered by a database transaction, which is likely how you are going to build your push notifications as well.

Remember, push notifications will come from our service, not from our app, so we’re headed back to the Windows Azure Portal at http://manage.windowsazure.com.  Open your mobile service, click the DATA tab, and then choose your data table, which in my example is named Element.  When you are viewing the table, flip over to the SCRIPT tab, where you will see something like this:

28-XAML-InsertScript

By default, you’ll be looking at the INSERT script for our database.  This JavaScript code will be executed every time a record is sent to the database.  We are going to modify this script (yes, I know it’s JavaScript, but it’s our only option.)  If you click the ? button in the bottom right corner, there are some excellent tutorials on doing different kinds of transactions, like:

28-XAML-Help

Anyways, I’ve modified my INSERT script to determine if my record was successfully inserted, and if it was, to send a push notification to the channel that was stored with that record.

function insert(item, user, request) {
    request.execute({
        success: function() {
            request.respond();
            push.wns.sendToastText02(item.channel, {
                text1: "(" + item.AtomicNumber + ") " + item.Name + " - " + item.Category,
                text2: item.Symbol + " | " + item.AtomicWeight + " | " + item.State + " | "
            }, {
                success: function(pushResponse) {
                    console.log("PUSH sent:", pushResponse);
                }
            });
        }
    });
}

 

If you will recall back to Day #10, when we worked on Toast Notifications, there were several different Toast templates that we could use.  This code uses those exact same templates.  In this example, I’m using ToastText02.  I set the text values of Text1 and Text2, and then write a success statement to my log file.

Updating this script is ultimately what sends your toast messages for you, and you can get as elaborate as you’d like.  For example, perhaps you save all of the “channels” that are sent to your database in one table, and then when your data changes (let’s say you’re a weather app, and you just got a new record indicating a blizzard is on the way) you could create a loop that would send a notification to every channel that is affected, based on other data in your database.

In short, the sky’s the limit.

Now That You’re Sending Push Notifications…

One last thing.  Remember how we had to update our package.appxmanifest file to allow toast messages on Day #10?  That still applies here.  Open your file, and choose “Yes” to make your app Toast Capable.  Without this, you’ll never see the beautiful toast messages that are being sent to your machine.

28-XAML-ToastCapable

Once you’ve made that change, every time you click the button in your application, you’ll not only be inserting a record into your Azure database, but you’ll also be sending back a Toast Notification to the user’s machine. Amazing.

Summary

Today, we took a look at Push Notifications by way of Windows Azure Mobile Services.  If you’re building an app that is going to have online data storage, push notifications, and even potentially multiple clients, like iOS, Android, or others, this will become an invaluable tool for you.  As I took this process apart, I was absolutely amazed at how easy everything was, and how integrated the experience is for us as developers.

If you would like to download my sample application that uses the code from this article, click the icon below:

downloadXAML

Tomorrow, we’re going to look at the lifecycle of an app, and the many ways that a user can open, as well as return to, your app.  See you then!

downloadTheTools

31 Days of Windows 8 | Day #27: Inclinometer

This article is Day #27 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.

advertisementsample433

Today, we are taking a look at our final sensor, the Inclinometer.  In many ways, it is similar to the Motion class from Windows Phone.  Ultimately, it aggregates several of our other values about the X, Y and Z axes to calculate three very important values: Pitch, Yaw, and Roll.  If you’ve ever even dabbled in aviation, you’ve heard these values incessantly.  They refer to the rotation around those three axis values.  Here’s a more visual example:

PITCH

YAW

ROLL

200px-Aptch[1] 200px-Ayaw[1]

200px-Aileron_roll[1] 

For more information on the principal axes of aircraft, check out this Wikipedia article.

In our case, however, we’re not talking about aircraft.  We’re talking about a Windows 8 device.  More specifically, we’re talking about the axial rotation of a Windows 8 device.  Thankfully, the same structure that we’ve seen from our other sensors still applies here.

It’s truly as simple as creating a new sensor object, registering an event handler to catch the data that comes from the sensor, and then one method to actually do something with said data.  Here’s how my Inclinometer code looks in my MainPage.xaml.cs file:

using System;
using Windows.Devices.Sensors;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
 
namespace Day27_Inclinometer
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        Inclinometer inclinometer;
 
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            inclinometer = Inclinometer.GetDefault();
            if (inclinometer != null)
            {
                inclinometer.ReadingChanged += inclinometer_ReadingChanged;
                Data.Visibility = Visibility.Visible;
            }
            else
            {
                NoSensorMessage.Visibility = Visibility.Visible;
            }
        }
 
        private async void inclinometer_ReadingChanged(Inclinometer sender, InclinometerReadingChangedEventArgs args)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                PitchValue.Text = args.Reading.PitchDegrees.ToString();
                RollValue.Text = args.Reading.RollDegrees.ToString();
                YawValue.Text = args.Reading.YawDegrees.ToString();
                TimeStamp.Text = args.Reading.Timestamp.ToString();
            });
        }
    }
}

 

As you can see in our example, we receive Pitch, Yaw, and Roll values in degrees, making it very simple to build calculations and animations into our apps using this data.  As with all of the sensors in your application, you must make sure that the user’s device contains the sensor before you try to use it.  Every Win8 device will be different, and it’s up to you to use the right sensor for the right job.

Summary

Today, we took a quick look at the last available sensor in our series, the Inclinometer.  Specifically designed to calculate the Pitch, Yaw, and Roll values of our user’s device, this sensor will be an invaluable tool for anyone building an application that uses rotation-based physics of any kind.  Pitch, Yaw, and Roll also become incredibly handy in tracking the position of the user’s device when performing augmented reality applications as well, eliminating what is commonly referred to as “drift".

If you would like to download a working sample to test on your own device, click the icon below:

downloadXAML

Tomorrow, we’re going to make the turn to the home stretch, with only 4 articles remaining.  We’ll kick the finale of this series off with Push Notifications, followed by some excellent guidance about getting your app to shine.  See you then!

downloadTheTools

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

31 Days of Windows 8 | Day #26: Gyrometer

This article is Day #26 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.

advertisementsample

Today continues our adventure through the world of sensors, and today we are looking at the Gyrometer.  The Gyrometer, or gyroscope, measures rotational velocity.  So, while the Accelerometer measures the acceleration around three axes, the Gyrometer measures the velocity of rotation around those axes.  Like this:

220px-Gyroscope_operation[1] Now, I’m not suggesting that there’s a little spinning widget inside your Windows 8 device.  Generally, mobile devices and tablets use a MEMS gyroscope, which uses vibrations or resonance to determine their data.

The gyroscope is also another one of those sensors that you’re going to get “sometimes.”  As you can see in the video below, some devices have one, and some don’t.  This is going to be a common theme with any sensor in Windows 8, because it is so terribly backwards compatible.

 

When Windows Phone 7 came out, every device was new, and there were stringent requirements about the sensors that had to be included in every device.  When it comes to the PC world, however, Windows 8 can be installed on practically any computer that was created in the last 5 years.  This makes it hard to get a consistent hardware set across devices, but doesn’t mean you shouldn’t support these sensors.  Many of the new machines that are now being offered DO include these sensors, which means as time moves forward, a higher percentage of computers will support your efforts.

In addition, if you’re attempting to do any kind of augmented reality in your app (where you look through the device like a window on the real world, with additional data like store ratings or popularity added to the display), the gyrometer will be exceptionally helpful in keeping you oriented.

Getting Data From the Gyrometer

In the past few articles, we’ve seen that getting data from a sensor follows a familiar pattern.  We create a new sensor object, we create an event handler, and then we grab the resulting data from the event handler’s method.  Today is no different, but I’ve added a little “pizazz” by visualizing the data as well.  In my XAML file, I’ve included three Line controls inside a Grid.

<Grid x:Name="ContentPanel" Margin="429,78,12,0">
    <Line x:Name="xLine" X1="240" Y1="350" X2="340" Y2="350" Stroke="Red" StrokeThickness="4"></Line>
    <Line x:Name="yLine" X1="240" Y1="350" X2="240" Y2="270" Stroke="Yellow" StrokeThickness="4"></Line>
    <Line x:Name="zLine" X1="240" Y1="350" X2="190" Y2="400" Stroke="Blue" StrokeThickness="4"></Line>
</Grid>

These lines will extend in three different directions, driven by the Gyrometer data.  Here’s the entire contents of my MainPage.xaml.cs file:

using System;
using Windows.Devices.Sensors;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
 
namespace Day26_Gyrometer
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        Gyrometer gyrometer;
 
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            gyrometer = Gyrometer.GetDefault();
            if (gyrometer != null)
            {
                gyrometer.ReadingChanged += gyrometer_ReadingChanged;
                Data.Visibility = Visibility.Visible;
            }
            else
            {
                NoSensorMessage.Visibility = Visibility.Visible;
            }
        }
 
        async void gyrometer_ReadingChanged(Gyrometer sender, GyrometerReadingChangedEventArgs args)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                XValue.Text = args.Reading.AngularVelocityX.ToString();
                YValue.Text = args.Reading.AngularVelocityY.ToString();
                ZValue.Text = args.Reading.AngularVelocityZ.ToString();
                TimeStamp.Text = args.Reading.Timestamp.ToString();
 
                xLine.X2 = xLine.X1 + args.Reading.AngularVelocityX * 200;
                yLine.Y2 = yLine.Y1 - args.Reading.AngularVelocityY * 200;
                zLine.X2 = zLine.X1 - args.Reading.AngularVelocityZ * 100;
                zLine.Y2 = zLine.Y1 + args.Reading.AngularVelocityZ * 100;
            });
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

In this example, you can see that I’m doing some simple math to change the X and Y values of the Line controls, so that they reflect the Gyrometer data that is being captured.  In case you’re curious, the reason the zLine has both its X and Y values changed is because it is set at an angle, which requires manipulation of both coordinates of one end of the line.

Ultimately, you’re going to find far more interesting ways to use this data than I have, so I’m looking forward to hearing what you’ve created!  Leave a comment on this post when you’ve got something.

If for nothing else, if you’re building a game that might have achievements or badges, I think it’s always cool to add ridiculous awards for hitting a certain number on a sensor.  Have some fun with it.  It’s certainly easy enough, right?

Summary

Today, we took a look at the Gyrometer (gyroscope) and how we can read the data from this sensor in Windows 8 app development.  Another sensor available on Windows 8 devices, it’s going to give you smoother, more accurate data about the movement of the device than the Accelerometer, but they both are excellent tools for the job.

If you would like to download the sample code from this article, click the icon below:

downloadXAML

Tomorrow, we’re going to cover the last sensor in this series, the Inclinometer.  Much like the Motion class from Windows Phone, this sensor aggregates some of the other data we’ve talked about to generate Pitch, Yaw, and Roll values from our device.  See you then!

downloadTheTools

31 Days of Windows 8 | Day #25: Accelerometer

This article is Day #25 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.

advertisementsample4

Today, we’re looking at yet another sensor available in Windows 8 devices, the Accelerometer.  It measure the acceleration of the device on 3 axes, X, Y, and Z.

The X axis runs horizontally across the device.  The Y axis runs vertically across the device.  The Z axis runs immediately through the device, from front to back.  Here’s an image to help illustrate, using a Windows Phone as the example (courtesy of http://www.andybeaulieu.com/):

25-Accelerometer

In simpler terms, we’re measuring the g-forces applied to those three axes.  Because of this, when we lay a Windows 8 tablet flat on a table, we get a Z axis value of –1, because there is one “g” (one unit of gravity) exerting itself on the negative size of the Z axis.  In the same way, if we propped our device up (similar to the phone in the photo) so that the bottom of the device is sitting on the table, we would get a Y axis value of –1.

So how do we gather these values?  Very similarly to how we have interacted with the past few sensors.  We create an Accelerometer object, we add an event handler, and we read the data when it changes.  Here’s my entire MainPage.xaml.cs file:

using System;
using Windows.Devices.Sensors;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
 
namespace Day25_Accerometer
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        Accelerometer accelerometer;
        int shakes;
 
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            accelerometer = Accelerometer.GetDefault();
            if (accelerometer != null)
            {
                accelerometer.ReadingChanged += accelerometer_ReadingChanged;
                accelerometer.Shaken += accelerometer_Shaken;
                Data.Visibility = Visibility.Visible;
            }
            else
            {
                NoSensorMessage.Visibility = Visibility.Visible;
            }
        }
 
        async void accelerometer_ReadingChanged(Accelerometer sender, AccelerometerReadingChangedEventArgs args)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                XValue.Text = args.Reading.AccelerationX.ToString();
                YValue.Text = args.Reading.AccelerationY.ToString();
                ZValue.Text = args.Reading.AccelerationZ.ToString();
                TimeStamp.Text = args.Reading.Timestamp.ToString();
            });
        }
 
        async void accelerometer_Shaken(Accelerometer sender, AccelerometerShakenEventArgs args)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                shakes++;
                ShakeCount.Text = shakes.ToString();
            });
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

If you have been following along with this series, this should look really familiar.  If you haven’t, you can see that we’re using the ReadingChanged event handler to grab our data values from the Accelerometer object, and then using the Dispatcher to write those values to our UI thread.

The one major difference you should notice is the new Shaken event handler.  Some accelerometers support this function, and others don’t, but we just don’t get any data when it’s not supported (it’s basically just a meta-calculation that approximates when the user’s device has been shaken similarly to how you might shake an Etch-A-Sketch to erase the screen.)  If you’re going to use this event, be sure that the user is using a device that supports it, like the Microsoft Surface.

You can certainly use the X, Y, and Z values to determine a shake on your own, so the Shaken event will likely not be of huge value to you until it is more widely supported.  By using these values, however, you can do some pretty impressive math.  Think of games like Labyrinth, and how you can use the angle of the device to determine where the objects on the screen should move.  I think there are tons of applications for this, and I’m looking forward to seeing what you create.

Summary

Today we took a look at the Accelerometer sensor, and how we can use it to grab data about the orientation and acceleration of the device on three different axis directions.

If you would like to download the sample application that uses the code from this article, click the icon below:

downloadXAML

Tomorrow, we’ll continue diving into sensors with the Inclinometer.  It allows us to measure the angle of incline for a Windows 8 device on the same three axes.  See you then!

downloadTheTools

31 Days of Windows 8 | Day #24: Light Sensor

This article is Day #24 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.

advertisementsample

Today, we are taking a look another one of the sensors we might find in a Windows 8 device: the Light Sensor.  With the Light Sensor, we can determine the brightness of the light around the user’s machine, and help to accommodate things like contrast, brightness, and other values that would make our app easier to read in high and low light.

I’ve put together yet another horribly produced video to show you how a light sensor works, and what kinds of values we can expect:

 

To make this application work, we’re going to follow a very similar pattern to the one we used yesterday for the Compass sensor. 

  • Initialize the Light Sensor.
  • If it’s available, create a ReadingChanged event handler.
  • In the event handler, grab the data from the sensor and write it to the screen.

Here’s my entire MainPage.xaml.cs file:

using System;
using Windows.Devices.Sensors;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
 
namespace Day24_LightSensor
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        LightSensor sensor;
 
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            sensor = LightSensor.GetDefault();
            if (sensor != null)
            {
                sensor.ReadingChanged += sensor_ReadingChanged;
                Data.Visibility = Visibility.Visible;
            }
            else
            {
                NoSensorMessage.Visibility = Visibility.Visible;
            }
        }
 
        async void sensor_ReadingChanged(LightSensor sender, LightSensorReadingChangedEventArgs args)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                Lux.Text = args.Reading.IlluminanceInLux.ToString();
                TimeStamp.Text = args.Reading.Timestamp.ToString();
            });
 
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

There’s nothing surprising about getting this data, but I was surprised to see how diverse the values on different machines (that were sitting next to each other) could be.  For instance, my Qualcomm ARM device (the one featured in the video above) generally rated the room I’m currently sitting in around 59 lux.  My Samsung tablet, however, which is a Windows 8 Pro device, rates this room around 42 lux.  Finally, my Surface RT device says this place is about 115 lux.

This is likely due to the accuracy and quality of the light sensor in each device, but in general, they’re really not that far apart on the scale of lux values.  Here’s an example from the Wikipedia article on Lux.

24-XAML-LuxChart

As you can see, even 100 lux is still a pretty dim value.  Just flipping the lightswitch on in my office jumped my sensor values up closer to 175.  Using the chart above, however, you should be able to create “ranges” of values that behave differently depending on the brightness of the light available.

For example, if you recognize that the user is in a low-light environment, you might switch their display to show a dark background and white text, because that is easier to read in that kind of light.  In a bright room, you might want to switch to black text on a white background.

In either case, you now know how to recognize the data from the light sensor, and use it effectively in your app.

Summary

Today we talked about the Light Sensor, and how it can be used to alter a user’s interface to make it more readable.  Ultimately, there are dozens of creative ways to leverage the lux data in your applications, and I’m looking forward to hearing how you’ll use it in your app.

If you’d like to download my working sample that uses the code from this article, click the icon below:

downloadXAML

Tomorrow, we’re going to get involved with a more robust sensor, the Accelerometer.  We can use this data to determine the rotation of the user’s device.  See you then!

downloadTheTools