Browse Source

[Android] Fix TryGetFileFromPathAsync/TryGetFolderFromPathAsync returning null for content:// URI (#21986)

* [Android] Fix TryGetFileFromPathAsync/TryGetFolderFromPathAsync returning null for content:// URI

* [Android] Add URI scheme constants in AndroidStorageProvider
pull/22008/head
lfeng 2 months ago
committed by GitHub
parent
commit
652131ce0d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      Directory.Packages.props
  2. 1
      src/Android/Avalonia.Android/Avalonia.Android.csproj
  3. 67
      src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs

1
Directory.Packages.props

@ -69,6 +69,7 @@
<PackageVersion Include="Tmds.DBus.Generator" Version="0.94.1" />
<PackageVersion Include="Xamarin.AndroidX.AppCompat" Version="1.7.1.3" />
<PackageVersion Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.2.0.2" />
<PackageVersion Include="Xamarin.AndroidX.DocumentFile" Version="1.1.0.3" />
<PackageVersion Include="Xamarin.AndroidX.Window" Version="1.5.1.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="Xunit.StaFact" Version="3.0.13" />

1
src/Android/Avalonia.Android/Avalonia.Android.csproj

@ -12,6 +12,7 @@
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />
<PackageReference Include="Xamarin.AndroidX.AppCompat" />
<PackageReference Include="Xamarin.AndroidX.Window" />
<PackageReference Include="Xamarin.AndroidX.DocumentFile" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Avalonia.Base\Avalonia.Base.csproj" />

67
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<byte> 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;

Loading…
Cancel
Save