Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Enable automatic daylight / night mode switch with your Windows Phone 8.1 app

Sample source code is available for download.

You know those fancy car GPS navigators that automatically switch color mode to dark when it gets dark to make it easy on your eyes? The display even turns dark when you drive into a tunnel and lights back up when you’re out…

Well, with ambient-light sensor support in the latest Windows Phone 8.1 SDK, it’s possible to build something quite like that. The new API is quite straightforward and follows the same practice as with other device sensors.

When your app starts, you should first query the device for the sensor to see if it exists. The GetDefault() method will return null if sensor isn’t present on the device or the system was unable to get a reference to it (happens when device is in a connected standby):

var sensor = Windows.Devices.Sensors.LightSensor.GetDefault();
if (sensor == null)
{
    return;
}

Once having access to the sensor, it’s recommended to set its reporting interval to default value, but in cases where you need to set it explicitly, you can do it by changing sensor’s ReportInterval, but check you’re not going below MinimumReportInterval. Here’s the code for setting it to 5 minutes, but if you need more dynamic readings, just leave it at default:

sensor.ReportInterval = Math.Max(sensor.MinimumReportInterval, 5*60*1000);

[Note: don’t forget to set it back to default – 0 – when you’re done]

To start reading, you can either perform a one-time read:

var reading = sensor.GetCurrentReading();

… or subscribe to continuous reads (with read interval set earlier):

sensor.ReadingChanged += OnLightSensorReadingChanged;

Either way, you’ll get a LightSensorReading with information about the current reading. The illuminance level returned by this is in lux so it should be easy to compare with some known values. I figured 500 – 1000 would be a good value to detect a decent daylight and in this example I’m testing against a value of 1000 lux.

We have the ambient light level, now what?

There are various cases where light sensor could come in handy, here’s a couple:

1. Allow user to have it’s theme respond to light, e.g. have light theme during the day and dark theme during the night. Reading apps, for example.
Luckily, in Windows Phone 8,1, changing theme for a page (or for any specific element) is now very simple. No more 3rd party helpers. Here’s an example of a OnLightSensorReadingChange event handler for the case, where application theme will be according to the latest sensor reading:

void OnLightSensorReadingChanged(Windows.Devices.Sensors.LightSensor sender, Windows.Devices.Sensors.LightSensorReadingChangedEventArgs args)
{
    Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
        () => RequestedTheme = args.Reading.IlluminanceInLux < 1000
              ? ElementTheme.Dark
              : ElementTheme.Light
        );
}

[Notice the relevant line is wrapped in a Dispatcher call – the LightSensorReadingChanged event will always be fired on a background thread so we have to get back to the UI thread to set a visual property properly]

2. Any app that displays a map could use this feature. Navigation apps, locators, running apps, …
And the Map control has a vary handy property to support this, let’s have a look at Map’s ColorScheme:

void OnLightSensorReadingChanged(Windows.Devices.Sensors.LightSensor sender, Windows.Devices.Sensors.LightSensorReadingChangedEventArgs args)
{
    Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
        () =>  Map.ColorScheme = args.Reading.IlluminanceInLux < 1000
               ? MapColorScheme.Dark
               : MapColorScheme.Light;
        );
}

One final note – the same API is available to Windows Store apps as well. Build for both, it’s great Smile

Download sample source code.