| File: Barometer\Barometer.shared.cs | Web Access |
| Project: src\src\Essentials\src\Essentials.csproj (Microsoft.Maui.Essentials) |
#nullable enable using System; using Microsoft.Maui.ApplicationModel; namespace Microsoft.Maui.Devices.Sensors { /// <summary> /// Monitor changes to the atmospheric pressure. /// </summary> public interface IBarometer { /// <summary> /// Gets a value indicating whether reading the barometer is supported on this device. /// </summary> bool IsSupported { get; } /// <summary> /// Gets a value indicating whether the barometer is actively being monitored. /// </summary> bool IsMonitoring { get; } /// <summary> /// Start monitoring for changes to the barometer. /// </summary> /// <param name="sensorSpeed">The speed to listen for changes.</param> void Start(SensorSpeed sensorSpeed); /// <summary> /// Occurs when the barometer reading changes. /// </summary> event EventHandler<BarometerChangedEventArgs>? ReadingChanged; /// <summary> /// Stop monitoring for changes to the barometer. /// </summary> void Stop(); } /// <summary> /// Monitor changes to the atmospheric pressure. /// </summary> public static class Barometer { /// <summary> /// Occurs when barometer reading changes. /// </summary> public static event EventHandler<BarometerChangedEventArgs> ReadingChanged { add => Default.ReadingChanged += value; remove => Default.ReadingChanged -= value; } /// <summary> /// Gets a value indicating whether reading the barometer is supported on this device. /// </summary> public static bool IsSupported => Default.IsSupported; /// <summary> /// Gets a value indicating whether the barometer is actively being monitored. /// </summary> public static bool IsMonitoring => Default.IsMonitoring; /// <summary> /// Start monitoring for changes to the barometer. /// </summary> /// <remarks> /// Will throw <see cref="FeatureNotSupportedException"/> if not supported on device. /// Will throw <see cref="InvalidOperationException"/> if <see cref="IsMonitoring"/> is <see langword="true"/>. /// </remarks> /// <param name="sensorSpeed">The speed to listen for changes.</param> public static void Start(SensorSpeed sensorSpeed) => Default.Start(sensorSpeed); /// <summary> /// Stop monitoring for changes to the barometer. /// </summary> public static void Stop() => Default.Stop(); static IBarometer? defaultImplementation; /// <summary> /// Provides the default implementation for static usage of this API. /// </summary> public static IBarometer Default => defaultImplementation ??= new BarometerImplementation(); internal static void SetDefault(IBarometer? implementation) => defaultImplementation = implementation; } /// <summary> /// Contains the current pressure information from the <see cref="IBarometer.ReadingChanged"/> event. /// </summary> public class BarometerChangedEventArgs : EventArgs { /// <summary> /// Initializes a new instance of the <see cref="BarometerChangedEventArgs"/> class. /// </summary> /// <param name="reading">The barometer data reading.</param> public BarometerChangedEventArgs(BarometerData reading) => Reading = reading; /// <summary> /// The current values of the barometer. /// </summary> public BarometerData Reading { get; } } /// <summary> /// Contains the pressure measured by the user's device barometer. /// </summary> public readonly struct BarometerData : IEquatable<BarometerData> { /// <summary> /// Initializes a new instance of the <see cref="BarometerData"/> class. /// </summary> /// <param name="pressure">The current pressure reading.</param> public BarometerData(double pressure) => PressureInHectopascals = pressure; /// <summary> /// Gets the current pressure in hectopascals. /// </summary> public double PressureInHectopascals { get; } /// <summary> /// Equality operator for equals. /// </summary> /// <param name="left">Left to compare.</param> /// <param name="right">Right to compare.</param> /// <returns><see langword="true"/> if objects are equal, otherwise <see langword="false"/>.</returns> public static bool operator ==(BarometerData left, BarometerData right) => left.Equals(right); /// <summary> /// Inequality operator. /// </summary> /// <param name="left">Left to compare.</param> /// <param name="right">Right to compare.</param> /// <returns><see langword="true"/> if objects are not equal, otherwise <see langword="false"/>.</returns> public static bool operator !=(BarometerData left, BarometerData right) => !left.Equals(right); /// <summary> /// Compares the underlying <see cref="BarometerData"/> instances. /// </summary> /// <param name="obj">Object to compare with.</param> /// <returns><see langword="true"/> if they are equal, otherwise <see langword="false"/>.</returns> public override bool Equals(object? obj) => (obj is BarometerData data) && Equals(data); /// <summary> /// Compares the underlying <see cref="BarometerData.PressureInHectopascals"/> instances. /// </summary> /// <param name="other"><see cref="BarometerData"/> object to compare with.</param> /// <returns><see langword="true"/> if they are equal, otherwise <see langword="false"/>.</returns> public bool Equals(BarometerData other) => PressureInHectopascals.Equals(other.PressureInHectopascals); /// <inheritdoc cref="object.GetHashCode"/> public override int GetHashCode() => PressureInHectopascals.GetHashCode(); /// <summary> /// Returns a string representation of the current values of <see cref="PressureInHectopascals"/>. /// </summary> /// <returns>A string representation of this instance in the format of <c>PressureInHectopascals: {value}</c>.</returns> public override string ToString() => $"{nameof(PressureInHectopascals)}: {PressureInHectopascals}"; } partial class BarometerImplementation : IBarometer { bool UseSyncContext => SensorSpeed == SensorSpeed.Default || SensorSpeed == SensorSpeed.UI; #pragma warning disable CS0067 public event EventHandler<BarometerChangedEventArgs>? ReadingChanged; #pragma warning restore CS0067 public bool IsMonitoring { get; private set; } SensorSpeed SensorSpeed { get; set; } = SensorSpeed.Default; void RaiseReadingChanged(BarometerData reading) { var args = new BarometerChangedEventArgs(reading); if (UseSyncContext) MainThread.BeginInvokeOnMainThread(() => ReadingChanged?.Invoke(this, args)); else ReadingChanged?.Invoke(this, args); } /// <inheritdoc/> /// <exception cref="FeatureNotSupportedException">Thrown if <see cref="IsSupported"/> returns <see langword="false"/>.</exception> /// <exception cref="InvalidOperationException">Thrown if <see cref="IsMonitoring"/> returns <see langword="true"/>.</exception> public void Start(SensorSpeed sensorSpeed) { if (!IsSupported) throw new FeatureNotSupportedException(); if (IsMonitoring) throw new InvalidOperationException("Barometer has already been started."); IsMonitoring = true; SensorSpeed = sensorSpeed; try { PlatformStart(sensorSpeed); } catch { IsMonitoring = false; throw; } } /// <inheritdoc/> /// <exception cref="FeatureNotSupportedException">Thrown if <see cref="IsSupported"/> returns <see langword="false"/>.</exception> public void Stop() { if (!IsSupported) throw new FeatureNotSupportedException(); if (!IsMonitoring) return; IsMonitoring = false; try { PlatformStop(); } catch { IsMonitoring = true; throw; } } } }