diff --git a/Directory.Packages.props b/Directory.Packages.props
index d38cb33b28..983d369fab 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -69,6 +69,7 @@
+
diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj
index befdcbcd5e..e22990d18c 100644
--- a/src/Android/Avalonia.Android/Avalonia.Android.csproj
+++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj
@@ -12,6 +12,7 @@
+
diff --git a/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs b/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs
index e55689f93d..66e56f3d6b 100644
--- a/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs
+++ b/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs
@@ -7,6 +7,7 @@ using Android;
using Android.App;
using Android.Content;
using Android.Provider;
+using AndroidX.DocumentFile.Provider;
using Avalonia.Platform.Storage;
using Avalonia.Platform.Storage.FileIO;
using AndroidUri = Android.Net.Uri;
@@ -18,6 +19,8 @@ namespace Avalonia.Android.Platform.Storage;
internal class AndroidStorageProvider : IStorageProvider
{
public static ReadOnlySpan AndroidKey => "android"u8;
+ private const string ContentUriScheme = "content";
+ private const string FileUriScheme = "file";
private readonly Activity _activity;
public AndroidStorageProvider(Activity activity)
@@ -62,10 +65,29 @@ internal class AndroidStorageProvider : IStorageProvider
// to read or write files in your application-specific directories [...]"
// Consequently, we don't try to check for that permission here anymore.
- var javaFile = new JavaFile(androidUriPath);
- if (javaFile.Exists() && javaFile.IsFile)
+ if (filePath.Scheme == FileUriScheme && androidUri.Path is not null)
{
- return new BclStorageFile(new System.IO.FileInfo(javaFile.AbsolutePath));
+ var javaFile = new JavaFile(androidUri.Path);
+ if (javaFile.Exists() && javaFile.IsFile)
+ {
+ return new BclStorageFile(new System.IO.FileInfo(javaFile.AbsolutePath));
+ }
+ return null;
+ }
+ else if (filePath.Scheme == ContentUriScheme && _activity.ContentResolver is not null)
+ {
+ try
+ {
+ using var stream = _activity.ContentResolver.OpenInputStream(androidUri);
+ if (stream is not null)
+ {
+ return new AndroidStorageFile(_activity, androidUri);
+ }
+ }
+ catch (Exception)
+ {
+ return null;
+ }
}
return null;
@@ -89,10 +111,43 @@ internal class AndroidStorageProvider : IStorageProvider
return null;
}
- var javaFile = new JavaFile(androidUriPath);
- if (javaFile.Exists() && javaFile.IsDirectory)
+ if (folderPath.Scheme == FileUriScheme && androidUri.Path is not null)
+ {
+ var javaFile = new JavaFile(androidUri.Path);
+ if (javaFile.Exists() && javaFile.IsDirectory)
+ {
+ return new BclStorageFolder(new System.IO.DirectoryInfo(javaFile.AbsolutePath));
+ }
+ return null;
+ }
+ else if (folderPath.Scheme == ContentUriScheme)
{
- return new BclStorageFolder(new System.IO.DirectoryInfo(javaFile.AbsolutePath));
+ try
+ {
+ if (OperatingSystem.IsAndroidVersionAtLeast(21))
+ {
+ if (DocumentsContract.IsTreeUri(androidUri))
+ {
+ var docId = DocumentsContract.GetTreeDocumentId(androidUri);
+ if (!string.IsNullOrEmpty(docId))
+ {
+ return new AndroidStorageFolder(_activity, androidUri, false);
+ }
+ }
+ else
+ {
+ var documentFile = DocumentFile.FromSingleUri(_activity, androidUri);
+ if (documentFile is not null && documentFile.Exists() && documentFile.IsDirectory)
+ {
+ return new AndroidStorageFolder(_activity, androidUri, false);
+ }
+ }
+ }
+ }
+ catch (Exception)
+ {
+ return null;
+ }
}
return null;