Platform specific code with Xamarin and Prism

When writing platform specific code within our iOS, Android and UWP projects we can use the built-in lightweight dependency injection code and attributes that comes out of the box with Xamarin, but when using Prism we’re probably using Unity or DryIoc as our preferred IoC library.

Let’s look at a simple example, whereby I have an interface in my shared code, which looks like this

public interface IFileService
{
   void Save(string data);
}

although there is file handling code etc. in .NET standard and we can implement something like this in the shared code, maybe we want some other more specific platform code. Here’s an Android file (i.e. within the Android project)

[assembly: Dependency(typeof(FileService))]
namespace Droid.Services
{
    public class FileService : IFileService
    {
        public void Save(string data)
        {
            // some Android specific code
        }
    }
}

The use of the DependencyAttribute makes this class available via Xamarin Forms built-in DependencyService, but not available to DryIoc, for example – hence what we want to do is use the built-in DI container and map this to our preferred IoC library.

All we need to do in our shared project’s App.xaml.cs file within the RegisterTypes method, we just do something like this

containerRegistry.RegisterInstance(DependencyService.Get<IFileService>());

Simple.

Adding SQLite to my Xamarin forms application

To be totally honest, this post Xamarin.Forms Local Databases covers everything you need to know.

Simply add Frank Krueger’s NuGet package to your shared code project. This library is both a database access library and ORM.

We’ll need to create the database file, hence we can create our file location using the following

private static readonly string DatabaseLocation =
   Path.Combine(
      Environment.GetFolderPath
        (Environment.SpecialFolder.LocalApplicationData), 
        "Capture.db3");

Create the database

var database = new SQLiteAsyncConnection(DatabaseLocation);
await database.CreateTableAsync<DataItem>();

Depending on the use case it may be best to create the database connection when the application starts and keep available whilst the application is running. In this instance my calls to the DB are going to be dictated by the user, i.e. pressing a button, so we can create the connection, then create a table for our data objects.

Note: The data object stored into the database must have a default constructor and not be abstract etc. for it to work with the ORM part of this library.

Closing the database

The database connection does not support the IDisposable interface, so we need to explicitly call

await database.CloseAsync();

Note: I’ve not checked the source for the library and had no issues with not closing the connection.

Inserting items into the database

We can insert new items into the database using

await database.InsertAsync(dataItem);

// or a batch insert using 

await database.InsertAllAsync(dataItems)

// or an insert OR replace using

await database.InsertOrReplaceAsync(dataItem)

Updating rows

We saw that we can InsertOrReplace rows but this is based upon whether the object is unique. In other words the data object is first inserted and then a key returned, if another object matches this newly inserted one, then it’s deleted.

We can call UpdateAsync if we know a data object has already been saved to the database and we just want to update it, i.e.

await database.UpdateAsync(dataItem);

and thus if we’re tracking, within our data object whether it’s been saved and decide whether to update or insert using

if(dataItem.Id != 0)
{
   await database.UpdateAsync(dataItem);
}
else
{
   dataItem.Id = await database.InsertAsync(dataItem);
}

Querying the database

It wouldn’t be much of a database if we couldn’t run queries on it. We can use

var list = 
   await database.QueryAsync<DataItem>(
      "SELECT * FROM [DataItem] WHERE [Success] = 0"
   );

We can also use Linq like this

var dataItem = 
   database.Table<DataItem>()
      .Where(i => i.Name == "Samsung").ToListAsync();

Hence here we’ll get a list of all DataItems with the name “Samsung”.

Deleting data

We can use

await database.DeleteAsync(dataItem);

Deleting the database

As the database is stored as a file we can simply delete the file from the file system using

if (File.Exists(DatabaseLocation))
{
   File.Delete(DatabaseLocation);
}

More on our data objects

The only thing we’ve specified in any of the above code, for our data objects, is that they must have a default constructor on a concrete class, but as this SQLite NuGet package is acting like an ORM (as opposed to us creating our tables etc. in SQL), we’ll probably need some of the following properties added to our data object…

In the above we’ve showed that we can get a key back from an insert etc. but we can also add a key to the data objects themselves and have SQLite supply the keys. So for example we can add the following to our data item class

[PrimaryKey, AutoIncrement]
public int Id { get; set; }

Now the id is our primary key and is automatically supplied during an insert using an AutoIncrement algorithm.

We can also add indexed properties, for example

[Indexed]
public string Name { get; set; }

We can ignore properties by marking them with the IgnoreAttribute, i.e.

[Ignore]
public int AverageDb { get; set; }

Other attributes, include the following UniqueAttribute, MaxLengthAttribute , NotNullAttribute, StoreAsTextAttribute (for enums) and CollationAttribute (BINARY, NOCASE, RTRIM are supported with BINARY being the default) for comparisons.

Transforming config files using SlowCheetah

It’s not unusual for our applications to require different configuration files (whether App.config or other) which might reflect different environments or build configurations. Under such circumstances I’ve tended to stick to using (good old) Nant to switch tokens in my configuration files as and when required.

An alternative to Nant or Cake etc. is Microsoft’s SlowCheetah, which allows us to create transformations within our configuration files, whether XML or JSON based as part of the build process within Visual Studio. These files will be named after the build configuration that you build your project with, i.e. Debug, Release etc.

To try this out, we first need to install SlowCheetah. So from Tools | Extensions and Updates, search for SlowCheetah and download it – you’ll need to restart Visual Studio to get it to installed.

Once installed we can right mouse click on the App.config and should see the option Add Transform.

Note: When we first add a transform Visual Studio will ask you to install the SlowCheetah NuGet package, select Yes when prompted.

Once you’ve executed Add Transform against the App.config you’ll find child nodes in solution explorer for App.Debug.config and App.Release.config (and any other build configurations you have).

If you right mouse click on either of these new config files, the context menu should show the option to Preview Transform. As the name suggests, this allows us to see what the transform will look like instead of having to build our solution to view the App.config within the bin folder.

Transforming .config files

In our simple implementation/example, we’ve got three App.config files now. The original App.config (which is ultimately what we’ll see in the bin folder as the exe.config) and a version of this file for Debug and Release builds.

What we need to do is add some configuration into the App.config as normal, so for example add the following

<appSettings>
   <add key="environment" value="NONE" />
</appSettings>

We can now add configuration to the Debug and Release config files to override this value. To save on duplicated config let’s concentrate on the App.Debug.config, so when we build using the Debug configuration SlowCheetah will transform our App.config with instructions from the App.Debug.config. Here’s an update to the App.Debug.config file

<appSettings>
   <add key="environment" value="DEBUG" 
      xdt:Transform="Replace" 
      xdt:Locator="Match(key)" />
</appSettings>

Note: the syntax for XML transformations is taken from XDT and for JSON from JDT.

As you can probably work out for yourself, we’re telling the transformation engine to replace the value for the given key. Without these two attributes no transformation takes place. Just adding configuration to this file, i.e. if we added another key/value solely to the App.Debug.config, will simply be ignored unless we tell the transformer what to do. For example if we wanted the App.Debug.config build to insert/add a new app settings key/value we can tell the transformer to do this using

<add key="url" 
   value="http://somewhere.com" 
   xdt:Transform="Insert"/>

Transformation syntax for XDT can be found here Transform Attribute Syntax.

Transform attributes include

  • Replace
  • Insert
  • InsertBefore
  • InsertAfter
  • Remove
  • RemoveAll
  • RemoveAttributes
  • SetAttributes

Transforming .json files

We may be using JSON files for configuration or support files (for example when creating .NET core applications or in any other type of application). SlowCheetah allows transformations on JSON as well using JDT.

Let’s add a JSON file to our test application, mine’s named Config.json and includes the following

{
  "appSettings" : {
     "environment" : "None" 
  }
}

Now in solution explorer within Visual Studio, right mouse click on Config.json and select Add Tranform. Again we’ll concentrate solely on the Config.Debug.json file that’s created as part of this process. Add the following to this file

{
  "appSettings" : {
    "@jdt.replace" : {
      "environment" :  "Debug" 
    } 
  }
}

As I’m sure you can see, we’re aiming to replace the value of the environment key to Debug (as we did with the .config previously). Obviously to see this happen and output to the relevant bin folder, select the Config.json (parent node) and set its property Copy to Output Directory to Copy if newer, now select each of the child nodes and switch those back to Do not copy as Visual Studio will set the child nodes to the same build action as the parent and we do not want/need these environment configurations in our output folder.

JDT includes the following verbs

References

SlowCheetah
SlowCheetah on GitHub

Using Openfin InterApplicationBus

In a previous post (Remoting using WCF) I covered interprocess communications using remoting and named pipes. If you’re using Openfin there’s an InterApplicationBus which basically allows for the same interprocess communication/messaging functionality.

Let’s see how this works. Let us assume we’re using Openfin and we have one application which should send a message and a second application which will receive a message.

Let’s see how to write some code that responds to messages

We’ll start by creating a WPF/Winforms or other application that remains running until explicitly closed. We want the application to remain open and wait listening for messages.

Add the OpenfinDesktop NuGet package (Install-Package OpenfinDesktop) to your application. Now within the class of your main window/form place the following

using Openfin.Desktop;
// may need this 
// using Window = System.Windows.Window;

we’ll make it simple by writing all our code within the MainWindow.xaml.cs constructor (for our WPF app.). So add the following to the constructor after InitializeComponent();

var runtime = Runtime.GetRuntimeInstance(new RuntimeOptions {Version = "9.61.38.40" });
runtime.Connect(() =>
{
   runtime.InterApplicationBus.subscribe("my-topic", (uuid, topic, message) =>
   {
      if (message != null)
      {
         Debug.WriteLine(message.ToString());
      }
   });
});

The Version used is important as it relates to code that is either already available on your machine or it should download, see OpenFin Versions. In my case this downloaded the latest code and hence when I ran the application I got an Openfin popup showing the download progress. The runtime etc. will be stored on your local storage (by default) in %localappdata%\OpenFin.

Also be aware – as you’d probably assume, the InterApplicationBus is running on it’s own thread, hence when you are handling messages it’s your responsibility to handle any marshalling, for example onto the GUI/Main thread.

We can also handle messages in a more event style for example, replace the code within the Connect method (above) with the following (this code also rids us of the lowe cased subscribe method name which is not in keeping with the C# naming conventions :-), beyond that I’m not wholly sure at this time if there’s any other difference in this code).

InterApplicationBus.Subscription<string>(runtime, "my-topic").MessageReceived += (sender, msg) =>
{
   if (msg != null)
   {
      Debug.WriteLine(msg.Message);
   }
};

Let’s see how to write some code that publishes messages

Create an second application, again make it a WPF/WinForms application so we don’t have to write code to keep the application open whilst we connect and send messages as these are asynchronous in nature.

Again, add the OpenfinDesktop NuGet package and using statements but within the constructor we’ll write the following code

var runtime = Runtime.GetRuntimeInstance(new RuntimeOptions { Version = "9.61.38.40" });
runtime.Connect(() =>
{
   runtime.InterApplicationBus.Publish("my-topic", "Hello World");
});

As you’d assume, this publishes a message to the bus with the topic my-topic, which our first application listens for. In this case a simple string (good old Hello World) is being sent, but we could send something a little more complex like a JSON message or the likes.

Now simply run the first application and once connected run the second and you should see the Hello World text in your Debug window.

Added a clicking command to Labels (and more)

I wanted to have a clickable label in my Xamarin Forms application. A button was just a little too large for my requirements, but a standard Label does not have a click command. However, it’s easy to create such an command handler, this also works for other UI elements.

In your XAML just use the GestureRecognizers collection and add a TapGestureRecongizer, like this

<Label Text="More...">
   <Label.GestureRecognizers>
      <TapGestureRecognizer Command="{Binding MoreCommand}" />
   </Label.GestureRecognizers>
</Label>

Simple.

Preparing a Xamarin Forms app. for deployment to Android

So I’ve created a cross platform application using Xamarin Forms and Visual Studio 2017 and now I want to get it deployed on some devices – in this post I’m concentrating on Android devices. So let’s look at what we need to do to get this application deployed…

I’m going to assume that the application version, icon, permission requirements and all those “standard” things have been implemented/setup and concentrate on getting the application ready for deployment to our device(s).

Release build

Obviously, like any other application, we’ll want to minimize the size of our application and remove any debug centric code that might be wrapped in #if DEBUG etc.

Select the Android project (ensure the build is set to Release), right mouse click and select properties and in Android Options ensure Use Shared Runtime and Use Fast Deployment (debug model only) are unchecked.

Archive and prepare for distribution

The process of bundling up an Android application is known as generating an archive. Right mouse click on the Android project in your solution and select Archive. Visual Studio will now go about archiving your application bundle.

Now click the Distribute button where you’ll be able to target the application’s distribution channel. I have two options Ad Hoc and Google Play. I’m going to stick to Ad Hoc which allows me to use email, a web site etc. to distribute my application via side loading.

We need to sign our application, so if you’ve not yet got a keystore/identity set-up you can just click the + button.

Note: Even if you’re just creating a new keystore for each application you’ll need to make sure you remember your password as this will be required to complete the signing process.

Fill in the options and then press Save As and you’ll be prompted for the keystore password.

We have now created an APK which can be installed onto you Android device. In my case I’m using Microsoft’s AppCenter to allow specific users to access the application for testing.

References

Preparing an Application for Release
Signing the Android Application Package

The Bluetooth device address (BD_ADDR)

As you’d expect, a Bluetooth device has a MAC address assigned to it, however the BD_ADDR (Bluetooth Device Address), at least in my experiments, doesn’t necessarily map to the MAC address you see in, for example, the Window Device Manager properties page for the Bluetooth device. I will update this document if I find my findings have changed.

The information listed below is taken from a few sources, some of which I’ve referenced at the end of the post, my knowledge on the subject is taken from those and my own experiments.

The BD_ADDR is a unique identifier using 48-bit address space. For example

11:22:33:44:55:66

The address denotes several pieces of information, as follows

  • NAP

    The Non-significant Address Part is denoted by the first 16 bits, using our example this would be the 11:22 value. The NAP is used in Frequency Hopping Synchronization frames/packets.

  • UAP

    The Upper Address Part is denoted by the next 8 bits, using our example this would be the 33 value. The UAP is used for seeding various Bluetooth specification algorithms.

  • OUI

    The Organizationally Unique Identifier (the first 24 bits) is actually the combination of the NAP and UAP, hence in our example the NAP + UAP gives us the OU which is 11:22:33

    With the knowledge on the make up of the BD_ADDR, we can see that by taking the OUI value, we should be able to fairly easily lookup the manufacturer of a device. For example using the OUI List.

  • LAP

    The Lower Address Part is made up of the final 24-bits, hence in our example this would be the 44:55:66 and is allocated by the device vendor. The LAP identifies a Bluetooth device and is transmitted with each frame/packet as part of the packet header.

References

Bluetooth: Defining NAP + UAP + LAPBluetooth MAC Address Changer for Windows
OUI List
BD_ADDR – how do you get one?
Discovering the Bluetooth UAP
Does each Bluetooth device has its own unique MAC Address? How can we access it in an app?

Bluetooth Proximity

This post is going to cover aspects of determining proximity with Bluetooth devices and hence covers a couple of key pieces of data.

RSSI

RSSI stands for Received Signal Strength Indication as is a measurement of radio signal strength, measure in dBm (decibel-milliwatts). The higher the RSSI value, the stronger the signal.

Signal strength can be affected by many things. Along with the obvious environment affects, such as walls and interference the different chipsets used can give wide variations and hence cannot be guaranteed to indicate whether one Bluetooth device is actually closer than another.

To use RSSI effectively to try to approximate proximity, at least in terms of whether we’re getting closer to the device or moving further away, we should track multiple samples of RSSI over time. If the signal is getting weaker then we might suggest the device is getting further away (ofcourse taking into account any environment and others forms of interference).

RSSI can be calculated (although it will likely be available from your preferred Bluetooth LE library) using the following formula (although this includes distance as a parameter which is, after all what we’re after with proximity so unlikely to have).

RSSI = -10n log(d) + A

where 

d is distance
A is txPower
and
n is a signal propagation constant 
(for example it might be set to 2 in free space, but 
vary in a walled area).

In situations where we have RSSI only (i.e. no TX Power) we can approximate proximity using the signal strength by checking the RSSI against the following range of values

RSSI of -50dBm to 0dBm – very close
RSSI of -90dBm to -50dBm – medium distance
RSSI of less than -90dBm – far away

However, as stated, signals may be affected by different forms of interference and also by the chipsets and power used for the radio, so can only be taken as “guesses” to proximity.

TX Power

If you see the an option on your preferred Bluetooth LE library called txPower which stands for transmitted power (also known as measured power).

Note: This doesn’t seem to be available/used by all Bluetooth devices. In which case it’ll be defaulted to zero.

TX power is used within the previous formula (along with the RSSI value) to help determine distance or proximity estimates. It allows us to take into consideration the actual power of the Bluetooth device as it’s a calibrated (read-only constant) which indicates the expected RSSI at a distance of 1 metre from the Bluetooth device. So with RSSI and TX Power we can rearrange the previous equation to calculate distance, here’s a C# implementation of that

public static double GetProximity(int rssi, int txPower)
{
   const int signalPropagationConstant = 2; 
   return Math.Pow(10d, ((double) txPower - rssi) / (10 * signalPropagationConstant));
}

Obviously when calculating proximity with a 0 txPower the distance will no longer be valid and hence you’ll have to simply have to use sample RSSI to get a basic idea of signal strength).

References
Bluetooth LE Advertisements – Gauging Distance
How to Calculate Distance from the RSSI value of the BLE Beacon
Estimating beacon proximity/distance based on RSSI – Bluetooth LE
Proximity And RSSI

Taking a screen shot on your phone/tablet

Whilst developing application for phones and/or tablets we might like to take some screenshots of a “live” application, as opposed to one within an emulator etc.

To take a screenshot we simply do the following.

  • Android – hold the power button and volume down button for a second.
  • iOS – press the home button and the power button
  • Windows 10 mobile – hold the power button and volume up button

Android application’s default theme colours

Note: I’m developing an application with Xamarin Forms, so, although I assume this is the same across Android development, I have not verified this.

We define a style for an Android application (see Resources/values/styles.xml). This consists of the theme being used as well as some values for customisation. These include the status bar (the bar at the top of the screen which contains notification icons such as wi-fi, Bluetooth icons etc.) as well as the caption/title colour, navigation bar colour etc.

The default colours for this and/or your applications toolbar etc. are customisable via this styles.xml file. Here’s some of the values available

  • colorPrimaryDark – this is the status bar colour, by default it’s set to #1976D2
  • colorPrimary – this is the action bar/toolbar colour, by default it’s set to #2196F3
  • colorAccent – this is the tint colour (used on controls/widgets as a highlight), by default it’s set to #FF4081

References

Material Design for Android
Styles and Themes