polarofficial / polar-ble-sdk

Repository includes SDK and code examples. More info https://polar.com/en/developers
Other
471 stars 154 forks source link

SDK Library Bindings for Xamarin Android and iOS #56

Closed tessarolli closed 2 years ago

tessarolli commented 4 years ago

Hi Polar Developers, Have any of you been able to create necessary bindings for the native libs on Android and iOS projects in a Xamarin / Xamarin Forms solution???

I've been trying to integrate Polar Sensors Data into my xamarin forms application and i wonder if someone already done this before?

tessarolli commented 4 years ago

OK, i've done it.

For future reader reference, here's how you do it: Add a new Android Binding project to solution. Add the polar-ble-sdk.aar to JARS folder, and set build action to LibraryProjectZip Add a new class file named AttributeOperation.cs to additions folder and set this to its content: using Java.Lang; namespace Com.Androidcommunications.Polar.Enpoints.Ble.Common.Attribute { public partial class AttributeOperation : Object, IComparable { int IComparable.CompareTo(Object obj) { return CompareTo((AttributeOperation)obj); } } }

Add two nugget references: a) Naxam.RxAndroid.Droid - b) Naxam.RxJava2.Droid

Build the project, and reference this project on your Xamarin.Android project.

And thats it for mapping the native android library to you xamarin android project.

Now for some code samples on how to interface with a polar sensor, this is what i've used: (Please, have in mind that this my first approach on this subject, and this code is only in early stage of development, thus its only saving a string representation of the data received on a List of strings)

`using System; using System.Collections.Generic; using System.Linq; using System.Text;

using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using Polar.Com.Sdk.Api; using Polar.Com.Sdk.Api.Model;

namespace TessarolliSolutions.Droid.Services.PolarSDK { public class PolarSDK { PolarBleApi api; List Log;

    public PolarSDK()
    {
        Log = new List<string>();
        // Verificar Quais Features vai utilizar ao instanciar a api
        api = PolarBleApiDefaultImpl.DefaultImplementation(MainActivity.Instance, PolarBleApi.FeatureBatteryInfo | PolarBleApi.FeatureDeviceInfo | PolarBleApi.FeatureHr);

        api.SetApiCallback(new PolarBleApiCallbackImpl(Log));

        var autoconnect = api.AutoConnectToDevice(-50, "180D", null).Subscribe(new RxAction(() => { Log.Add("Concluido"); }), new RxConsumer<Java.Lang.Throwable>((e) => { Log.Add($"Error: {e}"); }));

        //var scan = api.SearchForDevice(new Consumer(Log));

    }

    public class RxAction : Java.Lang.Object, IO.Reactivex.Functions.IAction
    {
        private readonly Action Callback;
        public RxAction(Action callback)
        {
            Callback = callback;
        }

        public void Run()
        {
            Callback?.Invoke();
        }
    }

    public class RxConsumer<T> : Java.Lang.Object, IO.Reactivex.Functions.IConsumer
    {
        private readonly Action<T> Callback;

        public RxConsumer(Action<T> action)
        {
            Callback = action;
        }

        public void Accept(Java.Lang.Object p0)
        {
            if (p0 is T param)
            {
                Callback?.Invoke(param);
            }
        }

    }
}

public class PolarBleApiCallbackImpl : PolarBleApiCallback
{
    #region construtor

    private List<string> Log;
    public PolarBleApiCallbackImpl(List<string> log = null)
    {
        Log = log ?? new List<string>();
    }
    #endregion

    #region Device Discovery / Connection
    public override void DeviceConnected(PolarDeviceInfo polarDeviceInfo)
    {
        base.DeviceConnected(polarDeviceInfo);

        Log.Add($"Device Connected: {polarDeviceInfo.DeviceId}");
    }

    public override void DeviceConnecting(PolarDeviceInfo polarDeviceInfo)
    {
        base.DeviceConnecting(polarDeviceInfo);
        Log.Add($"Device Connecting: {polarDeviceInfo.DeviceId}");
    }

    public override void DeviceDisconnected(PolarDeviceInfo polarDeviceInfo)
    {
        base.DeviceDisconnected(polarDeviceInfo);
        Log.Add($"Device Disconnected: {polarDeviceInfo.DeviceId}");
    }

    #endregion

    #region Data Received

    public override void DisInformationReceived(string identifier, Java.Util.UUID uuid, string value)
    {
        base.DisInformationReceived(identifier, uuid, value);
        Log.Add($"DisInformationReceived: ID: {identifier}, UUID: {uuid}, Value: {value}");
    }

    public override void HrNotificationReceived(string identifier, PolarHrData data)
    {
        base.HrNotificationReceived(identifier, data);
        Log.Add($"HrNotificationReceived: ID: {identifier}, HR: {data.Hr}, RRms: {(data.RrsMs.Count == 1 ? data.RrsMs[0] : "" )}, RRs: {(data.Rrs.Count == 1 ? data.Rrs[0] : "")}");
    }

    public override void BlePowerStateChanged(bool powered)
    {
        base.BlePowerStateChanged(powered);
        Log.Add($"BlePowerStateChanged: {powered}");
    }

    public override void BatteryLevelReceived(string identifier, int level)
    {
        base.BatteryLevelReceived(identifier, level);
        Log.Add($"BatteryLevelReceived: {level}");
    }

    #endregion

    #region Features

    public override void EcgFeatureReady(string identifier)
    {
        base.EcgFeatureReady(identifier);
        Log.Add($"Ecg Feature Ready: {identifier}");
    }

    public override void AccelerometerFeatureReady(string identifier)
    {
        base.AccelerometerFeatureReady(identifier);
        Log.Add($"Accelerometer Feature Ready: {identifier}");
    }

    public override void BiozFeatureReady(string identifier)
    {
        base.BiozFeatureReady(identifier);
        Log.Add($"Bioz Feature Ready: {identifier}");
    }

    public override void HrFeatureReady(string identifier)
    {
        base.HrFeatureReady(identifier);
        Log.Add($"HR Feature Ready: {identifier}");
    }

    public override void PolarFtpFeatureReady(string identifier)
    {
        base.PolarFtpFeatureReady(identifier);
        Log.Add($"FTP Feature Ready: {identifier}");
    }

    public override void PpgFeatureReady(string identifier)
    {
        base.PpgFeatureReady(identifier);
        Log.Add($"PPG Feature Ready: {identifier}");
    }

    public override void PpiFeatureReady(string identifier)
    {
        base.PpiFeatureReady(identifier);
        Log.Add($"PPI Feature Ready: {identifier}");
    }

    #endregion

    #region Dispose

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        Log = null;
    }

    #endregion

}

}`

I have not tampered with the IOS mapping yet.

erkki-silvola commented 4 years ago

Hi,

Nice job.

tessarolli commented 4 years ago

Thanks, there's still a long way to go, but this should be a great starting point for future developers out there.

RicardoMDI commented 4 years ago

Thanks for the contribution. Can you share your example code? I'm trying to do the same thins but it seems not to work. (I'm Brazilian too, if that matters :) )

RicardoMDI commented 4 years ago

Add a new class file named AttributeOperation.cs to additions folder and set this to its content: using Java.Lang; namespace Com.Androidcommunications.Polar.Enpoints.Ble.Common.Attribute { public partial class AttributeOperation : Object, IComparable { int IComparable.CompareTo(Object obj) { return CompareTo((AttributeOperation)obj); } } }

I'm having trouble here, it says "The name 'CompareTo' does not exist in the actual context". What am I doing wrong?

SuperCorks commented 3 years ago

Hi @tessarolli, @RicardoMDI , thank you for this thread! It has helped us a lot. Have you had any issues with the setLocalTime() method? Or anything related to this question?

Any help would be appreciated!

tessarolli commented 3 years ago

Hi @SuperCorks , i'm glad it helped!

To be honest, i've never had the chance to finish the project I was working on this, due to a change of priorities.

Maybe I'll revisit it later.

When I was testing it, i've not had any problems with setLocalTime()...

tessarolli commented 3 years ago

@RicardoMDI sorry about the long time.. maybe it was missing some using directives.. i dont remember it anymore.. sorry again..

SuperCorks commented 3 years ago

Thank you for the feedback, we're going to open-source the Android, iOS and portable project as soon as we have a working prototype (which we already have for Android except for the setLocalTime() method). Will keep you posted.

SuperCorks commented 3 years ago

Solved my issue. https://github.com/polarofficial/polar-ble-sdk/issues/199#issuecomment-925883492