扑朔迷离的健康许可

发布于 2025-01-24 12:19:59 字数 3453 浏览 3 评论 0 原文

我使用 health 在我的应用程序中包装在我的应用程序和Google Fit/Apple Health之间同步数据。到目前为止,我只有Testet Apple Health,如果我授予所有必要的权限,它的效果非常好。但是我发现了一件奇怪的事情,我不知道如何修复它。到目前为止,我仅实施并测试了与Apple Health的集成。

因此,我检查该应用程序是否有权读取或编写某种数据类型,然后阅读或将其写入Apple Health。如果授予权限并成功地读 /写操作,我想向用户介绍它。如果未授予许可,我也想向用户介绍它,因此他知道出了什么问题。在 HealthFactory 包的类中,我调用了 requestauthorization 方法,以检查用户是否已许可。我期望的行为是,如果未授予权限,则该方法的返回值是 false 如果未授予权限。但是,它始终是 true 。另外,方法 gethealthdatafromtypes writeHealthData 并未真正指示是否授予许可。

我实施了一些展示的方法:

class TestScreen extends StatelessWidget {
  TestScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ElevatedButton(
              child: Text("Health Permission"),
              onPressed: () async {
                final HealthFactory _health = HealthFactory();
                await Permission.activityRecognition.request();
                bool permission = await _health.requestAuthorization(
                  [HealthDataType.WEIGHT],
                  permissions: [HealthDataAccess.READ_WRITE],
                );
                print(permission);
              },
            ),
            ElevatedButton(
              child: Text("Read Data"),
              onPressed: () async {
                final HealthFactory _health = HealthFactory();
                DateTime untilDate = DateTime.now();
                DateTime fromDate = DateTime(1970);
                try {
                  List<HealthDataPoint> healthData =
                      await _health.getHealthDataFromTypes(
                    fromDate,
                    untilDate,
                    [HealthDataType.WEIGHT],
                  );
                  return print(healthData.toString());
                } on Exception catch (e) {
                  print(e.toString());
                  rethrow;
                }
              },
            ),
            ElevatedButton(
              child: Text("Write Data"),
              onPressed: () async {
                final HealthFactory _health = HealthFactory();
                try {
                  bool success = await _health.writeHealthData(
                    80,
                    HealthDataType.WEIGHT,
                    DateTime.now(),
                    DateTime.now(),
                  );
                  print(success);
                } on Exception catch (e) {
                  print(e.toString());
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

这是我的测试屏幕。

第一个按钮请求read_write datatype权重的权限。在第一个通话中,此窗口弹出: 当我在左上角单击“不允许”时,未授予权限,但是该方法仍然返回 true 。如果我转到设置,无论是否激活权限,它总是返回 true

第二个按钮应该读取Apple Health的重量数据。如果授予许可,一切正常。如果未授予权限,它仍然“有效”,但JSUT返回一个空列表。这很糟糕,因为我无法指出它是否失败或苹果健康没有任何权重数据。

第三个按钮应该将重量数据写入Apple Health。如果再次获得许可,一切都可以正常工作。如果未授予其权限,则MEHOD将返回false,不写任何东西。这已经是比从阅读操作中更好的指标了,但是我仍然无法指出是否没有授予权限或其他错误。

因此,我的问题是:是否有任何方法可以在代码级别上指出权限是否已授予?如果同步工作起作用,我真的需要它向用户介绍,如果没有,为什么它不起作用。

I use the health package in my App to sync data between my app and Google Fit / Apple Health. So far I have only testet Apple Health and it works perfectly fine if I grant all the necessary permissions. But I found one weird thing and I can't figure out how to fix it. So far I have only implemented and tested the integration with Apple Health.

So, I check if the app has the permission to read or write a certain data type, and then I read it or write it to Apple Health. If the permission was granted and the read / write operation was successful, I want to present that to the user. If the permission was not granted, I also want to present that to the user, so he knows what went wrong. In the HealthFactory class of the package there is the requestAuthorization method that I call to check whether the user has permission or not. The behavior I expected was that, if the permission is not granted, the return value of that method is false if the permission is not granted. But instead, it is always true. Also, the methods getHealthDataFromTypes and writeHealthData don't really indicate whether the permission is granted or not.

I implemented a few methods to showcase that:

class TestScreen extends StatelessWidget {
  TestScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ElevatedButton(
              child: Text("Health Permission"),
              onPressed: () async {
                final HealthFactory _health = HealthFactory();
                await Permission.activityRecognition.request();
                bool permission = await _health.requestAuthorization(
                  [HealthDataType.WEIGHT],
                  permissions: [HealthDataAccess.READ_WRITE],
                );
                print(permission);
              },
            ),
            ElevatedButton(
              child: Text("Read Data"),
              onPressed: () async {
                final HealthFactory _health = HealthFactory();
                DateTime untilDate = DateTime.now();
                DateTime fromDate = DateTime(1970);
                try {
                  List<HealthDataPoint> healthData =
                      await _health.getHealthDataFromTypes(
                    fromDate,
                    untilDate,
                    [HealthDataType.WEIGHT],
                  );
                  return print(healthData.toString());
                } on Exception catch (e) {
                  print(e.toString());
                  rethrow;
                }
              },
            ),
            ElevatedButton(
              child: Text("Write Data"),
              onPressed: () async {
                final HealthFactory _health = HealthFactory();
                try {
                  bool success = await _health.writeHealthData(
                    80,
                    HealthDataType.WEIGHT,
                    DateTime.now(),
                    DateTime.now(),
                  );
                  print(success);
                } on Exception catch (e) {
                  print(e.toString());
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

This is my test screen.

The first button requests READ_WRITE permission for the datatype WEIGHT. At the first call, this window pops up:
Health Access
When I click on "Don't Allow" in the top left corner, the permissions are NOT granted, but the method still returns true. If I go to the settings, no matter if I activate the permission or not, it always returns true.

The second button is supposed to read WEIGHT data from Apple Health. If the permission is granted, everything works fine. If the permission is NOT granted, it still "works", but jsut returns an empty list. This is pretty bad, because I can't indicate whether it failed or Apple Health just doesn't have any WEIGHT data.

The third button is supposed to write WEIGHT data into Apple Health. If the permission is granted, again, everthing works fine. If ther permission is NOT granted, the mehod returns false and doesn't write anything. This is already a better indicator than from the READ operation, but still, I can't indicate whether the permission wasn't granted or it was some other error.

So my question is: Is there any way to indicate at code level whether the permissions have been granted or not? I really need this to present to the user if the sync worked, and if not, why it didn't work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怀里藏娇 2025-01-31 12:19:59

Please take a look at the documentation https://pub.dev/documentation/health/latest/health/HealthFactory/hasPermissions.html please also verify but on IOS it looks like it returns null. Apple protects this fields and the package returns null as Apple HealthKit will not disclose if READ access has been granted for a data type due to privacy concern, this method can only return null to represent an undertermined status, if it is called on iOS with a READ or READ_WRITE access.:

倾`听者〃 2025-01-31 12:19:59

您是对的,似乎HealthKit不允许我们访问权限状态。我个人认为,如果我在过去一个月中无法获得步骤,则用户没有切换许可:

  Future<bool> hasPermissionsOniOS() async {
    final now = DateTime.now();
    final lastMonth = DateTime(now.year, now.month - 1, now.day);
    final stepsOfLastMonth =
        await health.getTotalStepsInInterval(lastMonth, now);
    return stepsOfLastMonth != null;
  }

You are right, it seems like HealthKit do not allow us to access the permission status. I personally consider that the user did not toggled the permission if I can't get its steps over the past month:

  Future<bool> hasPermissionsOniOS() async {
    final now = DateTime.now();
    final lastMonth = DateTime(now.year, now.month - 1, now.day);
    final stepsOfLastMonth =
        await health.getTotalStepsInInterval(lastMonth, now);
    return stepsOfLastMonth != null;
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文