Xamarin

Integrate the Colocator Xamarin NuGet into your Xamarin app

Adding the dependency

  1. In your Xamarin Forms project, using the source nuget.orh, add the Colocator NuGet package (author - Crowd Connected)

  2. In your Android project, in the MainActivity.cs file, add the following in the “OnCreate(Bundle savedInstanceState)” method after loading the application

CrossCurrentActivity.Current.Init(this, savedInstanceState);

Integration Sample

Getting Permission

iOS Additional Steps

Navigate to your Xamarin.iOS project and open Info.plist file

  1. In the Application tab, enable Background Modes with the following modes:
  • Location updates
  • Background fetch
  • Remote notifications
  • Bluetooth Peripheral
  • Bluetooth Central
  1. In the Source tab, add the following properties and relevant descriptions for them:
  • Privacy - Location Always and When in Use Usage Description
  • Privacy - Location Always Usage Description
  • Privacy - Location When in Use Usage Description
  • Privacy - Bluetooth Peripheral Usage Description
  1. If you will use Colocator for Indoor Services add the following properties:
  • Privacy - Motion Usage Description
  • NSBluetoothAlwaysUsageDescription

For more details about these permissions in the iOS section

Android Additional Steps

Navigate to your Xamarin.Android project and open AndroidManifest.xml file from the Properties folder

In the Application tab, at Required Permissions section, enable:

  • AccessCoarseLocation
  • AccessFineLocation

Location Permission

Request location permission for both Android and iOS using Plugin.Permissions NuGet package or other preferred method.

Example using Plugin.Permissions

iOS
  1. Go to your iOS project and add Plugin.Permissions NuGet

  2. In your Main.cs file (or other preferred file) add the following method

using Plugin.Permissions;
using Plugin.Permissions.Abstractions;

...

static private async void AskForLocationPermission()
{
    PermissionStatus status = await CrossPermissions.Current.RequestPermissionAsync<LocationAlwaysPermission>();
}
  1. In the Main function, before calling “UIApplication.Main(args, null, “AppDelegate”);” request location permission as follows
AskForLocationPermission();
Android
  1. Go to your Android project and add Plugin.Permissions NuGet

  2. In your MainActivity.cs file (or other preferred file) add the following inside your “OnCreate(Bundle savedInstanceState)” method

ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation }, 0);
  1. In your “OnRequestPermissionsResul()” method add the following
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);

Bluetooth and Motion Permissions (only iOS) - Used for Indoor Location Service

You can use Colocator features for triggering the permission OS pop-ups whenever you want in your Forms application.

Import the plugin

using Colocator;

Create an instance of the plugin

 IColocator colo = ColocatorMain.Instance;

Trigger permission pop-up

colo.TriggerBluetoothPermissionPopUp();
colo.TriggerMotionPermissionPopUp();

Enabling Location Gathering

Start the library

Start the library in your main project

Import the plugin

using Colocator;

Create an instance of the plugin

 IColocator colo = ColocatorMain.Instance;

Start the library and set the delegate

colo.StartWithAppKey("YOUR_APP_KEY");

In the iOS project, the library should be started in AppDelegate.cs as follows:


public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    ...

    Colocator.ColocatorMain.Instance.StartWithAppKey("YOUR_APP_KEY");

    ...
}

Background Refresh - only iOS

We use background refresh to periodically check whether we should enable location tracking.

Enable Background Refresh by adding the following in your AppDelegate.cs file:

[Export("application:performFetchWithCompletionHandler:")]
public override void PerformFetch(UIApplication application, System.Action<UIBackgroundFetchResult> completionHandler)
{
    Colocator.ColocatorMain.Instance.UpdateLibraryBasedOnClientStatusWithClientKey("CC_APP_KEY", false, completion: (result) =>
    {
        if (result)
        {
            completionHandler(UIBackgroundFetchResult.NewData);
        }
        else
        {
            completionHandler(UIBackgroundFetchResult.NoData);
        }
    });
}

Silent Push Notifications - only iOS

We use Silent Push Notifications to enable location tracking at a given time.

Please enable Silent Push Notifications by doing the following in your AppDelegate.cs:

  1. Ensure the app has notification permission

  2. Registering for remote notifications

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    ...

    var authOptions = UserNotifications.UNAuthorizationOptions.Alert | UserNotifications.UNAuthorizationOptions.Badge | UserNotifications.UNAuthorizationOptions.Sound;
    UserNotifications.UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) => { });
    UIApplication.SharedApplication.RegisterForRemoteNotifications();

    ...
}
  1. Send the APNS Token as an alias
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    byte[] bytes = deviceToken.ToArray<byte>();
    string[] hexArray = bytes.Select(b => b.ToString("x2")).ToArray();
    var token = string.Join(string.Empty, hexArray);

    Colocator.ColocatorMain.Instance.AddAliasWithKey("apns_user_id", token);
}
  1. Call the library when one is received
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
    NSString source = userInfo.ObjectForKey(new NSString("source")) as NSString;

    if (source == "colocator")
    {
        Colocator.ColocatorMain.Instance.ReceivedSilentNotificationWithUserInfo(userInfo, "CC_APP_KEY", completion: (result) => {
            if (result)
            {
                completionHandler(UIBackgroundFetchResult.NewData);
            }
            else
            {
                completionHandler(UIBackgroundFetchResult.NoData);
            }
        });
    } else {

        ...

    }
}

Disabling Location Gathering

If required you can stop the library

ColocatorMain.Instance.Stop();

Sending an Alias

Aliases are key-value pairs. They are primarily used to send alternative IDs for a device, for example a unique Push Notification identifier. Go to the Push Notification Integrations page for more details

ColocatorMain.Instance.AddAliasWithKey("YOUR_KEY", "YOUR_VALUE");

Foreground Service (only Android)

Enable the foreground service ny doing the following

ColocatorMain.Instance.ActivateForegroundService("YOUR_TITLE", foregroundServiceIconID, "CHANNEL");

Indoor Location Service

For indoor location and positioning, a few more steps need to be implemented

Location Callbacks - Only for Indoor Navigation Purposes

The latest location can be sent back to the device as updates. This is primarily used for displaying the location of the device on a map.

The location update callbacks contain a ColocatorLocationResponse object and they are deceived through a ColocatorDelegate

  1. Set the delegate
ColocatorMain.Instance.Delegate = new MyClass();
  1. Configure the delegate
public class MyClass : ColocatorDelegate
{
    ...
    
    public void DidReceiveLocation(ColocatorLocationResponse location)
    {
        // Use the location as you wish
        // location.Latitude
        // location.Longitude
        // location.Error
        // location.Timestamp
        // location.HeaderOffset
        // location.Floor
    }
}

Request one location:

ColocatorMain.Instance.RequestLocation();

Request a stream of location updates:

ColocatorMain.Instance.RegisterLocationListener();

Stopping Location Updates

Please make sure you unregister from location callbacks when the user is not using the indoor map screen or navigation.

This is important for battery and performance optimization.

Stop the stream of updates:

ColocatorMain.Instance.UnregisterLocationListener();