0

I have a Xamarin Forms project in which I need the user to be able to "load" an image. I can already press a button and search for a file using FilePicker like this:

async void OnUpload(object sender, EventArgs e)
        {
            try
            {
                FileData filedata = await CrossFilePicker.Current.PickFile();
                // the dataarray of the file will be found in filedata.DataArray 
                // file name will be found in filedata.FileName;
                //etc etc.
            }
            catch (Exception ex)
            {
            }
        } 

What I would need now is to copy that "filedata" (the image) to the resource folder of the project in order to access to the file easily. I have tried:

await CrossFilePicker.Current.SaveFile(filedata.FileName);

but it doesn't save any file into the project folder. Moreover, I only need it to work on UWP and Android.

Josemafuen
  • 682
  • 2
  • 16
  • 41

1 Answers1

3

The SaveFile method saves it in a very specific folder.

If you want to save it somewhere of your choosing you have to implement it with the DependencyService. IO operations are very specific to the OS, so are the filepaths. I will give you a simple example for you to build on.

Start with defining an interface in your shared code, like so:

public interface IFileManager
{
    void SaveFile(Stream stream);
}

Of course, it can have other methods as well, or extra parameters if you would like to specify things like filename, that is up to you. You would also probably like some kind of return value to know what happened.

Now, per platform implement this interface. For example for Android, it could look like this:

[assembly: Xamarin.Forms.Dependency (typeof (FileManager_Android))]

public class FileManager_Android : IFileManager
{
    public void SaveFile(Stream stream)
    {
        var dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim);

        string filename = System.DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg";
        string filePath = System.IO.Path.Combine(dir, name);

        try
        {
            System.IO.File.WriteAllBytes(filePath, imageData);
        }
        catch (Exception ex)
        {
            System.Console.WriteLine(e.ToString());
        }
    }
}

(Saving code inspired by this link)

This will take the stream and save it to a path of your choosing.

For UWP you will need to implement it as well, which is quite similar, except for the implementation of SaveFile. As far as I know there is no plugin yet which makes this easier for you. There is PCLStorage, but this plugin only seems to work with text files. You could still look into it for inspiration though.

Gerald Versluis
  • 30,492
  • 6
  • 73
  • 100
  • Awesome, thank you, the only problem is that I don't want to save it in an external folder like Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim); But in the Drawable folder – Josemafuen Mar 29 '17 at 12:10
  • You cannot write in that folder after your app is on the device. Also see this [SO post](http://stackoverflow.com/questions/3374061/write-to-res-drawable-on-the-fly) on this. If it has helped you please accept it as an answer. – Gerald Versluis Mar 29 '17 at 12:20