| File: Battery\Battery.shared.cs | Web Access |
| Project: src\src\Essentials\src\Essentials.csproj (Microsoft.Maui.Essentials) |
#nullable enable using System; namespace Microsoft.Maui.Devices { /// <summary> /// Methods and properties for battery and charging information of the device. /// </summary> /// <remarks> /// <para>Platform specific remarks:</para> /// <para>- Android: <c>Battery_Stats</c> permission must be set in manifest.</para> /// <para>- iOS: Simulator will not return battery information, must be run on device.</para> /// <para>- Windows: None.</para> /// </remarks> public interface IBattery { /// <summary> /// Gets the current charge level of the device from 0.0 to 1.0. /// </summary> /// <remarks>Returns -1 if no battery exists.</remarks> double ChargeLevel { get; } /// <summary> /// Gets the charging state of the device. /// </summary> BatteryState State { get; } /// <summary> /// Gets the current power source for the device. /// </summary> BatteryPowerSource PowerSource { get; } /// <summary> /// Gets the current energy saver status of the device. /// </summary> EnergySaverStatus EnergySaverStatus { get; } /// <summary> /// Occurs when battery properties change. /// </summary> event EventHandler<BatteryInfoChangedEventArgs> BatteryInfoChanged; /// <summary> /// Occurs when the energy saver status changes. /// </summary> event EventHandler<EnergySaverStatusChangedEventArgs> EnergySaverStatusChanged; } /// <summary> /// Methods and properties for battery and charging information of the device. /// </summary> public static class Battery { /// <summary> /// Gets the current charge level of the device from 0.0 to 1.0. /// </summary> /// <remarks>Returns -1 if no battery exists.</remarks> public static double ChargeLevel => Default.ChargeLevel; /// <summary> /// Gets the charging state of the device. /// </summary> public static BatteryState State => Default.State; /// <summary> /// Gets the current power source for the device. /// </summary> public static BatteryPowerSource PowerSource => Default.PowerSource; /// <summary> /// Gets the current energy saver status of the device. /// </summary> public static EnergySaverStatus EnergySaverStatus => Default.EnergySaverStatus; /// <summary> /// Event trigger when battery properties have changed. /// </summary> public static event EventHandler<BatteryInfoChangedEventArgs> BatteryInfoChanged { add => Default.BatteryInfoChanged += value; remove => Default.BatteryInfoChanged -= value; } /// <summary> /// Occurs when the energy saver status changes. /// </summary> public static event EventHandler<EnergySaverStatusChangedEventArgs> EnergySaverStatusChanged { add => Default.EnergySaverStatusChanged += value; remove => Default.EnergySaverStatusChanged -= value; } static IBattery? defaultImplementation; /// <summary> /// Provides the default implementation for static usage of this API. /// </summary>s public static IBattery Default => defaultImplementation ??= new BatteryImplementation(); internal static void SetDefault(IBattery? implementation) => defaultImplementation = implementation; } partial class BatteryImplementation : IBattery { event EventHandler<BatteryInfoChangedEventArgs>? BatteryInfoChangedInternal; event EventHandler<EnergySaverStatusChangedEventArgs>? EnergySaverStatusChangedInternal; public event EventHandler<BatteryInfoChangedEventArgs> BatteryInfoChanged { add { if (BatteryInfoChangedInternal == null) StartBatteryListeners(); BatteryInfoChangedInternal += value; } remove { BatteryInfoChangedInternal -= value; if (BatteryInfoChangedInternal == null) StopBatteryListeners(); } } public event EventHandler<EnergySaverStatusChangedEventArgs> EnergySaverStatusChanged { add { if (EnergySaverStatusChangedInternal == null) StartEnergySaverListeners(); EnergySaverStatusChangedInternal += value; } remove { EnergySaverStatusChangedInternal -= value; if (EnergySaverStatusChangedInternal == null) StopEnergySaverListeners(); } } // a cache so that events aren't fired unnecessarily // this is mainly an issue on Android, but we can stiil do this everywhere static double currentLevel; static BatteryPowerSource currentSource; static BatteryState currentState; void SetCurrent() { currentLevel = ChargeLevel; currentSource = PowerSource; currentState = State; } void OnBatteryInfoChanged(double level, BatteryState state, BatteryPowerSource source) => OnBatteryInfoChanged(new BatteryInfoChangedEventArgs(level, state, source)); void OnBatteryInfoChanged() => OnBatteryInfoChanged(ChargeLevel, State, PowerSource); void OnBatteryInfoChanged(BatteryInfoChangedEventArgs e) { if (currentLevel != e.ChargeLevel || currentSource != e.PowerSource || currentState != e.State) { SetCurrent(); BatteryInfoChangedInternal?.Invoke(null, e); } } void OnEnergySaverChanged() => OnEnergySaverChanged(EnergySaverStatus); void OnEnergySaverChanged(EnergySaverStatus saverStatus) => OnEnergySaverChanged(new EnergySaverStatusChangedEventArgs(saverStatus)); void OnEnergySaverChanged(EnergySaverStatusChangedEventArgs e) => EnergySaverStatusChangedInternal?.Invoke(null, e); } /// <summary> /// Describes possible states of the battery. /// </summary> public enum BatteryState { /// <summary>Battery state could not be determined.</summary> Unknown = 0, /// <summary>Battery is actively being charged by a power source.</summary> Charging = 1, /// <summary>Battery is not plugged in and discharging.</summary> Discharging = 2, /// <summary>Battery is full.</summary> Full = 3, /// <summary>Battery is not charging or discharging, but in an inbetween state.</summary> NotCharging = 4, /// <summary>Battery does not exist on the device.</summary> NotPresent = 5 } /// <summary> /// Enumerates power sources with which the device and battery can be powered or charged. /// </summary> public enum BatteryPowerSource { /// <summary>Power source cannot be determined.</summary> Unknown = 0, /// <summary>Power source is the battery and is currently not being charged.</summary> Battery = 1, /// <summary>Power source is an AC Charger.</summary> AC = 2, /// <summary>Power source is a USB port.</summary> Usb = 3, /// <summary>Power source is wireless.</summary> Wireless = 4 } /// <summary> /// Enumerates states that the energy saver van have on the device. /// </summary> public enum EnergySaverStatus { /// <summary>Status of energy saving is unknown.</summary> Unknown = 0, /// <summary>Energy saving is on.</summary> On = 1, /// <summary>Energy saving is off.</summary> Off = 2 } /// <summary> /// Event arguments containing the current reading of <see cref="IBattery"/>. /// </summary> public class BatteryInfoChangedEventArgs : EventArgs { /// <summary> /// Initializes a new instance of the <see cref="BatteryInfoChangedEventArgs"/> class. /// </summary> /// <param name="level">The current level of the battery.</param> /// <param name="state">The state of the battery.</param> /// <param name="source">The source of the battery.</param> public BatteryInfoChangedEventArgs(double level, BatteryState state, BatteryPowerSource source) { ChargeLevel = level; State = state; PowerSource = source; } /// <summary> /// Gets the current charge level of the device from 0.0 to 1.0. /// </summary> public double ChargeLevel { get; } /// <summary> /// Gets the charging state of the device. /// </summary> public BatteryState State { get; } /// <summary> /// Gets the current power source for the device. /// </summary> public BatteryPowerSource PowerSource { get; } /// <summary> /// Returns a string representation of this instance of <see cref="BatteryInfoChangedEventArgs"/>. /// </summary> /// <returns>A string representation of this instance in the format of <c>ChargeLevel: {value}, State: {value}, PowerSource: {value}</c>.</returns> public override string ToString() => $"{nameof(ChargeLevel)}: {ChargeLevel.ToString()}, " + $"{nameof(State)}: {State}, " + $"{nameof(PowerSource)}: {PowerSource}"; } /// <summary> /// Event arguments when the energy saver status changes. /// </summary> public class EnergySaverStatusChangedEventArgs : EventArgs { /// <summary> /// Initializes a new instance of the <see cref="EnergySaverStatusChangedEventArgs"/> class. /// </summary> /// <param name="saverStatus">The current status of the event.</param> public EnergySaverStatusChangedEventArgs(EnergySaverStatus saverStatus) { EnergySaverStatus = saverStatus; } /// <summary> /// Gets the current status of energy saver mode. /// </summary> public EnergySaverStatus EnergySaverStatus { get; } /// <summary> /// Returns a string representation of this instance of <see cref="EnergySaverStatusChangedEventArgs"/>. /// </summary> /// <returns>A string representation of this instance in the format of <c>EnergySaverStatus: {value}</c>.</returns> public override string ToString() => $"{nameof(EnergySaverStatus)}: {EnergySaverStatus}"; } }