Detecting orientation in Universal apps (Windows & Phone 8.1)

Working with sensors on Windows Phone is should be a breeze, both thanks to the fine-grained APIs in Windows.Devices.Sensors classes and the higher-level APIs in e.g. the SimpleOrientationSensor. I’ve ran into problems though, and only a workaround would take me forward – hopefully it take can you forward someday too Smile

UPDATE 2014-10-08: As Anthony stated in a comment, storing the sensor in field variable will prevent it from being garbage collected and keep the events coming. Article will be updated with details.

workaround

In theory

The SimpleOrientationSensor is as easy can be – it has a method to GetCurrentOrientation and an OrientationChanged event. I happily created a class in my project that used this a did some actions when orientation changed – man I can’t believe how productive C# devving is.

Reality

Quickly I started running into a big problem: the OrientationChanged event stops getting raised after a short while (around 5 raises – 30 seconds). First I thought it was due to the large and complex web-hybrid app that I was working on, but isolating the problem in a sample app showed the same behaviour.

I started testing around on different devices (Lumia 520, 925, 930 and 1520) and found that the event stops be raised on all of them (except for a few times on the 1520).

The workaround

Creating something a simple as a timer that launches and checks current orientation proved to solve my problems.

Easing my power draining anxiety

[Nice double-meaning title right? Winking smile]

Ok, problem solved, I’m now getting my orientation changed events. All good? Maybe.

What if fetching the sensor and checking for orientation every second drains battery like crazy? We should test!

This is the reason for the third button in the sample, “launch web”. It will simple launch a web page – so we have something real to compare our power consumption measurements with.

You hadn’t missed the power diagnostics had you? It can be found under the ‘debug’ menu:

debug-diagnostics   diag-mem

Of course it’s not an exaxt measurement, but at least it gives you some kind of indication of how battery-friendly your code is.

Running power consumption diagnostics resulted in this graph:

perf-detailed

I’ve circled the three interesting sections; startup, orientation polling and loading a web page. As you can see – loading a web page is (of course) A LOT heavier than polling for orientation. And I think that we can safely assume that in normal app, in which the user navigates around, scrolls, loads content from the web, the power consumption overhead of polling for orientation is negligible. If you have an app that stays alive for long periods of time, you should consider other alternatives for detecting orientation change.

Sample code

The sample app consists of three buttons; one to start listening to the OrientationChanged event, one to launch a timer and poll GetCurrentOrientation, and one for launching the web site.

For me, launching the ‘change’ event listener will result in a few events being raised – but none after that. But the ‘timer’ will keep going forever.

wp_ss_20141006_0001

You can find the code on github.

Please report back if you see different behaviour from the event raiser!

Br

This Post Has 3 Comments

  1. I think you’ll find your problem is caused by the Sensor being garbage collected.

    If you store the sensor in a referenced variable in your class, the notifications don’t stop.
    Conversely, when I tried it your way, they never fired at all.

    1. Hi Anthony,

      You are absolutely right, storing the sensor in a field keeps the events coming.
      Thanks!
      Will update the article

  2. Unfortunately if the device is lying flat and is rotated, the SimpleOrientation value is always either FaceUp or FaceDown. So using this method it’s impossible to determine which way it’s currently rotated if it’s lying flat.

Leave a Reply

Close Menu