diff --git a/src/Essentials/src/Battery/Battery.android.cs b/src/Essentials/src/Battery/Battery.android.cs index 53b781210088..c242246f10f8 100755 --- a/src/Essentials/src/Battery/Battery.android.cs +++ b/src/Essentials/src/Battery/Battery.android.cs @@ -19,7 +19,7 @@ partial class BatteryImplementation : IBattery void StartEnergySaverListeners() { powerReceiver = new EnergySaverBroadcastReceiver(OnEnergySaverChanged); - Application.Context.RegisterReceiver(powerReceiver, new IntentFilter(PowerManager.ActionPowerSaveModeChanged)); + PlatformUtils.RegisterBroadcastReceiver(powerReceiver, new IntentFilter(PowerManager.ActionPowerSaveModeChanged), false); } void StopEnergySaverListeners() @@ -50,7 +50,7 @@ void StartBatteryListeners() Permissions.EnsureDeclared(); batteryReceiver = new BatteryBroadcastReceiver(OnBatteryInfoChanged); - Application.Context.RegisterReceiver(batteryReceiver, new IntentFilter(Intent.ActionBatteryChanged)); + PlatformUtils.RegisterBroadcastReceiver(batteryReceiver, new IntentFilter(Intent.ActionBatteryChanged), false); } void StopBatteryListeners() @@ -74,7 +74,7 @@ public double ChargeLevel Permissions.EnsureDeclared(); using (var filter = new IntentFilter(Intent.ActionBatteryChanged)) - using (var battery = Application.Context.RegisterReceiver(null, filter)) + using (var battery = PlatformUtils.RegisterBroadcastReceiver(null, filter, false)) { var level = battery.GetIntExtra(BatteryManager.ExtraLevel, -1); var scale = battery.GetIntExtra(BatteryManager.ExtraScale, -1); @@ -94,7 +94,7 @@ public BatteryState State Permissions.EnsureDeclared(); using (var filter = new IntentFilter(Intent.ActionBatteryChanged)) - using (var battery = Application.Context.RegisterReceiver(null, filter)) + using (var battery = PlatformUtils.RegisterBroadcastReceiver(null, filter, false)) { var status = battery.GetIntExtra(BatteryManager.ExtraStatus, -1); switch (status) @@ -121,7 +121,7 @@ public BatteryPowerSource PowerSource Permissions.EnsureDeclared(); using (var filter = new IntentFilter(Intent.ActionBatteryChanged)) - using (var battery = Application.Context.RegisterReceiver(null, filter)) + using (var battery = PlatformUtils.RegisterBroadcastReceiver(null, filter, false)) { var chargePlug = battery.GetIntExtra(BatteryManager.ExtraPlugged, -1); diff --git a/src/Essentials/src/Connectivity/Connectivity.android.cs b/src/Essentials/src/Connectivity/Connectivity.android.cs index 76c529845df7..1f463b7b3a96 100644 --- a/src/Essentials/src/Connectivity/Connectivity.android.cs +++ b/src/Essentials/src/Connectivity/Connectivity.android.cs @@ -45,7 +45,7 @@ void StartListeners() conectivityReceiver = new ConnectivityBroadcastReceiver(OnConnectivityChanged); - Application.Context.RegisterReceiver(conectivityReceiver, filter); + PlatformUtils.RegisterBroadcastReceiver(conectivityReceiver, filter, false); } void StopListeners() diff --git a/src/Essentials/src/Platform/PlatformUtils.android.cs b/src/Essentials/src/Platform/PlatformUtils.android.cs index aabcc96addfe..3afe2b78e4c8 100644 --- a/src/Essentials/src/Platform/PlatformUtils.android.cs +++ b/src/Essentials/src/Platform/PlatformUtils.android.cs @@ -1,3 +1,4 @@ +#nullable enable using System; using Android.App; using Android.Content; @@ -25,13 +26,28 @@ internal static int NextRequestCode() return requestCode; } + internal static Intent? RegisterBroadcastReceiver(BroadcastReceiver? receiver, IntentFilter filter, bool exported) + { +#if ANDROID34_0_OR_GREATER + if (OperatingSystem.IsAndroidVersionAtLeast(34)) + { + var flags = exported ? ReceiverFlags.Exported : ReceiverFlags.NotExported; + return Application.Context.RegisterReceiver(receiver, filter, flags); + } +#endif + return Application.Context.RegisterReceiver(receiver, filter); + } + internal static bool HasSystemFeature(string systemFeature) { var packageManager = Application.Context.PackageManager; - foreach (var feature in packageManager.GetSystemAvailableFeatures()) + if (packageManager is not null) { - if (feature?.Name?.Equals(systemFeature, StringComparison.OrdinalIgnoreCase) ?? false) - return true; + foreach (var feature in packageManager.GetSystemAvailableFeatures()) + { + if (feature?.Name?.Equals(systemFeature, StringComparison.OrdinalIgnoreCase) ?? false) + return true; + } } return false; } @@ -51,38 +67,5 @@ internal static bool IsIntentSupported(Intent intent, string expectedPackageName return intent.ResolveActivity(pm) is ComponentName c && c.PackageName == expectedPackageName; } - - internal static Java.Util.Locale GetLocale() - { - var resources = Application.Context.Resources; - var config = resources.Configuration; - -#if __ANDROID_24__ - if (OperatingSystem.IsAndroidVersionAtLeast(24)) - return config.Locales.Get(0); -#endif - -#pragma warning disable CS0618 // Type or member is obsolete - return config.Locale; -#pragma warning restore CS0618 // Type or member is obsolete - } - - internal static void SetLocale(Java.Util.Locale locale) - { - Java.Util.Locale.Default = locale; - var resources = Application.Context.Resources; - var config = resources.Configuration; -#pragma warning disable CS0618 // Type or member is obsolete -#pragma warning disable CA1422 // Validate platform compatibility -#pragma warning disable CA1416 // Validate platform compatibility - if (OperatingSystem.IsAndroidVersionAtLeast(24)) - config.SetLocale(locale); - else - config.Locale = locale; - resources.UpdateConfiguration(config, resources.DisplayMetrics); -#pragma warning restore CA1422 // Validate platform compatibility -#pragma warning restore CA1416 // Validate platform compatibility -#pragma warning restore CS0618 // Type or member is obsolete - } } } diff --git a/src/Essentials/test/DeviceTests/Tests/Battery_Tests.cs b/src/Essentials/test/DeviceTests/Tests/Battery_Tests.cs index d343cdd2502a..fde8d7b8af1c 100644 --- a/src/Essentials/test/DeviceTests/Tests/Battery_Tests.cs +++ b/src/Essentials/test/DeviceTests/Tests/Battery_Tests.cs @@ -1,4 +1,5 @@ using Microsoft.Maui.Devices; +using System.Threading.Tasks; using Xunit; namespace Microsoft.Maui.Essentials.DeviceTests @@ -53,5 +54,37 @@ public void App_Is_Not_Lower_Power_mode() { Assert.Equal(EnergySaverStatus.Off, Battery.EnergySaverStatus); } + + [Fact] + public async Task EnergySaverStatusChanged_Does_Not_Crash() + { + Battery.EnergySaverStatusChanged += Battery_EnergySaverStatusChanged; + + // just ensure there is no need for the OS to "respond" to a new subscription + await Task.Delay(1000); + + Battery.EnergySaverStatusChanged -= Battery_EnergySaverStatusChanged; + + static void Battery_EnergySaverStatusChanged(object sender, EnergySaverStatusChangedEventArgs e) + { + // do nothing + } + } + + [Fact] + public async Task BatteryInfoChanged_Does_Not_Crash() + { + Battery.BatteryInfoChanged += Battery_BatteryInfoChanged; + + // just ensure there is no need for the OS to "respond" to a new subscription + await Task.Delay(1000); + + Battery.BatteryInfoChanged -= Battery_BatteryInfoChanged; + + static void Battery_BatteryInfoChanged(object sender, BatteryInfoChangedEventArgs e) + { + // do nothing + } + } } } diff --git a/src/Essentials/test/DeviceTests/Tests/Connectivity_Tests.cs b/src/Essentials/test/DeviceTests/Tests/Connectivity_Tests.cs index 9747ce8919bb..7fbc1bd22020 100644 --- a/src/Essentials/test/DeviceTests/Tests/Connectivity_Tests.cs +++ b/src/Essentials/test/DeviceTests/Tests/Connectivity_Tests.cs @@ -23,6 +23,22 @@ public void Distict_Connection_Profiles() Assert.Equal(profiles.Count(), profiles.Distinct().Count()); } + [Fact] + public async Task ConnectivityChanged_Does_Not_Crash() + { + Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged; + + // just ensure there is no need for the OS to "respond" to a new subscription + await Task.Delay(1000); + + Connectivity.ConnectivityChanged -= Connectivity_ConnectivityChanged; + + static void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e) + { + // do nothing + } + } + [Fact] public async Task Test() {