diff --git a/src/Essentials/src/Permissions/Permissions.android.cs b/src/Essentials/src/Permissions/Permissions.android.cs index 7aa6d6ab3f2d..bb41d846c2d6 100644 --- a/src/Essentials/src/Permissions/Permissions.android.cs +++ b/src/Essentials/src/Permissions/Permissions.android.cs @@ -521,14 +521,75 @@ public override (string androidPermission, bool isRuntime)[] RequiredPermissions public partial class StorageRead : BasePlatformPermission { - public override (string androidPermission, bool isRuntime)[] RequiredPermissions => - new (string, bool)[] { (Manifest.Permission.ReadExternalStorage, true) }; + public override (string androidPermission, bool isRuntime)[] RequiredPermissions + { + get + { + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + { + return []; + } + + return new (string, bool)[] { (Manifest.Permission.ReadExternalStorage, true) }; + } + } + + public override Task RequestAsync() + { + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + { + return Task.FromResult(PermissionStatus.Granted); + } + + return base.RequestAsync(); + } + + public override Task CheckStatusAsync() + { + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + { + return Task.FromResult(PermissionStatus.Granted); + } + + return base.CheckStatusAsync(); + } } public partial class StorageWrite : BasePlatformPermission { - public override (string androidPermission, bool isRuntime)[] RequiredPermissions => - new (string, bool)[] { (Manifest.Permission.WriteExternalStorage, true) }; + public override (string androidPermission, bool isRuntime)[] RequiredPermissions + { + + get + { + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + { + return []; + } + + return new (string, bool)[] { (Manifest.Permission.WriteExternalStorage, true) }; + } + } + + public override Task RequestAsync() + { + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + { + return Task.FromResult(PermissionStatus.Granted); + } + + return base.RequestAsync(); + } + + public override Task CheckStatusAsync() + { + if (OperatingSystem.IsAndroidVersionAtLeast(33)) + { + return Task.FromResult(PermissionStatus.Granted); + } + + return base.CheckStatusAsync(); + } } public partial class Vibrate : BasePlatformPermission diff --git a/src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt b/src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt index 0373cf272708..7b22ecc4b5bd 100644 --- a/src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt +++ b/src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt @@ -55,4 +55,8 @@ static Microsoft.Maui.Devices.Sensors.Geolocation.StopListeningForeground() -> v *REMOVED*Microsoft.Maui.Media.IMediaPicker.CapturePhotoAsync(Microsoft.Maui.Media.MediaPickerOptions? options = null) -> System.Threading.Tasks.Task! *REMOVED*Microsoft.Maui.Media.IMediaPicker.CaptureVideoAsync(Microsoft.Maui.Media.MediaPickerOptions? options = null) -> System.Threading.Tasks.Task! *REMOVED*Microsoft.Maui.Media.IMediaPicker.PickPhotoAsync(Microsoft.Maui.Media.MediaPickerOptions? options = null) -> System.Threading.Tasks.Task! -*REMOVED*Microsoft.Maui.Media.IMediaPicker.PickVideoAsync(Microsoft.Maui.Media.MediaPickerOptions? options = null) -> System.Threading.Tasks.Task! \ No newline at end of file +*REMOVED*Microsoft.Maui.Media.IMediaPicker.PickVideoAsync(Microsoft.Maui.Media.MediaPickerOptions? options = null) -> System.Threading.Tasks.Task! +~override Microsoft.Maui.ApplicationModel.Permissions.StorageRead.CheckStatusAsync() -> System.Threading.Tasks.Task +~override Microsoft.Maui.ApplicationModel.Permissions.StorageRead.RequestAsync() -> System.Threading.Tasks.Task +~override Microsoft.Maui.ApplicationModel.Permissions.StorageWrite.CheckStatusAsync() -> System.Threading.Tasks.Task +~override Microsoft.Maui.ApplicationModel.Permissions.StorageWrite.RequestAsync() -> System.Threading.Tasks.Task \ No newline at end of file diff --git a/src/Essentials/test/DeviceTests/Tests/Permissions_Tests.cs b/src/Essentials/test/DeviceTests/Tests/Permissions_Tests.cs index 8de912fd1e83..615aae993237 100644 --- a/src/Essentials/test/DeviceTests/Tests/Permissions_Tests.cs +++ b/src/Essentials/test/DeviceTests/Tests/Permissions_Tests.cs @@ -1,6 +1,10 @@ +using System; using System.Threading.Tasks; using Microsoft.Maui.ApplicationModel; +using Microsoft.Maui.Devices; +using Microsoft.Maui.Dispatching; using Xunit; +using Xunit.Sdk; namespace Microsoft.Maui.Essentials.DeviceTests { @@ -74,5 +78,30 @@ await Task.Run(async () => await Assert.ThrowsAsync(async () => await Permissions.RequestAsync()); }); } + + [Fact +#if !__ANDROID__ + (Skip = "Test only applies to Android") +#endif + ] + public async Task StorageAndroid13AlwaysGranted() + { + if (DeviceInfo.Platform == DevicePlatform.Android && OperatingSystem.IsAndroidVersionAtLeast(33)) + { + var status = await Permissions.CheckStatusAsync(); + Assert.Equal(PermissionStatus.Granted, status); + + status = await Permissions.CheckStatusAsync(); + Assert.Equal(PermissionStatus.Granted, status); + } + else // Android < API 33, we didn't request these, so status denied + { + var status = await Permissions.CheckStatusAsync(); + Assert.Equal(PermissionStatus.Denied, status); + + status = await Permissions.CheckStatusAsync(); + Assert.Equal(PermissionStatus.Denied, status); + } + } } }