In the previous two posts (Light sensor and Compass), I’ve shown how to use the sensors in a UWP app. Working with them is very easy and it can enhance the usability of your app. In this post, we willshow how to use another sensor, the Inclinometer.

This sensor is used a lot for games, as it detects the inclination of the device. That way, the user can control the game by tilting the device. Pretty cool, no? It’s note a pure sensor, as you won’t have an inclinometer in your device, but it gets its data from other two sensors, the accelerometer and the gyroscope.

The sensor usage is similar to the other sensors, and it shows three measures, Yaw (the rotation on the Z axis), Pitch (rotation on the X axis) and Roll (rotation on the Y axis):

inclinometer

(source – https://msdn.microsoft.com/en-us/windows/uwp/devices-sensors/sensors)

Playing with a ball in UWP

To show the usage f an inclinometer, we will create a project that can be a starting point for a game. We will draw a ball in the window and, depending on how the user tilts the device, the ball will move faster or slower, to the left and to the right.

We will start creating a new UWP blank app. Change the main element in the main page to a Canvas and add a new Ellipse to it:

[sourcecode language=”xml” padlinenumbers=”true”]
<Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Ellipse Width="80" Height="80" Fill="Red" x:Name="Ball"/>
</Canvas>
[/sourcecode]

In the constructor of the MainPage, we position the ball and add the code to initialize the inclinometer and set its ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
Loaded += (s, e) =>
{
Canvas.SetLeft(Ball, ActualWidth / 2 – 40);
Canvas.SetTop(Ball, ActualHeight – 80);
var inclinometer = Inclinometer.GetDefault();
if (inclinometer == null)
{
return;
}
inclinometer.ReadingChanged += async (s1, e1) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var position = Canvas.GetLeft(Ball);
var newPosition = position + e1.Reading.RollDegrees;
if (newPosition ActualWidth – 80)
newPosition = ActualWidth – 80;
Canvas.SetLeft(Ball, newPosition);
});
};
};
}
[/sourcecode]

As you can see, this time I’m doing all the initialization in the handler of the Loaded event of the page. That’s because ActualWidth and ActualHeight of the page aren’t set before the Loaded event fires, and if I don’t use this handler, the ball would be placed in the wrong place. As we have a Canvas, we position the ball with the attached properties Left and Top. In the code behind, this is done with the static methods Canvas.SetLeft and Canvas.SetTop.

The next step is to get the Inclinometer sensor with GetDefault and set its ReadingChanged handler. It will get the current position of the ball and will set the new position depending on the Roll (number of degrees of tilt in the Y position). That way, if the user tilts more, the ball will move faster. If he tilts less, it will move slower.

With that code in place, we have our moving ball project complete and can run it. If your device has an inclinometer, you can see the ball moving. If it doesn’t have, you can use a Windows Phone and see the same app running there.

image

Conclusions

Using the inclinometer is very simple and you can provide your users a different kind of input with it, you just need to get its reading and move the elements in your app according to the tilt of the device.

The source code for this app is in https://github.com/bsonnino/MovingBall

In the last post, I have shown how to use the light sensor to get light data and offer a better experience for the user. In this post, I will show another sensor available in 2-in-1 devices and tablets: the compass. The compass is a sensor the shows the direction, related to the magnetic north.

On physical compasses, this reading is given by a magnetic needle that is always pointing to the magnetic north. When you turn the compass, it will show you where are you heading to. In computers and smartphones, there is no magnetic needle, but the sensor shows the angle of the device, related to the magnetic north. To use the sensor, we must create a program that does the same three steps of the last post:

  • Get an instance of the sensor with the GetDefault method
  • Set its properties
  • Set a handler for the ReadingChanged

In this post, we will create a program that simulates a physical compass and shows the heading of the device.

Creating a compass simulator in UWP

The first step is to create a blank UWP project. In this project, add images tor the compass background and needle (I got my background from http://www.clipartbest.com/images-of-a-compass and the needle from http://www.clker.com/clipart-compassnorth.html) in the Assets folder.

Then, add the two images to the main window:

[sourcecode language=”xml” padlinenumbers=”true”]
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Image Source="Assets\\Compass.png" HorizontalAlignment="Stretch"
           VerticalAlignment="Stretch" Stretch="Uniform"/>
    <Image Source="Assets\\Compassnorth-Hi.png" HorizontalAlignment="Stretch"
           VerticalAlignment="Stretch" Stretch="Uniform" x:Name="Needle"/>
</Grid>
[/sourcecode]

In the constructor of MainWindow, we must get the compass and set the ReadingChanged event handler:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
var compass = Compass.GetDefault();
if (compass == null)
{
return;
}
compass.ReadingChanged += async (s, e) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
RotateNeedle(e.Reading.HeadingMagneticNorth);
});
};
}
[/sourcecode]

The event handler just calls RotateNeedle, passing the reading angle as parameter. RotateNeedle is very simple:

[sourcecode language=”csharp”]
private void RotateNeedle(double angle)
{
var transform = new RotateTransform() { Angle = angle };
Needle.RenderTransformOrigin = new Windows.Foundation.Point(0.5, 0.5);
Needle.RenderTransform = transform;
}
[/sourcecode]

It just creates a RotateTransform, setting the angle to the reading angle, sets the origin of the rotation on the middle of the needle and then sets the RenderTransform property to this transform.

With this, you have a compass simulator that works both on desktops and smartphones. As you turn the device, the needle will be pointing to the magnetic north and the head will show you the direction.

image

Conclusions

As you can see, working with the compass is very easy, you can easily get the reading of the sensor and change the view, depending on what the user is heading. This is one more tool that you can use to give the user a better experience.

The full source code for the project is in https://github.com/bsonnino/Compass

Some time ago, computer makers introduced new classes of Windows devices: the 2-in-1 and the tablets. These kinds of computers bring a lot of innovation – the 2-in-1 computers can be used as notebooks and tablets, while still maintaining their power: you can have very powerful devices, that can be used at the office and on the road, thus avoiding the need of having a tablet and a notebook.

But this kind of devices have another kind of innovations that are not visible at first sight: sensors. With them, you can have the same experience you have with a smartphone – you can use the accelerator for games or gestures, the GPS for location and routing and many others. This series of posts will show how to use these sensors in UWP, so you can give your user a better experience, so he can use all the resources of his device. And all this with an added bonus, thanks to UWP development – the same project will work both on desktop devices and smartphones.

Working with sensors in UWP

Basically, working with sensors in UWP is pretty much the same:

  • You get an instance of the sensor with the GetDefault method
  • You set its properties
  • You set a handler for the ReadingChanged

That’s all that is needed to work with sensors in UWP. So, let’s go and start with the first sensor: the light sensor.

Working with the light sensor

The light sensor can be used to detect the environment lighting and adjust the screen brightness according to the external light, so the use has the best experience. In this post I will show a simple way to create the effect used in GPS devices: when it’s day, it shows the display with a white background and when it’s night, it shows it with a black background.

To get this effect, the simplest way is to use themes. UWP has three default themes, Dark, Light and High Contrast and you can set them by using the RequestedTheme property of the control (in our case, the main window). So, let’s start.

In Visual Studio create a UWP application and add this XAML to the main page:

[sourcecode language=”xml” padlinenumbers=”true”]

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Text="Day" HorizontalAlignment="Center" x:Name="MainText"
VerticalAlignment="Center" FontSize="48" />
</Grid>
[/sourcecode]

Then, in the MainPage constructor, we will initialize the light sensor and process its readings:

[sourcecode language=”csharp”]
public MainPage()
{
this.InitializeComponent();
var lightSensor = LightSensor.GetDefault();
if (lightSensor == null)
{
MainText.Text = "There is no light sensor in this device";
return;
}
lightSensor.ReportInterval = 15;
lightSensor.ReadingChanged += async (s, e) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
if (e.Reading.IlluminanceInLux < 30)
{

RequestedTheme = ElementTheme.Dark;
MainText.Text = "Night";
}
else
{
RequestedTheme = ElementTheme.Light;
MainText.Text = "Day";
}
});
};
}
[/sourcecode]

We must use the Dispatcher to change the theme and text, because the ReadingChanged can be called in a different thread of the UI thread. When the Illuminance reading is less than 30 Lux, we change to the Dark theme and change the text to Night.

Now, when you run the program in a device that has a light sensor, you will see the default view in daylight like this:

Day

If you cover the light sensor to simulate the lack of light, you will see something like this:

Night

Conclusions

As you can see, it’s very easy to work with sensors. With them, you can give a better experience for your users, so they can enjoy using your apps. And a added benefit is that you can use the same app in a desktop or in a Windows Phone.

The source code for this app is in https://github.com/bsonnino/LightSensor

Nowadays it’s very common to receive JSON data from many sources and to process it in our programs. I have the same problem and, sometimes, I also have to debug the received data to see what’s coming from the server. Many times, the data is minimized and it’s very difficult to analyze what’s coming. On the other side, I have formatted JSON data and want to save space, minimizing it.

You can go to online sites (just do a search for “json formatter” in your preferred search engine) and format the JSON data, to get the formatted output.

image

But, as a developer, I wanted to create a program that does that. So I decided to create a Windows UWP program to process the JSON data.

The first step is to create a UWP program in Visual Studio:

image

In MainPage.xaml, we add the two textboxes, one for the minified JSON and the other for the processed JSON:

[sourcecode language=”xml”]
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="MiniBox" Margin="5" AcceptsReturn="True" TextWrapping="Wrap"/>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<Button Width="85" Height="40" Content="Format &gt;&gt;" Margin="5" />
<Button Width="85" Height="40" Content="&lt;&lt; Minify" Margin="5" />
</StackPanel>
<TextBox x:Name="FormBox" Margin="5" Grid.Column="2" AcceptsReturn="True" TextWrapping="Wrap"/>
</Grid>
[/sourcecode]

To process the JSON data, we use the Newtonsoft Json.NET library (http://www.newtonsoft.com/json). We can add it using NuGet. In the Solution Explorer, right click in References and select “Manage NuGet packages” and add the library Newtonsoft.Json.

Then, in MainPage.xaml, add the handler for the Click handler for the Format button:

[sourcecode language=”xml”]
<Button Width="90" Height="40" Content="Format &gt;&gt;"  Margin="5" Click="FormatJsonClick"/>
[/sourcecode]

Select the Click event handler and press F12 to create the event handler in code and type this code:

[sourcecode language=”csharp”]
private async void FormatJsonClick(object sender, RoutedEventArgs e)
{
try
{
if (!string.IsNullOrWhiteSpace(MiniBox.Text))
{
FormBox.Text = JsonConvert.SerializeObject(
JsonConvert.DeserializeObject(MiniBox.Text), Formatting.Indented);
}
}
catch (JsonReaderException ex)
{
await new MessageDialog($&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;Error parsing JSON: {ex.Message}&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;).ShowAsync();
}
}
[/sourcecode]

We are using two functions of the library to format the data: DeserializeObject, to transform the string into an object and then SerializeObject to transform the object into a string again. This time, we use the Formatting.Indented to format the result and add it to the destination box. To minify the JSON, you must use the same procedure, but use Formatting.None:

[sourcecode language=”csharp”]
private async void MinifyJsonClick(object sender, RoutedEventArgs e)
{
try
{
if (!string.IsNullOrWhiteSpace(FormBox.Text))
{
MiniBox.Text = JsonConvert.SerializeObject(
JsonConvert.DeserializeObject(FormBox.Text), Formatting.None);
}
}
catch (JsonReaderException ex)
{
await new MessageDialog($&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;Error parsing JSON: {ex.Message}&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;).ShowAsync();
}
}
[/sourcecode]

If you run the program and paste some JSON into the first box and click Format, the formatted JSON is shown in the second box.

image

If you want to reverse the process, just click on the Minify button.

Easy, no? Just one line of code and you have a Minifier/Formatter for JSON data.

If you want to take a look at the source code for the project, you can go to https://github.com/bsonnino/ProcessJson