I remembered the thing, You need to get the absolute path from your uri. Usually, content:// path is returned from download folder or any drive path, you need to get actual path for it. You can try this.
Its an device specific code for Android, Inject it with dependency service.
I faced above issue in Native android & solved that as follows in Java
, below is the converted code for the same in 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;
}
EDIT -
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.
This is what I actually do in my project, whichever file is selected by the user, it is copied to Pictures Dir
in internal storage & returns the path.
We deal with the ImageStream
to make a copy of the original document.
The idea to make a duplicate copy is that we uses the copy for uploading purpose as the user may delete the original document selected. So after pushing the document to the server, we delete the copied file as well. So as we deal with the stream we don't face any issue with Content://
.
Hope this maybe helpful.