diff --git a/src/Essentials/src/Battery/Battery.android.cs b/src/Essentials/src/Battery/Battery.android.cs index c242246f10f8..093fa133ad45 100755 --- a/src/Essentials/src/Battery/Battery.android.cs +++ b/src/Essentials/src/Battery/Battery.android.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using Android.App; using Android.Content; @@ -8,13 +10,13 @@ namespace Microsoft.Maui.Devices { partial class BatteryImplementation : IBattery { - static PowerManager powerManager; + static PowerManager? powerManager; - static PowerManager PowerManager => + static PowerManager? PowerManager => powerManager ??= Application.Context.GetSystemService(Context.PowerService) as PowerManager; - BatteryBroadcastReceiver batteryReceiver; - EnergySaverBroadcastReceiver powerReceiver; + BatteryBroadcastReceiver? batteryReceiver; + EnergySaverBroadcastReceiver? powerReceiver; void StartEnergySaverListeners() { @@ -32,7 +34,7 @@ void StopEnergySaverListeners() { System.Diagnostics.Debug.WriteLine("Energy saver receiver already unregistered. Disposing of it."); } - powerReceiver.Dispose(); + powerReceiver?.Dispose(); powerReceiver = null; } @@ -63,7 +65,7 @@ void StopBatteryListeners() { System.Diagnostics.Debug.WriteLine("Battery receiver already unregistered. Disposing of it."); } - batteryReceiver.Dispose(); + batteryReceiver?.Dispose(); batteryReceiver = null; } @@ -76,6 +78,9 @@ public double ChargeLevel using (var filter = new IntentFilter(Intent.ActionBatteryChanged)) using (var battery = PlatformUtils.RegisterBroadcastReceiver(null, filter, false)) { + if(battery is null) + return -1; // Unknown + var level = battery.GetIntExtra(BatteryManager.ExtraLevel, -1); var scale = battery.GetIntExtra(BatteryManager.ExtraScale, -1); @@ -96,6 +101,9 @@ public BatteryState State using (var filter = new IntentFilter(Intent.ActionBatteryChanged)) using (var battery = PlatformUtils.RegisterBroadcastReceiver(null, filter, false)) { + if (battery is null) + return BatteryState.Unknown; + var status = battery.GetIntExtra(BatteryManager.ExtraStatus, -1); switch (status) { @@ -123,6 +131,9 @@ public BatteryPowerSource PowerSource using (var filter = new IntentFilter(Intent.ActionBatteryChanged)) using (var battery = PlatformUtils.RegisterBroadcastReceiver(null, filter, false)) { + if (battery is null) + return BatteryPowerSource.Unknown; + var chargePlug = battery.GetIntExtra(BatteryManager.ExtraPlugged, -1); if (chargePlug == (int)BatteryPlugged.Usb) @@ -143,7 +154,7 @@ public BatteryPowerSource PowerSource [BroadcastReceiver(Enabled = true, Exported = false, Label = "Essentials Battery Broadcast Receiver")] class BatteryBroadcastReceiver : BroadcastReceiver { - Action onChanged; + readonly Action? onChanged; public BatteryBroadcastReceiver() { @@ -152,14 +163,14 @@ public BatteryBroadcastReceiver() public BatteryBroadcastReceiver(Action onChanged) => this.onChanged = onChanged; - public override void OnReceive(Context context, Intent intent) => + public override void OnReceive(Context? context, Intent? intent) => onChanged?.Invoke(); } [BroadcastReceiver(Enabled = true, Exported = false, Label = "Essentials Energy Saver Broadcast Receiver")] class EnergySaverBroadcastReceiver : BroadcastReceiver { - Action onChanged; + readonly Action? onChanged; public EnergySaverBroadcastReceiver() { @@ -168,7 +179,7 @@ public EnergySaverBroadcastReceiver() public EnergySaverBroadcastReceiver(Action onChanged) => this.onChanged = onChanged; - public override void OnReceive(Context context, Intent intent) => + public override void OnReceive(Context? context, Intent? intent) => onChanged?.Invoke(); } } diff --git a/src/Essentials/test/DeviceTests/Tests/Battery_Tests.cs b/src/Essentials/test/DeviceTests/Tests/Battery_Tests.cs index af423bca2699..0947a01276c1 100644 --- a/src/Essentials/test/DeviceTests/Tests/Battery_Tests.cs +++ b/src/Essentials/test/DeviceTests/Tests/Battery_Tests.cs @@ -55,6 +55,16 @@ public void App_Is_Not_Lower_Power_mode() Assert.Equal(EnergySaverStatus.Off, Battery.EnergySaverStatus); } + [Fact] + public void Unsubscribe_BatteryInfoChanged_Does_Not_Crash() + { + // TODO: the test runner app (UI version) should do this, until then... + if (!HardwareSupport.HasBattery) + return; + + Battery.BatteryInfoChanged -= (sender, args) => { }; + } + [Fact] public async Task EnergySaverStatusChanged_Does_Not_Crash() {