FindViewById<> CodeRush template

Here is an useful CodeRush editor template if you work with Mono For Android.

FindViewById<«FieldStart»«Caret»«FieldEnd»>(Resource.Id.«FieldStart»«FieldEnd»);«Target()»

I use string fv as trigger. That makes binding variables/fields to Views a bit faster and with less typing.

Example, I’d type

someView = fv

then I’d press SPACE and I’d get an extended template

someView = FindViewById<|>(Resource.Id.|);|

Then I have to type just TextView, ENTER, someView, ENTER, ENTER and I’d get

someView = FindViewById<TextView>(Resource.Id.someView);| <- this is cursor

So instead of typing the whole enchillada I had to type only the letters in yellow.

someView = fvSPACEFindViewById<TextView>(Resource.Id.someView);

With Android these statements are quite common and thus the fv template spares me a lot of typing.

But hey it can get better. If stick to a naming convetion that variable name is the same as Id name + View suffix I can enhance the template, I will name it fvx.

«FieldStart(Name)»«Caret»«Link(viewName)»«BlockAnchor»«FieldEnd»View = FindViewById<«FieldStart»«FieldEnd»>(Resource.Id.«FieldStart»«Link(viewName)»«FieldEnd»);«Target()»

Note the «Link» directive that copies the typed text. And the typing result is

fvxSPACEsomeView = FindViewById<TextView>(Resource.Id.some);

Even better now, eh. The only further improvement is to deduce the variable type and type in TextView automatically. I have to investigate this option to refine the template even further.

You can use the two templates by simply creating them in CodeRush (DevExpress/Options/Editor/Selections/Templates) or you can import them (see attached file) into templates – right click in templates list and select Import Templates…

 

CSharp_Righthand_MonoForAndroid.xml (10.42 kb)

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.