找不到路径的一部分“/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://
.
的任何问题
希望这可能有所帮助。
我正在使用 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://
.
希望这可能有所帮助。