Development
Step 1: Creating a new project
Open Visual Studio IDE to create a new Tizen Wearable Xaml App.
-
Go to File > New > Project to open the New Project window.
-
In the New Project window do the following steps:
a. Select Installed > Visual C# > Tizen 4.0 platform.
b. Select Tizen Wearable Xaml App project type.
c. Specify the project Name (SmartLevel).
d. Set the project Location.
e. Click the OK button to start creating a new project.
-
Project structure should look like below (Solution Explorer window):
Step 2: Adding assets
-
Download and unpack the assets for the application.
The assets pack consists of two folders...
... which contain the following set of images:
-
Background image file (
res/background.png
) -
Level indicator image file (
res/ball.png
) -
Custom application icon - existing file should be replaced (shared/res/SmartLevel.png). Please notice that application icon filename will be different if you choose your own name for the project. In such case, make sure you update icon tag in
tizen-manifest.xml
file.
-
-
Select the unpacked folders, res and shared, and copy them using context menu or press Control + C. Next, make a left mouse click on the project name SmartLevel in Solution Explorer and press Control + V to paste copied folders directly to the SmartLevel project.
-
Confirm following pop-ups to replace the content of the res and shared folders of the project.
Learn more by watching the video
Step 3: Creating the view
-
Go to Solution Explorer window and open the
MainPage.xaml
file. -
Remove the
StackLayout
element, which has been prepared by default, and add an emptyAbsoluteLayout
element.<?xml version="1.0" encoding="utf-8" ?> <c:CirclePage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:c="clr-namespace:Tizen.Wearable.CircularUI.Forms;assembly=Tizen.Wearable.CircularUI.Forms" x:Class="SmartLevel.MainPage"> <c:CirclePage.Content> <AbsoluteLayout> </AbsoluteLayout> </c:CirclePage.Content> </c:CirclePage>
-
Add the content of the page with two image elements positioned in the Absolute Layout:
- Image element for the application background (
background.png
) - Image element for the level ball indication (
ball.png
)
<?xml version="1.0" encoding="utf-8" ?> <c:CirclePage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:c="clr-namespace:Tizen.Wearable.CircularUI.Forms;assembly=Tizen.Wearable.CircularUI.Forms" x:Class="SmartLevel.MainPage"> <c:CirclePage.Content> <AbsoluteLayout> <Image Source="background.png" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5, 0.5, 360, 360" /> <Image Source="ball.png" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5, 0.5, 40, 40" Aspect="AspectFit" x:Name="ball" /> </AbsoluteLayout> </c:CirclePage.Content> </c:CirclePage>
- Image element for the application background (
Notice that we have set name ball for the image which displays level ball indication, which would be used in the code in the next section.
Learn more by watching the video
To build and run this application on the device, follow the steps below:
-
Press Ctrl+Shift+B keys to build the project.
-
Press Ctrl+F5 keys to start installing the application.
Learn more by watching the video
The application should now look like the one below:
Step 4: Reading data from accelerometer sensor
-
Go to Solution Explorer window and open the
MainPage.xaml.cs
file. -
Add two lines of code:
- A
using
statement for theTizen.Sensor
namespace. - A private field, which will store an instance of the
Accelerometer
class.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Xamarin.Forms; using Xamarin.Forms.Xaml; using Tizen.Wearable.CircularUI.Forms; using Tizen.Sensor; namespace SmartLevel { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class MainPage : CirclePage { private Accelerometer _accelerometer; public MainPage() { InitializeComponent(); } } }
- A
-
Add
InitializeAccelerometer()
method, which creates instance ofAccelerometer
class, initializes it and starts reading data from the accelerometer. Use this method in theMainPage
constructor.public partial class MainPage : CirclePage { private Accelerometer _accelerometer; public MainPage() { InitializeComponent(); InitializeAccelerometer(); } private void InitializeAccelerometer() { _accelerometer = new Accelerometer(); _accelerometer.Interval = 20; _accelerometer.DataUpdated += OnAccelerometerDataUpdated; _accelerometer.Start(); } }
-
Add
OnAccelerometerDataUpdated
method. It will handleDataUpdated
event of the accelerometer instance by updating position of the level ball indicator.public partial class MainPage : CirclePage { private Accelerometer _accelerometer; public MainPage() { InitializeComponent(); InitializeAccelerometer(); } private void InitializeAccelerometer() { _accelerometer = new Accelerometer(); _accelerometer.Interval = 20; _accelerometer.DataUpdated += OnAccelerometerDataUpdated; _accelerometer.Start(); } private void OnAccelerometerDataUpdated(object sender, AccelerometerDataUpdatedEventArgs e) { double x = (e.X + 10) / 20; double y = (e.Y + 10) / 20; var position = new Rectangle(x, 1 - y, 40, 40); AbsoluteLayout.SetLayoutBounds(ball, position); } }
Learn more by watching the video
At this point, you have an application which moves level ball indicator every 20 milliseconds. In the next section, you will learn how to easily average the recent accelerometer data to smooth level ball indicator movement.
To build and run this application on the device, follow the steps below:
-
Press Ctrl+Shift+B keys to build the project.
-
Press Ctrl+F5 keys to start installing the application.
Please try to pitch and roll your watch device to see level ball indication moving on the screen.
Step 5: Calculating average position based on latest data
-
Open the
MainPage.xaml.cs
file. Add generic Queue collection called_positions
, which stores tuple - pair of two double values. Those values are the recent positions of the level ball indicator on the watch screen.public partial class MainPage : CirclePage { private Accelerometer _accelerometer; private Queue<(double x, double y)> _positions = new Queue<(double x, double y)>(); public MainPage() { InitializeComponent(); InitializeAccelerometer(); } // (...) }
-
Inside
OnAcceletometerDataUpdated
method add code which:-
Adds (Enqueue) the latest data sample read from the accelerometer.
-
Removes (Dequeue) the oldest data sample, but only if there are more than 25 samples in the queue
_positions
.
private void OnAccelerometerDataUpdated(object sender, AccelerometerDataUpdatedEventArgs e) { double x = (e.X + 10) / 20; double y = (e.Y + 10) / 20; _positions.Enqueue((x, y)); if (_positions.Count > 25) _positions.Dequeue(); var position = new Rectangle(x, 1 - y, 40, 40); AbsoluteLayout.SetLayoutBounds(ball, position); }
-
-
Use
LINQ
methodAverage()
to calculate average value of the position based onx
andy
values stored in the_positions
collection.private void OnAccelerometerDataUpdated(object sender, AccelerometerDataUpdatedEventArgs e) { double x = (e.X + 10) / 20; double y = (e.Y + 10) / 20; _positions.Enqueue((x, y)); if (_positions.Count > 25) _positions.Dequeue(); double xAverage = _positions.Average(item => item.x); double yAverage = _positions.Average(item => item.y); var position = new Rectangle(x, 1 - y, 40, 40); AbsoluteLayout.SetLayoutBounds(ball, position); }
-
Use newly calculated
xAverage
andyAverage
values (instead of the latestx
andy
) to create new position object.private void OnAccelerometerDataUpdated(object sender, AccelerometerDataUpdatedEventArgs e) { double x = (e.X + 10) / 20; double y = (e.Y + 10) / 20; _positions.Enqueue((x, y)); if (_positions.Count > 25) _positions.Dequeue(); double xAverage = _positions.Average(item => item.x); double yAverage = _positions.Average(item => item.y); var position = new Rectangle(xAverage, 1 - yAverage, 40, 40); AbsoluteLayout.SetLayoutBounds(ball, position); }
Learn more by watching the video
At this point, you have an application which displays level ball indicator based on latest 25 data samples read from accelerometer. Notice that the level ball indicator moves slowly and smoothly when the watch is rolled and/or pitched.
To build and run this application on the device, follow the steps below:
-
Press Ctrl+Shift+B keys to build the project.
-
Press Ctrl+F5 keys to start installing the application.
Try to pitch and roll your watch device to see level ball indication moving on the screen. Notice that now the level ball indicator moves are smooth!
You're done!
Congratulations! You have successfully achieved the goal of this Code Lab activity. Now, you can create your own Tizen app for your Galaxy Watch by yourself! But, if you're having trouble, you may check out the link below.