I've created a new file using XmlSerializer and StreamWriter to persist data. From the test I did with my app, storing and restoring data using this method is working. Just for curiosity, I've tried to find the file created in the Android File System, without success. I've tried to find it with an Android app (ES File Explorer) and a desktop app (on Mac, Android File Transfer). In both case, I was unable to find the created file.
XmlSerializer xmlSerializer = new XmlSerializer (typeof(GAData));
TextWriter writer = new StreamWriter (FilePath);
xmlSerializer.Serialize (writer, this);
writer.Close ();
Console.WriteLine ("Data saved");
Where FilePath is define here :
// Determining the path
var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
FilePath = Path.Combine (documentsPath, "AppData.txt");
Console.WriteLine (Path.GetFullPath (FilePath));
The last Console.WriteLine is logging : /data/data/com.domain.myapp/files/AppData.txt
The exact same code is working like a charm on iOS, and I can see the file in the File System using an app on my Mac. Why can I find it in the Android File System? Or, where is it saved if it's somewhere else?
/data/data/com.domain.myapp/files/AppData.txt
That is private internal memory. Private as only your app has access.
Your app can reach it using getFilesDir().
Other app like ES File Explorer have no access.
You should be using FilesDir from the ContextWrapper
Path.Combine(FilesDir.Path , "MyFile.text");
Example, copies a file that is in the assets folder to the local file system
if (!File.Exists(Path.Combine(FilesDir.Path , "myFile.Text")))
{
using (var asset = Assets.Open("TextToCopyTo.txt"))
{
using (var dest = File.Create(Path.Combine(FilesDir.Path , "MyFile.text")))
{
asset.CopyTo(dest);
}
}
}
Related
I'm using Launcher.Default.OpenAsync(OpenFileRequest request) to open a PDF file in an external PDF editor. The file loads correctly, but to edit the document this external app asks you to make a copy and edit over that copy, not the original file. I can edit the original file if I open the PDF using the device (Galaxy Tab S6 Lite) file explorer but it's not possible to do the same if I open the same file from my MAUI app.
I see OpenFileRequest constructor asks for a ReadOnlyFile. Is there a way I could create an "OpenFileRequest" with write permissions, or an alternative way to launch the document editor with the file so I can edit it without having to create a copy?
Example code:
var filename = "example.pdf";
var file = new ReadOnlyFile(filename);
var openFileRequest = new OpenFileRequest("PDF Document", file);
await Launcher.Default.OpenAsync(openFileRequest);
I have tried to edit the pdf file with the Pdf Editor in some other apps. But all of them need to save as another file. So it seems only the file explorer can edit the original file.
In addition, the ReadOnlyFile is inherited from the FileBase. So you can try:
var filename = "example.pdf";
var file = new ReadOnlyFile(filename);
var openFileRequest = new OpenFileRequest("PDF Document", file as FileBase);
await Launcher.Default.OpenAsync(openFileRequest);
Actually, the other app doesn't have the permission to write the file in your app. You can refer to this case which is about editing pdf with external application does not overwrite existing file.
I can't find any native android api about grant the others app the write permission of the existing file. This should be the android permission limit.
I have a list of arrays of data in my app that I would now like to write to a file (csv) and use a 3rd party app (such as email) to share this csv file. I have had no luck finding any helpful resources for creating, finding the file path for, and appending to a file in Kotlin. Does anyone have experience with this or have examples to point to? Just to get started I'm trying to write the header and close the file so I can see that it is correctly writing.
This is what I have for now:
val HEADER = "ID, time, PSI1, PSI2, PSI3, speed1, speed2, temp1, temp2"
val filename = "export.csv"
var fileOutStream : FileOutputStream = openFileOutput(filename,Context.MODE_PRIVATE)
try {
fileOutStream.write(HEADER.toByteArray())
fileOutStream.close()
}catch(e: Exception){
Log.i("TAG", e.toString())
}
It doesn't throw the exception, but I cannot find the file in the file system. I'm using a physical tablet for testing/debug. I've checked the com.... folder for my app.
I cannot find the file in the file system
Use Android Studio's Device File Explorer and look in /data/data/.../files/, where ... is your application ID.
Also, you can write your code a bit more concisely as:
try {
PrintWriter(openFileOutput(filename,Context.MODE_PRIVATE)).use {
it.println(HEADER)
}
} catch(e: Exception) {
Log.e("TAG", e.toString())
}
use() will automatically close the PrintWriter, and PrintWriter gives you a more natural API for writing out text.
It appears there are many ways to create a file and append to it, depending on the minimum API version you are developing for. I am using minimum Android API 22. The code to create/append a file is below:
val HEADER = "DATE,NAME,AMOUNT_DUE,AMOUNT_PAID"
var filename = "export.csv"
var path = getExternalFilesDir(null) //get file directory for this package
//(Android/data/.../files | ... is your app package)
//create fileOut object
var fileOut = File(path, filename)
//delete any file object with path and filename that already exists
fileOut.delete()
//create a new file
fileOut.createNewFile()
//append the header and a newline
fileOut.appendText(HEADER)
fileOut.appendText("\n")
/*
write other data to file
*/
openFileOutput() creates a private file, likely inside of app storage. These files are not browsable by default. If you want to create a file that can be browsed to, you'll need the WRITE_EXTERNAL_STORAGE permission, and will want to create files into a directory such as is provided by getExternalFilesDir()
I want to import pdf in my xamarin android project.
I want to have a pdf in my application folder at the installation of the application.
Bu when i try to add this pdf in android ressources and try to open it, i get a path error.
i save my pdf in draxable ressource and call path like : #drawable/pdfname or pdfname. the two solution don t work.
Best regards,
ok, i put it in the asset folder. I want to send email with attachement. I try this but the app said me the file is empty. var file = new Java.IO.File("Assets/CV_2017.pdf"); var uri = Android.Net.Uri.FromFile(file); i set my ressource as "build as android asset".
To get the url of the file in assets folder, you can code for example like this:
var file = new File(Android.Net.Uri.Parse("file:///android_asset/CV_2017.pdf").ToString());
if (file.Exists())
{
var uri = file.AbsolutePath;
}
If you want to access the stream of the file under assets, you can use AssetManager and code for example like this:
AssetManager assets = this.Assets;
using (StreamReader sr = new StreamReader (assets.Open ("CV_2017.pdf")))
{
//TODO:
}
I have an android app where I am writing data (csv format) to the filesystem for export.
The app writes the file without any problem (I can see it in the file manager app). The issue is when I plug my device into my PC, the file doesn't show up?
I am writing to the downloads directory using this code to get the file path:
public File getDataStorageDir() {
// Get the directory for the user's public pictures directory.
File base = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
base = new File(base, "F3F");
base.mkdirs();
File file = new File(base.getAbsolutePath() + String.format("/%s.txt", mRace.name));
return file;
}
I can export the file to dropbox or email it, but I would also like to be able to plug in via usb and drag it off the filesystem. Could this be something to do with permissions?
Thanks
I'm new to android development and I am working on a little project. What I am having some issue with is getting access to preloaded files.
In my app, I have an XML file that I preloaded (I just simply put it in my src folder in a package). How do I access them in my classes? I need to get a File object pointing to this file so that I can use it as I would I/O files. It seems like this should be trivial, but alas I am stuck.
Lets say the file is located under: com.app.preloadedFiles/file1.XML
I've tried something along the lines of this, but have had no success:
URL dir_url = ClassLoader.getSystemResource("preloadedFiles/file1.XML");
FIle file = new File(dir_url.toURI());
I solved this in my app by getting an InputStream to the file -- something like:
myContext.getAssets().open(fileName);
//read the data and store it in a variable
Then, if you truly need to do File related opterations with it, you can write it to a private (or public) directory and do your operations from you newly written file. Something like:
File storageDir = myContext.getDir(directoryName, Context.MODE_PRIVATE);
File myFile = new File(storageDir + File.separator + fileName);
//then, write the data to the file and manipulate it -- store the name for access via File later