Xamarin Media Plugin
I am using the xamarin forms media plugin (by james montemagno) and the actual image capture and saving works fine, I debugged the image creation on an emulator and was stored in
/storage/emulated/0/Android/data/{APPNAME}.Android/files/Pictures/{DIRECTORYNAME}/{IMAGENAME}
however in my application it will get a list of filenames from the API which I want to check if the image exists in that folder.
The following works fine on IOS:
var documentsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string jpgFilename = System.IO.Path.Combine(documentsDirectory, App.IMAGE_FOLDER_NAME);
jpgFilename = System.IO.Path.Combine(jpgFilename, name);
I tried the following two methods to get it on Android, but both are wrong.
var documentsDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string jpgFilename = System.IO.Path.Combine(documentsDirectory, App.IMAGE_FOLDER_NAME);
jpgFilename = System.IO.Path.Combine(jpgFilename, name);
Java.IO.File dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DataDirectory + "/" + App.IMAGE_FOLDER_NAME + "/" + name);
dir ends with / Store / emulate / 0 / data / {tEL} / {ImageName}
jpgFileName ends with / data / data / {APPNAME} .Android / files / {DIRECTORYNAME} / {IMAGENAME}
I don't want to hardcode any paths, but none of them are correct. I have not found anything in the GIT documentation for getting the file path other than by looking at the path to the file generated by the capture
Problem
I had the same problem with the Xamarin Media Plugin. For me the problem is this:
- We really don't know where the plugin will save the image on Android.
After reading all the documentation I found, I just noted this:
... When your user takes a photo , it will still save the temporary data , but if necessary, make a copy in a public gallery (based on the platform). In the MediaFile, you will now see the AlbumPath, which you can also query.
(from: Plugin Github Page )
- to save the photo to the phone gallery (it will be public), but this way is known.
- and we don't know what it means to store temporary data.
Decision
After exploring how / where an app can store data, I found where the plugin stores photos on Android -> so I can generate back full filenames
In your Android app, the main path you are looking for is:
var basePath = Android.App.Application.Context.GetExternalFilesDir(null).AbsolutePath
It refers to the external private folder of the application . It looks like this:
/storage/emulated/0/Android/data/com.mycompany.myapp/files
So, to get the full path to the file:
var fullPath = basePath + {DIRECTORYNAME} + {FILENAME};
I suggest you make a dependency service like "ILocalFileService" that will expose this "base path" property.
Please let me know if this works for you!
I solved a similar problem. I wanted to collect all files for my application in a folder visible to all users.
var documentsDirectory = Android.OS.Environment.GetExternalStoragePublicDirectory(
Android.OS.Environment.DirectoryDocuments);
If you want to create Directory
, add to your class using System.IO;
and you will have the same functionality in a normal .NET application.
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
If you want to create files or directory, you can use PCLStorage
.
public async Task<bool> CreateFileAsync(string name, string context)
{
// get hold of the file system
IFolder folder = FileSystem.Current.LocalStorage;
// create a file, overwriting any existing file
IFile file = await folder.CreateFileAsync(name,
CreationCollisionOption.ReplaceExisting);
// populate the file with some text
await file.WriteAllTextAsync(context);
return true;
}