From 56cbcb553930fa7863438e5599f1fd7c714639a0 Mon Sep 17 00:00:00 2001 From: Vit Nemecky Date: Fri, 8 Dec 2023 00:08:30 +0100 Subject: [PATCH] Fix detection of storage folder for both 33+ Android API and legacy ones --- .../ReadWriteExternalStoragePermission.cs | 18 +++++++---- .../SharedFileStorageService.cs | 30 +++++++++++++++++-- .../Properties/AndroidManifest.xml | 4 +-- .../SharedFileStorageService.cs | 4 ++- .../ISharedFileStorageService.cs | 2 ++ .../ViewModels/CreationListPageViewModel.cs | 2 +- 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/BrickController2/BrickController2.Android/PlatformServices/Permission/ReadWriteExternalStoragePermission.cs b/BrickController2/BrickController2.Android/PlatformServices/Permission/ReadWriteExternalStoragePermission.cs index c10912e2..9f0e4a73 100644 --- a/BrickController2/BrickController2.Android/PlatformServices/Permission/ReadWriteExternalStoragePermission.cs +++ b/BrickController2/BrickController2.Android/PlatformServices/Permission/ReadWriteExternalStoragePermission.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Android.OS; +using System; using static Xamarin.Essentials.Permissions; using BrickController2.PlatformServices.Permission; @@ -6,10 +7,15 @@ namespace BrickController2.Droid.PlatformServices.Permission { public class ReadWriteExternalStoragePermission : BasePlatformPermission, IReadWriteExternalStoragePermission { - public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)> - { - (Android.Manifest.Permission.ReadExternalStorage, true), - (Android.Manifest.Permission.WriteExternalStorage, true) - }.ToArray(); + public override (string androidPermission, bool isRuntime)[] RequiredPermissions => ((int)Build.VERSION.SdkInt <= 32) ? + // Android API 32 and older - ask for permissions + new (string androidPermission, bool isRuntime)[] + { + (Android.Manifest.Permission.ReadExternalStorage, true), + (Android.Manifest.Permission.WriteExternalStorage, true) + } : + // Android API 33+ does not support permissions to external storage + // Let it be Granted (via empty permission list) + Array.Empty<(string androidPermission, bool isRuntime)>(); } } \ No newline at end of file diff --git a/BrickController2/BrickController2.Android/PlatformServices/SharedFileStorage/SharedFileStorageService.cs b/BrickController2/BrickController2.Android/PlatformServices/SharedFileStorage/SharedFileStorageService.cs index 7bc66209..e1ee0e39 100644 --- a/BrickController2/BrickController2.Android/PlatformServices/SharedFileStorage/SharedFileStorageService.cs +++ b/BrickController2/BrickController2.Android/PlatformServices/SharedFileStorage/SharedFileStorageService.cs @@ -26,14 +26,18 @@ public bool IsPermissionGranted } } - public string SharedStorageDirectory + public string SharedStorageBaseDirectory { get { try { #pragma warning disable CS0618 // Type or member is obsolete - var storageDirectory = Environment.ExternalStorageDirectory?.AbsolutePath; + var storageDirectory = ((int)Build.VERSION.SdkInt <= 32) ? + // Android API 32 and older - keep backward compatible: /storage/emulated/0/ + Environment.ExternalStorageDirectory?.AbsolutePath : + // Android API 33+ - use /storage/emulated/0/Documents + Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDocuments)?.AbsolutePath; var storageState = Environment.ExternalStorageState; #pragma warning restore CS0618 // Type or member is obsolete @@ -42,6 +46,28 @@ public string SharedStorageDirectory return null; } + return storageDirectory; + } + catch (Exception) + { + return null; + } + } + } + + public string SharedStorageDirectory + { + get + { + try + { + var storageDirectory = SharedStorageBaseDirectory; + + if (storageDirectory == null) + { + return null; + } + var bc2StorageDirectory = Path.Combine(storageDirectory, _brickController2SharedDirectory); if (!Directory.Exists(bc2StorageDirectory)) diff --git a/BrickController2/BrickController2.Android/Properties/AndroidManifest.xml b/BrickController2/BrickController2.Android/Properties/AndroidManifest.xml index 463938b9..8f8747c2 100644 --- a/BrickController2/BrickController2.Android/Properties/AndroidManifest.xml +++ b/BrickController2/BrickController2.Android/Properties/AndroidManifest.xml @@ -8,8 +8,8 @@ - - + + diff --git a/BrickController2/BrickController2.iOS/PlatformServices/SharedFileStorage/SharedFileStorageService.cs b/BrickController2/BrickController2.iOS/PlatformServices/SharedFileStorage/SharedFileStorageService.cs index a583e9c1..759926ec 100644 --- a/BrickController2/BrickController2.iOS/PlatformServices/SharedFileStorage/SharedFileStorageService.cs +++ b/BrickController2/BrickController2.iOS/PlatformServices/SharedFileStorage/SharedFileStorageService.cs @@ -21,7 +21,9 @@ public bool IsPermissionGranted } } - public string SharedStorageDirectory + public string SharedStorageDirectory => SharedStorageBaseDirectory; + + public string SharedStorageBaseDirectory { get { diff --git a/BrickController2/BrickController2/PlatformServices/SharedFileStorage/ISharedFileStorageService.cs b/BrickController2/BrickController2/PlatformServices/SharedFileStorage/ISharedFileStorageService.cs index 9f63067e..0cc50dd2 100644 --- a/BrickController2/BrickController2/PlatformServices/SharedFileStorage/ISharedFileStorageService.cs +++ b/BrickController2/BrickController2/PlatformServices/SharedFileStorage/ISharedFileStorageService.cs @@ -6,6 +6,8 @@ public interface ISharedFileStorageService bool IsPermissionGranted { get; set; } + string SharedStorageBaseDirectory { get; } + string SharedStorageDirectory { get; } } } diff --git a/BrickController2/BrickController2/UI/ViewModels/CreationListPageViewModel.cs b/BrickController2/BrickController2/UI/ViewModels/CreationListPageViewModel.cs index c47fafdd..7463ca40 100644 --- a/BrickController2/BrickController2/UI/ViewModels/CreationListPageViewModel.cs +++ b/BrickController2/BrickController2/UI/ViewModels/CreationListPageViewModel.cs @@ -124,7 +124,7 @@ await _dialogService.ShowMessageBoxAsync( _disappearingTokenSource.Token.ThrowIfCancellationRequested(); } - if (SharedFileStorageService.SharedStorageDirectory != null) + if (SharedFileStorageService.SharedStorageBaseDirectory != null) { var storagePermissionStatus = await _readWriteExternalStoragePermission.CheckStatusAsync(); if (storagePermissionStatus != PermissionStatus.Granted && !_isStoragePermissionRequested)