February 10, 2014

Use iBeacons in Android with C#

By

Since Apple introduced iBeacons in iOS 7, the interest in them has skyrocketed. For example, Apple is using them in their retail stores, the NFL installed them at the Super Bowl and Major League Baseball will be using them during the upcoming season. We have discussed previously how to implement iBeacons in your Xamarin.iOS apps with a ‘Find the Monkey’ game and how to leverage them in a retail store environment, but today we will be discussing how to bring the same iBeacon support to your Xamarin.Android apps.

xplat_findmonkey

iBeacons allow devices to discover their proximity to “beacons”, which can be dedicated third-party hardware or iOS devices. Previously, discovering iBeacons was limited to iOS 7. However, thanks to the work of Radius Networks and the Xamarin.Android iBeacon Service Component created by Chris Riesgo, you can now discover iBeacons from Android devices that support Bluetooth LE.

Let’s look at how to use the Android iBeacon Service component to discover an iBeacon, which we’ll run inside an iOS application using Core Bluetooth to advertise the iBeacon as shown below:

var uuid = new NSUuid ("A1F30FF0-0A9F-4DE0-90DA-95F88164942E");
var beaconId = "iOSBeacon";
var beaconRegion = new CLBeaconRegion (uuid, beaconId) {
  NotifyEntryStateOnDisplay = true,
  NotifyOnEntry = true,
  NotifyOnExit = true
};
var peripheralData = beaconRegion.GetPeripheralData (new NSNumber (-59));
peripheralDelegate = new BTPeripheralDelegate ();
peripheralMgr = new CBPeripheralManager (peripheralDelegate, DispatchQueue.DefaultGlobalQueue);
peripheralMgr.StartAdvertising (peripheralData);

Once the iBeacon is advertising, other iOS 7 apps and Android apps can discover it.

Chris’s component, like all Xamarin components, includes a sample project. In this case, the sample project is an Android application that works with the iOS sample from the “Find the Monkey” post. This code makes for a great starting point to build your own application that uses iBeacons. Included in the example is the source for a couple classes called MonitorNotifier and RangeNotifier, which we can use in our application to handle beacon region monitoring and ranging respectively.

monitorNotifier = new MonitorNotifier ();
monitoringRegion = new Region (BEACON_ID, UUID, null, null);
rangeNotifier = new RangeNotifier ();
rangingRegion = new Region (BEACON_ID, UUID, null, null);

With these notifier classes in place, we can create a beacon manager, which will coordinate all the beacon discovery and ranging updates.

beaconMgr = IBeaconManager.GetInstanceForApplication (this);

The beacon manager is handed the instances of the monitor and range notifiers, after which it can start monitoring and ranging.

public void OnIBeaconServiceConnect ()
{
  beaconMgr.SetMonitorNotifier (monitorNotifier);
  beaconMgr.SetRangeNotifier (rangeNotifier);
  beaconMgr.StartMonitoringBeaconsInRegion (monitoringRegion);
  beaconMgr.StartRangingBeaconsInRegion (rangingRegion);
}

To implement code to handle region monitoring and ranging, we simply bind the Activity to the beacon manager and wire up the appropriate event handlers:

beaconMgr.Bind (this);
monitorNotifier.EnterRegionComplete += EnteredRegion;
monitorNotifier.ExitRegionComplete += ExitedRegion;
rangeNotifier.DidRangeBeaconsInRegionComplete += RangingBeaconsInRegion;

In this app we’ll present messages to the user and show an image with a QR code when the Android device discovers the beacon in range:

void EnteredRegion (object sender, MonitorEventArgs e)
{
  ShowMessage ("Welcome back!");
}
void ExitedRegion (object sender, MonitorEventArgs e)
{
  ShowMessage ("Thanks for shopping here!");
}
void RangingBeaconsInRegion (object sender, RangeEventArgs e)
{
  if (e.Beacons.Count > 0) {
    var beacon = e.Beacons.FirstOrDefault ();
    switch ((ProximityType)beacon.Proximity) {
      case ProximityType.Immediate:
      case ProximityType.Near:
      case ProximityType.Far:
        ShowMessage ("Here's a coupon!", true);
        break;
      case ProximityType.Unknown:
        ShowMessage ("Beacon proximity unknown");
        break;
      }
    }
}

When we get near the beacon, we see the message change and the image with the QR code is displayed.

android_beacon

As you can see looking at this and our previous posts the code across scenarios is very similar, at least for the iBeacon part. Thanks to this component you can do it all in C# on both iOS and Android.

The source from this post is available in my GitHub repo.

Discuss this post in the Xamarin forums.

TwitterFacebookGoogle+LinkedInEmail