I am attempting to write a file on an Android device. I would then like to be able to easily transfer that file to a Windows computer for viewing and analysis.
Needless to say, I am having a lot of issues doing this. I am using .Net MAUI, and my Android device is a Samsung Galaxy Tab A7 Lite running Android 13.
I am running the following code to write a test file. I also have some code inserted as a sanity check to immediately read the file that I wrote:
string target_file = System.IO.Path.Combine(FileSystem.Current.AppDataDirectory, "test_file.txt");
using (FileStream output_stream = System.IO.File.OpenWrite(target_file))
{
using (StreamWriter stream_writer = new StreamWriter(output_stream))
{
stream_writer.Write("hello, world!");
}
}
using (FileStream input_stream = System.IO.File.OpenRead(target_file))
{
using (StreamReader stream_reader = new StreamReader(input_stream))
{
var input_text = stream_reader.ReadToEnd();
}
}
This code is working. It is writing a file, and I am am able to read the file. The problem is that I am not able to see this file anywhere outside of the application. I can't see it in the Android "My Files" app on the Samsung tablet, nor can I see it in the Windows File Explorer when I connect my Android tablet to the PC.
The file is supposedly at the following path: "/data/user/0/[com.companyname.appname]/files/test_file.txt"
According to the comments in the following Stack Overflow posts, the "solution" is to save to a "shared" folder, because apparently the private app data folder is not viewable with Windows File Explorer:
- Creating and Writing to a text file on Android .NET MAUI
- .NET MAUI writing file in android to folder that then can be accessed in windows file explorer
Unfortunately, the answer posted on this post does not work:
.NET MAUI writing file in android to folder that then can be accessed in windows file explorer
It once again just directs the saved file to be in the app's private data folder. Specifically, it tries to save at this path:
"/storage/emulated/0/Android/data/[com.companyname.appname]/files/Documents"
One suggestions that has been made is to use the .Net MAUI FileSaver (https://learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/essentials/file-saver?tabs=android). While this may seemingly allow saving to a shared folder (I haven't yet tested it to fully find out), it would require user interaction to actually select the save location of the file, which is unacceptable in this scenario. My app needs to be able to save log files to a very specific folder at any time (without user interaction), and then periodically the user needs to be able to transfer those files to a computer for viewing/analysis.
Any suggestions on how to solve this issue?
For those wondering how to write files to a public folder, especially using .Net MAUI, I figured out how to do it. Here is how:
First off, my main resources were these two posts:
The following documentation was also helpful:
Anyways, step 1 is to define a partial class that can then be re-defined on a per-platform basis. Here is my partial class:
As you see, I'm basically wanting to implement 3 functions:
(1) a function to let the user select a folder - this folder will have persistable permissions so we can always read/write from/to it. It will be a public folder, not a folder a folder private to the app. (2) a function to actually write data to a file (3) a function to check and see if the folder location has been selected and permissions have been given.
Now, for .Net MAUI, assuming you want to actually deploy your app to multiple platforms, you would need to define these functions for each platform. For the sake of this post, we are only concerned about Android.
So here is my Android implementation of these functions:
Next, on the actual Android activity class, we will need to handle the result of the
RequestSelectLogFolderfunction - because it callsStartActivityForResult. So in our Android activity, we need to overrideOnActivityResultand then do a bit of work to handle that result. Here is my implementation:Finally, having done all of this, we should be good to go. We will be able to read/write files to the user-specified public directory on the Android device, and these permissions will be persisted across app restarts and across device reboots.
So, to actually use this code, I could do something like the following. Let's assume the user presses the button in the UI, and I want to write data to a file when the user presses that button. This could be my code inside of my button event-handler:
There we go. That's all of it. Hope this helps someone in the future.