Как получить количество шагов Samsung Health в формах Xamarin

Я пытаюсь получить количество шагов от Samsung Health с помощью Xamarin Forms (для Android-приложения).

Я попытался использовать https://github.com/etheriau/SamsungHealthForXamarin, чтобы воссоздать образец проекта SimpleHealth из SDK Samsung Health.

В примере проекта Java используются анонимные встроенные классы в той же области, что мы не можем сделать в C#. Похоже, вместо этого вам нужно создать интерфейс IConnectionListener.

Есть ли у кого-нибудь опыт получения "данных о шагах" из Samsung Health с помощью Xamarin Forms (C#)? Мне бы хотелось увидеть супер простой пример получения сегодняшнего количества шагов на C#. Не похоже, что это должно быть так сложно.

1 ответ

Решение

Если я вас правильно понял, ваша проблема в основном связана с тем, как заставить слушателя соединения знать, что именно представляет собой его хранилище данных. Исходя из того, что все слушатели на Java - это просто класс на C#, реализующий необходимый интерфейс, мы можем создать наш слушатель следующим образом:

public class ConnectionListener : HealthDataStore.IConnectionListener
{
    internal HealthDataStore Store { get; set; }

    public void OnConnected()
    {
        var stepCountReporter = new StepCountReporter(Store);
        // NOTE: Check for permissions here
        stepCountReporter.Start();
    }
    public void OnConnectionFailed(HealthConnectionErrorResult p0)
    {
        // Health data service is not available.
    }
    public void OnDisconnected()
    {
        Store.DisconnectService();
    }
}

Важная линия - третья - внутреннее свойство. Store. Здесь мы сохраним ссылку на нашHealthDataStore, что будет зависеть от нашего слушателя.

Наш сервис будет выглядеть так:

private void InitStepService()
{
    var connectionListener = new ConnectionListener();
    store = new HealthDataStore(this, connectionListener);
    connectionListener.Store = store; // This is the important line
    store.ConnectService();
}

Опять же, важная строка - это третья строка из метода - мы назначаем хранилище свойству нашего слушателя, чтобы мы могли иметь его ссылку там.

Тот же подход применим и к классу StepCountReporter:

public class StepCountReporter
{
    private readonly HealthDataStore store;
    private const long OneDayInMillis = 24 * 60 * 60 * 1000L;

    public StepCountReporter(HealthDataStore store)
    {
        this.store = store;
    }

    public void Start()
    {
        HealthDataObserver.AddObserver(store, HealthConstants.StepCount.HealthDataType,
            new StepObserver(ReadTodayStepCount));
        ReadTodayStepCount();
    }

    private void ReadTodayStepCount()
    {
        var resolver = new HealthDataResolver(store, null);

        // Set time range from start time of today to the current time
        var startTime = DateTime.Now.Date.Ticks;
        var endTime = startTime + OneDayInMillis;

        ReadRequestBuilder requestBuilder = new ReadRequestBuilder()
            .SetDataType(HealthConstants.StepCount.HealthDataType)
            .SetProperties(new[] { HealthConstants.StepCount.Count })
            .SetLocalTimeRange(HealthConstants.StepCount.StartTime, HealthConstants.StepCount.TimeOffset,
                startTime, endTime);

        IReadRequest request = requestBuilder.Build();

        try
        {
            resolver.Read(request).SetResultListener(new StepResultHolderResultListener());
        }
        catch (Exception)
        {
            // Getting step count fails.
        }
    }
}

Здесь вам понадобятся 2 дополнительных класса - StepResultHolderResultListener & StepObserver

StepResultHolderResultListener

public class StepResultHolderResultListener : IHealthResultHolderResultListener
{
    public void OnResult(Java.Lang.Object resultObject)
    {
        if (resultObject is ReadResult result)
        {
            int count = 0;

            try
            {
                var iterator = result.Iterator();
                while (iterator.HasNext)
                {
                    var data = (HealthData) iterator.Next();
                    count += data.GetInt(HealthConstants.StepCount.Count);
                }
            }
            finally
            {
                result.Close();
            }

            // Update your UI here with the count variable
        }
    }

    // Rest of the methods from the interface
}

StepObserver

public class StepObserver : HealthDataObserver
{
    private readonly Action readTodayStepCountAction;

    private StepObserver(Handler p0)
        : base(p0)
    {
    }

    public StepObserver(Action readTodayStepCountAction)
        : this((Handler) null)
    {
        this.readTodayStepCountAction = readTodayStepCountAction;
    }

    public override void OnChange(string dataTypeName)
    {
        readTodayStepCountAction();
    }
}

После этого вы можете уведомлять пользовательский интерфейс любым способом - используя Xamarin MessagingCenter, используя события, используя какую-либо другую логику наблюдателя - в зависимости от архитектуры вашего проекта.

Несколько примечаний по теме:

  1. Обратите внимание, что проект был перемещен в Bitbucket, как сказано вREADME.md
  2. Как всегда, есть некоторые ограничения, которые следует учитывать. Документы Samsung Health - Ограничения

SDK Samsung Health для Android работает на устройствах с Android 6.0 Marshmallow (уровень API 23) или выше.

Требуется установка Samsung Health. Последний SDK работает с Samsung Health 6.2 или выше. Смотрите здесь SDK и совместимые версии Samsung Health.

TargetSdkVersion приложения, использующего SDK Samsung Health для Android, должен быть 26 или выше.

Приложение Samsung Health доступно на всех смартфонах Samsung, а также на Android-смартфонах сторонних производителей с Marshmallow или выше.

Другие вопросы по тегам