Search code examples
c#androidxamarinandroid-4.1-jelly-bean

Xamarin Android 16 Jelly Bean / 4.1 create folder and file


I know c#; have developed for windows mobile; I now have an android project with constraints that I cannot change; the most important being cannot run above API 16 due to the devices the app will be running on. These devices are already purchased. I’m aware of the age of these devices, and how old 4.1 is; hands tied.

I’ve started a new Xamarin (not forms) project for android only; compile using 8.1 Oreo; Min version 4.1, target version 8.1. I’m aware this is not ideal however doing so I’ve managed to get lots of other needed features working including camera and barcode scanner. Changing compile version down to 4.1 causes numerous errors which won’t compile.

I’m testing the device using usb-debugging on the actual device and even though it’s 4.1, the code runs and features work – camera, scanner etc.

I’m stuck trying to create a folder and then write/read a file in that folder. I’d like this folder to be accessible via windows explorer when plugged into computer.

I’ve got code like this to write a file:

string FileContents = "Text file contents";

Java.IO.File SaveFolder = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory("Documents") + Java.IO.File.Separator + "FolderName");

Boolean Success = false;
if (!SaveFolder.Exists())
{
    Success = SaveFolder.Mkdirs();
}

string FName = "test.txt";
string FTogether = System.IO.Path.Combine(SaveFolder.Path, FName);

Java.IO.FileWriter fw = new Java.IO.FileWriter(FTogether);
fw.Write(FileContents);
fw.Close();
SaveFolder.Dispose();

And code like this to read the file:

Java.IO.File SaveFolder = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory("Documents") + Java.IO.File.Separator + "FolderName");

string FName = "test.txt";
string FTogether = System.IO.Path.Combine(SaveFolder.Path, FName);

StreamReader sr = new StreamReader(FTogether);
string FileContents = sr.ReadToEnd(); 

Debugging reveals SaveFolder’s AbsolutePath to be /storage/sdcard0/Documents/FolderName

I think this is part of the android’s internal storage which the app has access to but nothing else.

How do I get a folder which is accessible from outside the app ?

Environment.DirectoryDocuments 

cannot be used because it’s null at runtime on API 16.


Solution

  • The path you have is actually publicly accessible so it's not specific to your application. When you connect your Android device to the computer, you should be able to go to the root folder of the device and see the Documents folder.

    Don't let the /storage/sdcard0/ part in the beginning of the path confuse you. For historical reasons, Android simulates an sdcard even if there isn't one physically on the device. In reality, /storage/sdcard0/ is just a symlink to /data/media/0.

    For a really good overview of Android storage, I'd recommend you read this very thorough Reddit post: Let's clear up the confusion regarding storage in Android once and for all, including adoptable storage in Marshmallow.

    What you can also do is download a file explorer app (in case your phone doesn't already have one) and go to the Documents folder. You should see FolderName there.


    Edit: Since you're running on such an old version of you might also suffer from the bug in the MTP protocol, which causes newly created files and folders to be invisibile when attaching the device to a computer via USB.

    The fix is to call MediaScannerConnection.scanFile for each new file/folder you've created, as explained here.