找不到路径的一部分“/content:/com.android.externalstorage.documents/document/6759-130B%3ANew%20Text%20Document.txt”

Could not find a part of the path "/content:/com.android.externalstorage.documents/document/6759-130B%3ANew%20Text%20Document.txt"

我正在使用 FilePicker-Plugin-for-Xamarin-and-Windows 并在访问外部存储时遇到此错误 :

Could not find a part of the path "/content:/com.android.externalstorage.documents/document/6759-130B%3ANew%20Text%20Document.txt".

注意:我有读和写权限,而且我在运行时询问用户。
使用此路径时问题消失了:

storage/6759-130B%3ANew%20Text%20Document.txt

这是选择器中 非常著名的老错误 officially mentioned

对我来说,我似乎必须将 content:// 转换为 file path.

更多info

我想起来了,你需要从你的 uri 中获取绝对路径。通常,content:// 路径是从下载文件夹或任何驱动器路径返回的,您需要获取它的实际路径。你可以试试这个。

Its an device specific code for Android, Inject it with dependency service.

我在 Native android 中遇到了上述问题并在 Java 中解决了以下问题,下面是在 c#

中相同的转换代码
private string GetRealPathFromURI(Uri contentURI)
{
    ICursor cursor = ContentResolver.Query(contentURI, null, null, null, null);
    cursor.MoveToFirst();
    string documentId = cursor.GetString(0);
    documentId = documentId.Split(':')[1];
    cursor.Close();

    cursor = ContentResolver.Query(
    Android.Provider.MediaStore.Images.Media.ExternalContentUri,
    null, MediaStore.Images.Media.InterfaceConsts.Id + " = ? ", new [] { documentId }, null);
    cursor.MoveToFirst();
    string path = cursor.GetString(cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.Data));
    cursor.Close();

    return path;
}

编辑 -

Try this

       FileData fileData = await CrossFilePicker.Current.PickFile();
       string filePath;
       if (fileData != null)
       {
            await Task.Run(() => {
            filePath = DependencyService.Get<IImageUtilities>().SaveFileFromStream(new MemoryStream(fileData.DataArray), fileData.FileName));
        });

Code for Xamarin.Android

public string SaveFileFromStream((System.IO.Stream imageStream,  string filename)
{
            string name = filename;
            string filePath = null;
            try
            {
                byte[] imageData = ((MemoryStream)imageStream).ToArray();
                IFolder folder = FileSystem.Current.GetFolderFromPathAsync(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures).ToString()).Result;
                IFile file = folder.CreateFileAsync(name, CreationCollisionOption.GenerateUniqueName).Result;
                filePath = System.IO.Path.Combine(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures).ToString(), file.Name);

                System.IO.Stream outputStream = file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite).Result;
                outputStream.Write(imageData, 0, imageData.Length);
                outputStream.Flush();
                outputStream.Close();
            }
            catch(Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            return filePath;
}

Later on, the new path of the file is used everywhere needed accordingly.

这就是我在我的项目中实际做的,无论用户选择哪个文件,它都会被复制到内部存储中的 Pictures Dir & returns 路径。

我们处理 ImageStream 制作原始文档的副本。 制作副本的想法是我们将副本用于上传目的,因为用户可能会删除所选的原始文档。所以在将文档推送到服务器后,我们也删除了复制的文件。因此,当我们处理流时,我们不会遇到 Content://.

的任何问题

希望这可能有所帮助。