健康

启用与 Apple Health 和 Google Fit 的健康数据读写。

该插件支持

  • 通过 hasPermissionsrequestAuthorizationrevokePermissions 方法处理健康数据访问权限。
  • 通过 getHealthDataFromTypes 方法读取健康数据。
  • 通过 writeHealthData 方法写入健康数据。
  • 通过 writeWorkout 方法在 iOS 上写入训练数据。
  • 通过 writeAudiogram 方法在 iOS 上写入听力图数据。
  • 通过 getTotalStepsInInterval 方法访问总步数。
  • 通过 removeDuplicates 方法清除重复数据点。

请注意,对于 Android,目标手机需要安装 Google Fit 并有互联网访问权限,否则该插件将无法正常工作。

数据类型

数据类型 单位 iOS Android 注释
ACTIVE_ENERGY_BURNED 卡路里
BASAL_ENERGY_BURNED 卡路里
BLOOD_GLUCOSE 毫克/分升
BLOOD_OXYGEN 百分比
BLOOD_PRESSURE_DIASTOLIC 毫米汞柱
BLOOD_PRESSURE_SYSTOLIC 毫米汞柱
BODY_FAT_PERCENTAGE 百分比
BODY_MASS_INDEX 无单位
BODY_TEMPERATURE 摄氏度
ELECTRODERMAL_ACTIVITY 西门子
HEART_RATE 次/分钟
HEIGHT
RESTING_HEART_RATE 次/分钟
STEPS 计数
WAIST_CIRCUMFERENCE
WALKING_HEART_RATE 次/分钟
WEIGHT 千克
DISTANCE_WALKING_RUNNING
FLIGHTS_CLIMBED 计数
MOVE_MINUTES 分钟
DISTANCE_DELTA
MINDFULNESS 分钟
SLEEP_IN_BED 分钟
SLEEP_ASLEEP 分钟
SLEEP_AWAKE 分钟
WATER 在 Android 上,饮水量需要注册第三方应用。
EXERCISE_TIME 分钟
WORKOUT 无单位
HIGH_HEART_RATE_EVENT 无单位 需要 Apple Watch
LOW_HEART_RATE_EVENT 无单位 需要 Apple Watch
IRREGULAR_HEART_RATE_EVENT 无单位 需要 Apple Watch
HEART_RATE_VARIABILITY_SDNN 毫秒 需要 Apple Watch
HEADACHE_NOT_PRESENT 分钟
HEADACHE_MILD 分钟
HEADACHE_MODERATE 分钟
HEADACHE_SEVERE 分钟
HEADACHE_UNSPECIFIED 分钟
AUDIOGRAM DECIBEL_HEARING_LEVEL

设置

Apple Health (iOS)

步骤 1:在 Info.plist 中添加以下 2 个条目

<key>NSHealthShareUsageDescription</key>
<string>We will sync your data with the Apple Health app to give you better insights</string>
<key>NSHealthUpdateUsageDescription</key>
<string>We will sync your data with the Apple Health app to give you better insights</string>

步骤 2:“Capabilities”选项卡中启用“HealthKit”。

Google Fit (Android)

请遵循 https://developers.google.com/fit/android/get-api-key 上的指南。

以下是遵循该指南的示例

将目录更改为您的密钥存储目录 (MacOS):cd ~/.android/

获取您的密钥存储 SHA1 指纹:keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

示例输出

Alias name: androiddebugkey
Creation date: Jan 01, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Android Debug, O=Android, C=US
Issuer: CN=Android Debug, O=Android, C=US
Serial number: 4aa9b300
Valid from: Mon Jan 01 08:04:04 UTC 2013 until: Mon Jan 01 18:04:04 PST 2033
Certificate fingerprints:
     MD5:  AE:9F:95:D0:A6:86:89:BC:A8:70:BA:34:FF:6A:AC:F9
     SHA1: BB:0D:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:75
     Signature algorithm name: SHA1withRSA
     Version: 3

请遵循 https://developers.google.com/fit/android/get-api-key 上的说明,为 Google 项目设置 OAuth2 Client ID,并将 SHA1 指纹添加到该 OAuth2 凭据。

客户端 ID 将类似于 YOUR_CLIENT_ID.apps.googleusercontent.com

Android 权限

从 API 级别 28 (Android 9.0) 开始,访问某些健身数据(例如步数)需要特殊权限。

要设置它,请将以下行添加到您的 AndroidManifest.xml 文件中。

<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>

此外,对于训练:如果请求了训练距离,则需要下面的位置权限。

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

有一个 debugmainprofile 版本,它们根据您启动应用的方式而选择。通常,仅将权限添加到 main 版本就足够了。

由于这是一个标记为 dangerous 的保护级别,权限系统不会自动授予它,它需要用户的操作。您可以使用 permission_handler 插件提示用户。遵循插件设置说明,并在请求数据之前添加以下行

await Permission.activityRecognition.request();

Android X

android/gradle.properties 文件的内容替换为以下行

org.gradle.jvmargs=-Xmx1536M
android.enableJetifier=true
android.useAndroidX=true

用法

有关如何使用 Health API 的详细示例,请参阅示例应用。

Health 插件通过 HealthFactory 类使用,使用不同的方法来处理权限以及获取和添加数据到 Apple Health / Google Fit。以下是使用该插件的简化流程。

  // create a HealthFactory for use in the app
  HealthFactory health = HealthFactory();

  // define the types to get
  var types = [
    HealthDataType.STEPS,
    HealthDataType.BLOOD_GLUCOSE,
  ];

  // requesting access to the data types before reading them
  bool requested = await health.requestAuthorization(types);

  var now = DateTime.now();

  // fetch health data from the last 24 hours
  List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(
     now.subtract(Duration(days: 1)), now, types);

  // request permissions to write steps and blood glucose
  types = [HealthDataType.STEPS, HealthDataType.BLOOD_GLUCOSE];
  var permissions = [
      HealthDataAccess.READ_WRITE,
      HealthDataAccess.READ_WRITE
  ];
  await health.requestAuthorization(types, permissions: permissions);

  // write steps and blood glucose
  bool success = await health.writeHealthData(10, HealthDataType.STEPS, now, now);
  success = await health.writeHealthData(3.1, HealthDataType.BLOOD_GLUCOSE, now, now);

  // get the number of steps for today
  var midnight = DateTime(now.year, now.month, now.day);
  int? steps = await health.getTotalStepsInInterval(midnight, now);

健康数据

HealthDataPoint 对象包含以下数据字段

HealthValue value; // NumericHealthValue, AudiogramHealthValue, WorkoutHealthValue
HealthDataType type;
HealthDataUnit unit;
DateTime dateFrom;
DateTime dateTo;
PlatformType platform;
String uuid, deviceId;
String sourceId;
String sourceName;

HealthData 对象可以使用 toJson() 方法序列化为 JSON。

获取健康数据

有关如何操作的展示,请参阅 pub.dev 上的示例。

注意:对于 iOS:请求健康数据之前必须解锁设备,否则将抛出错误。

flutter: Health Plugin Error:
flutter: 	PlatformException(FlutterHealth, Results are null, Optional(Error Domain=com.apple.healthkit Code=6 "Protected health data is inaccessible" UserInfo={NSLocalizedDescription=Protected health data is inaccessible}))

过滤重复项

如果多次请求相同数据并将其保存在同一个数组中,则会出现重复项。

单个数据点可以相互比较,使用 == 运算符,例如:

HealthDataPoint p1 = ...;
HealthDataPoint p2 = ...;
bool same = p1 == p2;

如果您有一个数据点列表,可以使用以下方法删除重复项:

List<HealthDataPoint> points = ...;
points = Health.removeDuplicates(points);

训练

从 4.0.0 开始,Health 支持向 iOS 和 Android 添加训练。

训练类型

训练类型 iOS Android 注释
ARCHERY
BADMINTON
BASEBALL
BASKETBALL
BIKING 在 iOS 上是 CYCLING,但在此处更改了名称以匹配 Android。
BOXING
CRICKET
CURLING
ELLIPTICAL
FENCING
AMERICAN_FOOTBALL
AUSTRALIAN_FOOTBALL
SOCCER
GOLF
GYMNASTICS
HANDBALL
HIGH_INTENSITY_INTERVAL_TRAINING
HIKING
HOCKEY
SKATING 在 iOS 上是 skating_sports
JUMP_ROPE
KICKBOXING
MARTIAL_ARTS
PILATES
RACQUETBALL
RUGBY
RUNNING
ROWING
SAILING
CROSS_COUNTRY_SKIING
DOWNHILL_SKIING
SNOWBOARDING
SOFTBALL
SQUASH
STAIR_CLIMBING
SWIMMING
TABLE_TENNIS
TENNIS
VOLLEYBALL
WALKING
WATER_POLO
YOGA
BOWLING
CROSS_TRAINING
TRACK_AND_FIELD
DISC_SPORTS
LACROSSE
PREPARATION_AND_RECOVERY
FLEXIBILITY
COOLDOWN
WHEELCHAIR_WALK_PACE
WHEELCHAIR_RUN_PACE
HAND_CYCLING
CORE_TRAINING
FUNCTIONAL_STRENGTH_TRAINING
TRADITIONAL_STRENGTH_TRAINING
MIXED_CARDIO
STAIRS
STEP_TRAINING
FITNESS_GAMING
BARRE
CARDIO_DANCE
SOCIAL_DANCE
MIND_AND_BODY
PICKLEBALL
CLIMBING
EQUESTRIAN_SPORTS
FISHING
HUNTING
PLAY
SNOW_SPORTS
PADDLE_SPORTS
SURFING_SPORTS
WATER_FITNESS
WATER_SPORTS
TAI_CHI
WRESTLING
AEROBICS
BIATHLON
CALISTHENICS
CIRCUIT_TRAINING
CROSS_FIT
DANCING
DIVING
ELEVATOR
ERGOMETER
ESCALATOR
FRISBEE_DISC
GARDENING
GUIDED_BREATHING
HORSEBACK_RIDING
HOUSEWORK
INTERVAL_TRAINING
IN_VEHICLE
KAYAKING
KETTLEBELL_TRAINING
KICK_SCOOTER
KITE_SURFING
MEDITATION
MIXED_MARTIAL_ARTS
P90X
PARAGLIDING
POLO
ROCK_CLIMBING (是) 在 iOS 上将存储为 CLIMBING
RUNNING_JOGGING (是) 在 iOS 上将存储为 RUNNING
RUNNING_SAND (是) 在 iOS 上将存储为 RUNNING
RUNNING_TREADMILL (是) 在 iOS 上将存储为 RUNNING
SCUBA_DIVING
SKATING_CROSS (是) 在 iOS 上将存储为 SKATING
SKATING_INDOOR (是) 在 iOS 上将存储为 SKATING
SKATING_INLINE (是) 在 iOS 上将存储为 SKATING
SKIING_BACK_COUNTRY
SKIING_KITE
SKIING_ROLLER
SLEDDING
STAIR_CLIMBING_MACHINE
STANDUP_PADDLEBOARDING
STILL
STRENGTH_TRAINING
SURFING
SWIMMING_OPEN_WATER
SWIMMING_POOL
TEAM_SPORTS
TILTING
TREADMILL
VOLLEYBALL_BEACH
VOLLEYBALL_INDOOR
WAKEBOARDING
WALKING_FITNESS
WALKING_NORDIC
WALKING_STROLLER
WALKING_TREADMILL
WEIGHTLIFTING
WHEELCHAIR
WINDSURFING
ZUMBA
OTHER

GitHub

查看 Github