5

我正在尝试使用 Xamarin Forms(用于 Android 应用程序)从 Samsung Health 获取步数。

我尝试使用SamsungHealthForXamarin从 Samsung Health SDK重新创建SimpleHealth示例项目。

Java 示例项目在我们无法在 C# 中使用的相同范围内使用匿名内联类。因此,您似乎必须构建一个 IConnectionListener 接口。

有没有人有使用 Xamarin Forms (C#) 从 Samsung Health 获取“步骤数据”的经验?我很想看到一个超级简单的例子,在 C# 中获取今天的步数。好像不应该这么难。

4

1 回答 1

3

如果我对您的理解正确,您的问题主要是如何让连接侦听器知道它的数据存储到底是什么。从 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。在这里,我们将保留对 our 的引用HealthDataStore,这取决于我们的侦听器。

我们的服务将如下所示:

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

同样,重要的一行是方法的第三行——我们将 store 分配给侦听器的属性,以便我们可以在那里获得它的引用。

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
}

步骤观察者

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();
    }
}

之后,您可以按照您希望的任何方式通知 UI - 使用 Xamarin 的MessagingCenter、使用事件、使用其他类型的观察者逻辑 - 具体取决于您的项目架构。

关于该主题的一些旁注:

  1. 请注意,该项目已移至Bitbucket,如README.md
  2. 与往常一样,您应该考虑一些限制。三星健康文档 - 限制

Samsung Health Android SDK 可在搭载 Android 6.0 Marshmallow(API 级别 23)或更高版本的设备上运行。

它需要安装三星健康。最新的 SDK 适用于 Samsung Health 6.2 或更高版本。在此处查看 SDK 和 Samsung Health 的兼容版本。

使用 Samsung Health Android SDK 的应用程序的 targetSdkVersion 应为 26 或更高版本。

三星健康适用于所有三星智能手机以及配备 Marshmallow 或更高版本的非三星 Android 智能手机。

于 2020-05-24T16:46:16.867 回答