Writing to SD card and notifying outside world of changes

When writing a logging part of an application (Mono For Android/Visual Studio) I got some, seemingly, weird Android behaviour. Since my application transmits large strings over the net I wanted to have a history of these so I can check them out. I could do it with a simple string visualizer but the thing is that Mono For Android isn’t supporting any visualizer in Visual Studio at all – they are just not there. So I’ve decided to write those strings to a SD card in a folder accessible to Windows Explorer. Which is a better option anyway, as I could manipulate those later.

Here is the (simplified) code I use to write these to SD card

string path = Path.Combine(Context.GetExternalFilesDir(null), "file.txt");
File.WriteAllText(path, "large text here");

And I get a nice file in /Android/data/[package]/files. That’s all fine. However, Windows Explorer is unaware of newly created file at all. The file is there it just doesn’t see it. Looks like the problem is that Android (tested on two devices) doesn’t notify the outside world about the file system changes. Instead one has to do it manually. But how? AFAIK it can’t be done from within Windows Explorer.

After some googling I’ve found this stackoverflow thread. I’ve ported the MediaScannerConnection solution to C#.

public class SingleMediaScanner : Java.Lang.Object, MediaScannerConnection.IMediaScannerConnectionClient
{
    private MediaScannerConnection connection;
    private string file;

    public SingleMediaScanner(Context context, string file)
    {
        connection = new MediaScannerConnection(context, this);
        this.file = file;
    }

    public void Connect()
    {
        connection.Connect();
    }

    public void OnMediaScannerConnected()
    {
        connection.ScanFile(file, null);
    }

    public void OnScanCompleted(string path, Android.Net.Uri uri)
    {
        connection.Disconnect();
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
            connection.Dispose();
        base.Dispose(disposing);
    }

    public static void NotifyFile(Context context, string file)
    {
        SingleMediaScanner scanner = new SingleMediaScanner(context, file);
        scanner.Connect();
    }
}

One would call SingleMediaScanner.NotifyFile(Context, “FILEPATH”) to let the outside world of the changes to the file.

Not sure whether this is the best of even correct solution but it gets the job done.

Leave a Reply