Hello,
I need to show a video file in Xamarin.Forms. I have placed the MP4 file in \Internal storage\Android\data\com.mycompany.MyApp\files\Videos
Then, I tried to access it using:
string videoPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyVideos), this.viewModel.Item.Video)
But videoPath variable contains "/data/data/com.desytec.FinningApp/files/Videos/777.mp4" .
Then, I am checking file existence:
bool existing = System.IO.File.Exists(videoPath);
But "existing" returns false. I tried by changing the first "/data" to "/Android" but the file is not found either.
Any help, please?
Thanks
Jaime
Firstly you have to figure out the difference between internal and external storage: https://docs.microsoft.com/en-us/xamarin/android/platform/files/#internal-vs-external-storageEnvironment.GetFolderPath()
will retrieve internal storage which has the format /data/data/appPackageName/files/...
: https://docs.microsoft.com/en-us/xamarin/android/platform/files/#working-with-internal-storage.
The path you can browse to see the files placing on your device like \Android\data\appPackageName\files\
is a private external storage path: https://docs.microsoft.com/en-us/xamarin/android/platform/files/external-storage?tabs=windows#private-external-files.
You have to create a dependency service to obtain it on Forms. The implementation on the Android project could be like this:
[assembly:Dependency(typeof(FileSystemImplementation))] namespace App.Droid { public class FileSystemImplementation : IFileSystem { public string GetExternalStorage() { Context context = Android.App.Application.Context; var filePath = context.GetExternalFilesDir(""); return filePath.Path; } } }
At last you can store it to this path on Forms:
var folderPath = DependencyService.Get<IFileSystem>().GetExternalStorage(); var file = Path.Combine(folderPath, "video.mp4"); // Adding folders here depending on your own choice. File.WriteAllBytes(file, bytes);
@jstuardo This documentation explains what external storage is on Android. And different Android OS has different prefix names.
Maybe it will show "internal storage" when you browse it on your PC but generally, we called it external storage. And use my code above programmatically you can access any other subfolders in the external storage.
Answers
Firstly you have to figure out the difference between internal and external storage: https://docs.microsoft.com/en-us/xamarin/android/platform/files/#internal-vs-external-storage
Environment.GetFolderPath()
will retrieve internal storage which has the format/data/data/appPackageName/files/...
: https://docs.microsoft.com/en-us/xamarin/android/platform/files/#working-with-internal-storage.The path you can browse to see the files placing on your device like
\Android\data\appPackageName\files\
is a private external storage path: https://docs.microsoft.com/en-us/xamarin/android/platform/files/external-storage?tabs=windows#private-external-files.You have to create a dependency service to obtain it on Forms. The implementation on the Android project could be like this:
At last you can store it to this path on Forms:
Hello,
I have read documents but I have one question. You tell me that in my case, this is the External storage, but the device does not have an external media, and in fact, when browsing using my PC, it is named as "Internal storage":
Please look at this screenshot:
The path that is shown is:
"Este equipo\C4050-Q4\Almacenamiento interno\Android\data\com.company.MyApp"
the path means:
"This PC\C4050-Q4\Internal storage\Android\data\com.company.MyApp"
When browsing the folder using the device, this is shown:
As you see, that is Internal storage, however, I can browse using the PC, create folders and save files in there. Is it something I can do to access that folder using the app? by the way, I have seen that inside "files" folder are other called ".override" which contains the DLL's files generated by Visual Studio when deployed the app.
.
On the other hand, the document says that internal storage have the format: /data/user/0/com.companyname/files, however, the path gotten by the method call is /data/data/com.companyname.MyApp/files. Are they actually the same?
To test, I tried by hardcoding the full path "/Device storage/Android/data/com.desytec.FinningApp/files/Videos/777.mp4" but when using System.IO.File.Exists method call, false is returned, even when I can see the file is there.
Any further help to solve above questions, please?
Regards
Jaime
Hello,
Finally I understood that external storage does not mean necessarily an external media. I tried by getting the folder this way:
System.IO.Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryMovies)
Then I copied the video to the Movies folder, and it worked!
Regards
Jaime
@jstuardo This documentation explains what external storage is on Android. And different Android OS has different prefix names.
Maybe it will show "internal storage" when you browse it on your PC but generally, we called it external storage. And use my code above programmatically you can access any other subfolders in the external storage.
Thanks @LandLu,
Finally, I could do it the way you suggested. I need to implement a dependency service to get the path according to platform.
What is the equivalence of Android.OS.Environment.ExternalStorageDirectory.AbsolutePath in iOS?
Regards
Jaime
@jstuardo iOS has a different file system. Each app on iOS has its own sandbox storage: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html.
Generally, we store user's data in the Documents folder. And we could access its path on Forms directly: