Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #459 from xamarin/feature/issue-348
Browse files Browse the repository at this point in the history
GH-348: Add Barometer Sensor API
  • Loading branch information
mattleibow committed Aug 15, 2018
2 parents 9d81a76 + d39b08c commit fee59d6
Show file tree
Hide file tree
Showing 30 changed files with 1,007 additions and 55 deletions.
84 changes: 84 additions & 0 deletions DeviceTests/DeviceTests.Shared/Barometer_Shared.cs
@@ -0,0 +1,84 @@
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xunit;

namespace DeviceTests
{
public class Barometer_Tests
{
[Fact]
public void IsSupported()
=> Assert.Equal(HardwareSupport.HasBarometer, Barometer.IsSupported);

[Fact]
[Trait(Traits.Hardware.Barometer, Traits.FeatureSupport.Supported)]
public async Task Monitor()
{
// TODO: the test runner app (UI version) should do this, until then...
if (!HardwareSupport.HasBarometer)
return;

var tcs = new TaskCompletionSource<BarometerData>();

Barometer.ReadingChanged += Barometer_ReadingChanged;
void Barometer_ReadingChanged(object sender, BarometerChangedEventArgs e)
{
tcs.TrySetResult(e.Reading);
}
Barometer.Start(SensorSpeed.UI);

var d = await tcs.Task;

Assert.True(d.Pressure >= 0);
Barometer.Stop();
Barometer.ReadingChanged -= Barometer_ReadingChanged;
}

[Fact]
[Trait(Traits.Hardware.Barometer, Traits.FeatureSupport.Supported)]
public async Task IsMonitoring()
{
// TODO: the test runner app (UI version) should do this, until then...
if (!HardwareSupport.HasBarometer)
return;

var tcs = new TaskCompletionSource<BarometerData>();
Barometer.ReadingChanged += Barometer_ReadingChanged;
void Barometer_ReadingChanged(object sender, BarometerChangedEventArgs e)
{
tcs.TrySetResult(e.Reading);
}
Barometer.Start(SensorSpeed.UI);

var d = await tcs.Task;
Assert.True(Barometer.IsMonitoring);

Barometer.Stop();
Barometer.ReadingChanged -= Barometer_ReadingChanged;
}

[Fact]
[Trait(Traits.Hardware.Barometer, Traits.FeatureSupport.Supported)]
public async Task Stop_Monitor()
{
// TODO: the test runner app (UI version) should do this, until then...
if (!HardwareSupport.HasBarometer)
return;

var tcs = new TaskCompletionSource<BarometerData>();
Barometer.ReadingChanged += Barometer_ReadingChanged;
void Barometer_ReadingChanged(object sender, BarometerChangedEventArgs e)
{
tcs.TrySetResult(e.Reading);
}
Barometer.Start(SensorSpeed.UI);

var d = await tcs.Task;

Barometer.Stop();
Barometer.ReadingChanged -= Barometer_ReadingChanged;

Assert.False(Barometer.IsMonitoring);
}
}
}
11 changes: 11 additions & 0 deletions DeviceTests/DeviceTests.Shared/HardwareSupport.cs
Expand Up @@ -74,5 +74,16 @@ static class HardwareSupport
// TODO: most UWP devices don't have a camera lamp (mobile devices do, we we don't care about those)
false;
#endif

public static bool HasBarometer =>
#if __ANDROID__
true;
#elif __IOS__
// iphone 6 and never have a barometer. looking in how to test this.
Xamarin.Essentials.DeviceInfo.DeviceType == Xamarin.Essentials.DeviceType.Physical;
#elif WINDOWS_UWP
// TODO: most UWP devices don't have a barometer (mobile devices do, we we don't care about those)
false;
#endif
}
}
1 change: 1 addition & 0 deletions DeviceTests/DeviceTests.Shared/Traits.cs
Expand Up @@ -14,6 +14,7 @@ static class Traits
internal static class Hardware
{
public const string Accelerometer = "HardwareAccelerometer";
public const string Barometer = "HardwareBarometer";
public const string Compass = "HardwareCompass";
public const string Gyroscope = "HardwareGyroscope";
public const string Magnetometer = "HardwareMagnetometer";
Expand Down
25 changes: 24 additions & 1 deletion Samples/Samples/View/AllSensorsPage.xaml
Expand Up @@ -141,7 +141,7 @@
<Button Grid.Row="5" Grid.Column="1" Text="Stop" Command="{Binding StopCommand}"
IsEnabled="{Binding IsActive}" />
</Grid>

<Label Text="Orientation Sensor" FontAttributes="Bold" Margin="0,6,0,0" />
<Grid x:Name="GridOrientation">
<Grid.BindingContext>
Expand Down Expand Up @@ -176,6 +176,29 @@
<Button Grid.Row="5" Grid.Column="1" Text="Stop" Command="{Binding StopCommand}"
IsEnabled="{Binding IsActive}" />
</Grid>
<Label Text="Monitor barometer for changes." FontAttributes="Bold" Margin="12" />
<Grid x:Name="GridBarometer">
<Grid.BindingContext>
<viewmodels:BarometerViewModel />
</Grid.BindingContext>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Label Grid.Row="0" Grid.ColumnSpan="2"
Text="{Binding BaromterValue, StringFormat='Barometer pressure (hPA): {0:N}'}" />

<Button Grid.Row="1" Grid.Column="0" Text="Start" Command="{Binding StartBarometerComand}"
IsEnabled="{Binding BarometerIsActive, Converter={StaticResource NegativeConverter}}" />

<Button Grid.Row="1" Grid.Column="1" Text="Stop" Command="{Binding StopBarometerCommand}"
IsEnabled="{Binding BarometerIsActive}" />
</Grid>
</StackLayout>
</ScrollView>
</StackLayout>
Expand Down
3 changes: 2 additions & 1 deletion Samples/Samples/View/AllSensorsPage.xaml.cs
Expand Up @@ -20,6 +20,7 @@ protected override void OnAppearing()
SetupBinding(GridGyro.BindingContext);
SetupBinding(GridMagnetometer.BindingContext);
SetupBinding(GridOrientation.BindingContext);
SetupBinding(GridBarometer.BindingContext);
}

protected override void OnDisappearing()
Expand All @@ -29,7 +30,7 @@ protected override void OnDisappearing()
TearDownBinding(GridGyro.BindingContext);
TearDownBinding(GridMagnetometer.BindingContext);
TearDownBinding(GridOrientation.BindingContext);

TearDownBinding(GridBarometer.BindingContext);
base.OnDisappearing();
}
}
Expand Down
48 changes: 48 additions & 0 deletions Samples/Samples/View/BarometerPage.xaml
@@ -0,0 +1,48 @@
<views:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Samples.View"
xmlns:viewmodels="clr-namespace:Samples.ViewModel"
x:Class="Samples.View.BarometerPage"
Title="Barometer">
<views:BasePage.BindingContext>
<viewmodels:BarometerViewModel />
</views:BasePage.BindingContext>

<StackLayout>
<Label Text="Monitor barometer for changes." FontAttributes="Bold" Margin="12" />

<ScrollView>
<Grid Padding="12,0,12,12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Label Grid.Row="0" Grid.ColumnSpan="2"
Text="{Binding Pressure, StringFormat='Barometer pressure (hPA): {0:N}'}" />

<Label Grid.Row="1" Grid.ColumnSpan="2" Text="Speed:" />

<Picker Grid.Row="2" Grid.ColumnSpan="2" HorizontalOptions="FillAndExpand"
ItemsSource="{Binding Speeds}"
SelectedIndex="{Binding Speed, Mode=TwoWay}"
IsEnabled="{Binding IsActive, Converter={StaticResource NegativeConverter}}"
Margin="0,0,0,10"/>


<Button Grid.Row="3" Grid.Column="0" Text="Start" Command="{Binding StartCommand}"
IsEnabled="{Binding IsActive, Converter={StaticResource NegativeConverter}}" />

<Button Grid.Row="3" Grid.Column="1" Text="Stop" Command="{Binding StopCommand}"
IsEnabled="{Binding IsActive}" />
</Grid>
</ScrollView>
</StackLayout>

</views:BasePage>
13 changes: 13 additions & 0 deletions Samples/Samples/View/BarometerPage.xaml.cs
@@ -0,0 +1,13 @@
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Samples.View
{
public partial class BarometerPage : BasePage
{
public BarometerPage()
{
InitializeComponent();
}
}
}
91 changes: 91 additions & 0 deletions Samples/Samples/ViewModel/BarometerViewModel.cs
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Samples.ViewModel
{
public class BarometerViewModel : BaseViewModel
{
bool isActive;
double pressure;
int speed = 2;

public BarometerViewModel()
{
StartCommand = new Command(OnStartBarometer);
StopCommand = new Command(OnStop);
}

public ICommand StartCommand { get; }

public ICommand StopCommand { get; }

public bool IsActive
{
get => isActive;
set => SetProperty(ref isActive, value);
}

public double Pressure
{
get => pressure;
set => SetProperty(ref pressure, value);
}

public List<string> Speeds { get; } =
new List<string>
{
"Fastest",
"Game",
"Normal",
"User Interface"
};

public int Speed
{
get => speed;
set => SetProperty(ref speed, value);
}

public override void OnAppearing()
{
Barometer.ReadingChanged += OnBarometerReadingChanged;
base.OnAppearing();
}

public override void OnDisappearing()
{
OnStop();
Barometer.ReadingChanged -= OnBarometerReadingChanged;

base.OnDisappearing();
}

async void OnStartBarometer()
{
try
{
Barometer.Start((SensorSpeed)Speed);
IsActive = true;
}
catch (Exception ex)
{
await DisplayAlertAsync($"Unable to start barometer: {ex.Message}");
}
}

void OnBarometerReadingChanged(object sender, BarometerChangedEventArgs e)
{
Pressure = e.Reading.Pressure;
}

void OnStop()
{
IsActive = false;
Barometer.Stop();
Barometer.ReadingChanged -= OnBarometerReadingChanged;
}
}
}
5 changes: 2 additions & 3 deletions Samples/Samples/ViewModel/CompassViewModel.cs
Expand Up @@ -102,9 +102,8 @@ async void OnStartCompass1()
if (Compass.IsMonitoring)
OnStopCompass2();

Compass.ReadingChanged += OnCompass1ReadingChanged;

Compass.Start((SensorSpeed)Speed1);
Compass.ReadingChanged += OnCompass1ReadingChanged;
Compass1IsActive = true;
}
catch (Exception ex)
Expand Down Expand Up @@ -141,8 +140,8 @@ async void OnStartCompass2()
if (Compass.IsMonitoring)
OnStopCompass1();

Compass.ReadingChanged += OnCompass2ReadingChanged;
Compass.Start((SensorSpeed)Speed2);
Compass.ReadingChanged += OnCompass2ReadingChanged;
Compass2IsActive = true;
}
catch (Exception ex)
Expand Down
10 changes: 8 additions & 2 deletions Samples/Samples/ViewModel/HomeViewModel.cs
Expand Up @@ -28,14 +28,20 @@ public HomeViewModel()
"📏",
"All Sensors",
typeof(AllSensorsPage),
"Have a look at the accelerometer, compass, gyroscope, magnetometer, and orientation sensors.",
new[] { "accelerometer", "compass", "gyroscope", "magnetometer", "orientation", "sensors", "hardware", "device" }),
"Have a look at the accelerometer, barometer, compass, gyroscope, magnetometer, and orientation sensors.",
new[] { "accelerometer", "barometer", "compass", "gyroscope", "magnetometer", "orientation", "sensors", "hardware", "device" }),
new SampleItem(
"📦",
"App Info",
typeof(AppInfoPage),
"Find out about the app with ease.",
new[] { "app", "info" }),
new SampleItem(
"📏",
"Barometer",
typeof(BarometerPage),
"Easily detect pressure level, via the device barometer.",
new[] { "barometer", "hardware", "device", "sensor" }),
new SampleItem(
"🔋",
"Battery",
Expand Down

0 comments on commit fee59d6

Please sign in to comment.