更新记录

1.1.5(2026-11-06)

  • 新增示例中并列的单项、全部读取授权入口,全部授权按当前服务支持的读取指标申请,不包含写入权限。
  • 修复 uni-app x 示例分类按钮嵌套 text 导致 iOS 编译警告的问题,保留分类切换和选中样式。
  • 优化示例“切换指标”按钮高度与对齐,隐藏当前服务不可用的扩展历史授权入口。

1.1.4(2026-11-05)

  • 新增 Android 系统自动计步条件检测,分别报告 Android 版本、U 扩展版本、计步传感器和权限状态。
  • 新增独立安卓本机计步,支持前台服务、通知停止、按日保存可信增量和中断状态,不混入健康平台统计。
  • 新增安卓示例自动检测、两次启用确认、Vue2 / Vue3 共用示例和复制全部计步日志。
  • 新增原生服务与权限;使用本机计步需重新制作包含当前插件的自定义基座或应用包。
  • 修复 iOS 云打包时可能出现的编译错误,现有调用方式不变;升级后需重新制作 iOS 自定义基座或应用包。

1.1.3(2026-11-05)

  • 修复 Android 健康摘要在重叠区间内选择最新记录时与其他平台规则不一致的问题;无法完整读取时明确返回失败。
  • 优化示例界面,按基础查询、写入管理和服务自检分类展示,改善记录内容、布局和文字可读性。
  • 优化使用说明,按基础、高级、进阶和完整示例组织健康数据接入。
查看更多

平台兼容性

uni-app(5.24)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
√ √ × × √ √ √ √ √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × - - - - - - - - - -

uni-app x(5.24)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × √ √ √ ×

lizhao-health

lizhao-health 用于在 uni-app / uni-app x 中读取手机已有的健康记录、生成多指标摘要,并在获得相应权限后写入和删除自己应用创建的记录。

第一次接入,建议先读取今天的步数记录。读通后,再按下面的业务模块增加饮水、身体指标、心率、血压、血糖和记录管理。

功能特色

功能 用途
读取健康明细 步数、运动、睡眠与身体测量等系统已有记录
统计与摘要 聚合时段数据,获取首页多指标摘要
保存主动录入 按权限写入饮水、身体测量等记录
管理应用记录 仅删除本应用创建的指定记录
运动首页 运动首页:展示步数、距离和活动消耗。
每日摘要 每日摘要:一次取得今日步数、活动能量、饮水量、最新测量与最近运动。
饮水记录 饮水记录:保存主动录入的饮水量,查看一段时间内的饮水总量。
身体档案 身体档案:查看身高、体重、体脂和去脂体重的原始记录与变化。
健康记录 健康记录:查询心率、心率变异性、呼吸、最大摄氧量、血压、血糖、血氧和体温。
运动记录 运动记录:读取系统保存的运动类别、时间及可用的距离和活动能量,不读取路线坐标。
睡眠记录 睡眠记录:按时间查看睡眠区间和系统提供的睡眠阶段。
数据管理 数据管理:保存使用者主动录入的数据,并删除本应用保存的指定记录。

适合哪些场景

场景 使用能力
运动首页 展示步数、距离和活动消耗。
每日摘要 一次取得今日步数、活动能量、饮水量、最新测量与最近运动。
饮水记录 保存主动录入的饮水量,查看一段时间内的饮水总量。
身体档案 查看身高、体重、体脂和去脂体重的原始记录与变化。
健康记录 查询心率、心率变异性、呼吸、最大摄氧量、血压、血糖、血氧和体温。
运动记录 读取系统保存的运动类别、时间及可用的距离和活动能量,不读取路线坐标。
睡眠记录 按时间查看睡眠区间和系统提供的睡眠阶段。
数据管理 保存使用者主动录入的数据,并删除本应用保存的指定记录。

下载与导入

适用项目 示例页面路径(相对项目根目录)
uni-app(Vue 2 / Vue 3) uni_modules/lizhao-health/example/health-demo.vue
uni-app x uni_modules/lizhao-health/example/health-demo.uvue

从基础到进阶:按业务模块使用

代码片段放入对应宿主页面脚本或按钮方法;uni-app x 保留 UTS 类型,使用 javascript 标记仅用于市场语法着色。整页示例按其标注的 Vue 版本使用。

以下模块假设已经完成相应类型的读取或写入授权,并选好了 provider。示例中的 provider、时间与数值由页面传入,每个函数只完成一个目标。

基础功能配置示例(简单示例)

只申请步数读取权限。把下面的函数绑定到页面按钮,由使用者点击后开始。

import {
  getHealthCapabilities,
  requestHealthAuthorization,
  queryHealthRecords
} from '@/uni_modules/lizhao-health'

// 由“读取今日步数”按钮调用。
function readTodaySteps() {
  getHealthCapabilities({
    success(capabilities) {
      // 没有可用服务或需要选择服务时,先显示原因。
      const provider = capabilities.provider
      if (provider == null) {
        console.log('暂时无法读取步数', capabilities.reason)
        return
      }

      requestHealthAuthorization({
        provider,
        readTypes: ['stepCount'],
        writeTypes: [],
        success() {
          // 授权流程结束后再读取;结果仍可能没有可见记录。
          const now = new Date()
          const start = new Date(now.getFullYear(), now.getMonth(), now.getDate())
          queryHealthRecords({
            provider,
            type: 'stepCount',
            startTime: start.getTime(),
            endTime: now.getTime(),
            pageSize: 20,
            success(result) {
              if (result.records.length == 0) {
                console.log('当前没有可读取的步数记录')
                return
              }
              console.log('已读取步数明细,本页记录数', result.records.length)
            },
            fail(error) {
              console.log('读取步数失败', error.errMsg)
            }
          })
        },
        fail(error) {
          console.log('步数授权流程未完成', error.errMsg)
        }
      })
    },
    fail(error) {
      console.log('检查健康服务失败', error.errMsg)
    }
  })
}

看到结果后,基础读取流程就跑通了。这里读取的是明细;需要今日总步数时,按模块一使用支持 sum 的统计接口。不同来源明细不能简单相加。

Android 读取的是所选健康服务已保存的步数记录。首次接入先核对后文“Android 步数接入条件”;服务存在和授权成功不代表已经采集到步数。

高级示例

今日摘要与运动

getHealthSummary 适合首页或看板一次读取多个常用指标。时间范围和每一项操作都必须显式传入;接口不会自动申请权限,也不会写入或删除数据。

import { getHealthSummary } from '@/uni_modules/lizhao-health'

function readTodaySummary(provider) {
  const now = new Date()
  const start = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime()
  getHealthSummary({
    provider,
    startTime: start,
    endTime: now.getTime(),
    items: [
      { type: 'stepCount', operation: 'sum' },
      { type: 'activeEnergyBurned', operation: 'sum' },
      { type: 'heartRate', operation: 'latest' },
      { type: 'exerciseSession', operation: 'latest' },
      { type: 'hydration', operation: 'sum' },
      { type: 'leanBodyMass', operation: 'latest' }
    ],
    success(result) {
      for (const item of result.items) {
        // 每项独立结算,不能把 empty 或 unsupported 显示为 0。
        // 数值供页面展示;日志只记录状态。
        console.log(item.type, item.operation, item.status)
        if (item.record?.exercise != null) {
          console.log('最近运动类型', item.record.exercise.activityType)
        }
      }
    },
    fail(error) {
      // 只有参数、服务选择或整体服务故障等顶层问题才走 fail。
      console.log('今日摘要未完成', error.errMsg)
    }
  })
}

items 为 1–30 项,同一 type + operation 不可重复。latest 返回时间范围内最新的一条完整记录;sum / average / min / max 使用当前服务能力表中明确支持的原生统计。返回顺序与输入一致,每项状态为 success / empty / unsupported / failed,一项失败不会丢掉其他项结果。

一次摘要会复用本次探测到的服务与指标能力,下一次调用重新探测;每项数据操作仍由原生服务检查当前权限,能力快照不代表持续授权,也不是多指标数据的原子快照。首次能力探测失败或响应损坏属于整体服务故障,触发顶层 fail / complete,不继续执行数据读取。

latest 按记录结束时间选择;结束时间相同时按开始时间选择。Android 查询范围过大或不能完整读取时会返回失败,请缩小时间范围重试。

exerciseSession 只允许 latest 或明细查询,不支持写入、删除和统计。HealthRecord.exercise 包含归一化运动类别、平台原始类别,以及系统明确提供的距离和活动能量;插件不请求或返回路线、坐标和轨迹。

进阶示例

在需要排查服务配置或授权状态时,由使用者主动触发诊断;此操作不读取健康记录。

import { getHealthDiagnostics } from '@/uni_modules/lizhao-health'

function checkHealthService() {
  getHealthDiagnostics({
    success(result) { console.log('服务状态', result.reason) },
    fail(error) { console.log('检查失败', error.errMsg) },
    complete() { console.log('检查结束') }
  })
}

完整示例

完成平台配置后,在 uni-app 或 uni-app x 的页面按钮中调用;首次需要由使用者同意读取步数。首次授权和实际记录是否可见由所选服务决定。

import { getHealthCapabilities, requestHealthAuthorization, queryHealthRecords } from '@/uni_modules/lizhao-health'

function readSteps() {
  getHealthCapabilities({
    success(capabilities) {
      const provider = capabilities.provider
      if (provider == null) {
        console.log('请检查或选择健康服务', capabilities.reason)
        return
      }
      requestHealthAuthorization({
        provider,
        readTypes: ['stepCount'],
        writeTypes: [],
        success() {
          const now = new Date()
          const start = new Date(now.getFullYear(), now.getMonth(), now.getDate())
          queryHealthRecords({
            provider,
            type: 'stepCount',
            startTime: start.getTime(),
            endTime: now.getTime(),
            pageSize: 20,
            success(result) { console.log('步数记录', result.records) },
            fail(error) { console.log('读取失败', error.errMsg) },
            complete() { console.log('读取结束') }
          })
        },
        fail(error) { console.log('授权未完成', error.errMsg) }
      })
    },
    fail(error) { console.log('健康服务不可用', error.errMsg) }
  })
}

模块化示例

模块 使用目的 示例
运动 查看距离和活动消耗 模块一
身体档案 查看身高、体重和去脂体重 模块二
健康测量 查看心率、血压和血糖 模块三
睡眠与记录管理 查询睡眠、保存和删除自有记录 模块四至六
历史和诊断 分页、授权、饮水和服务指引 模块七至十一

完整页面与宿主要求

按上方表格选择示例并注册页面。两个入口均按 Tab 展示查询、写入管理与服务自检,安卓设备还提供本机计步。主示例提供服务选择、接入指引、单项与批量授权、独立历史授权、读取与分页、统计与今日概览,以及身高、饮水量、去脂体重录入。删除目标只来自查询中确认属于本应用的记录,或本次已确认写入成功的非空原生 ID;打开页面不会自动读写健康平台记录,安卓示例会检测条件并读取本机计步状态。

代码片段的使用前提

以下为各业务示例的使用前提与类型说明。

以下模块假设已经完成相应类型的读取或写入授权,并选好了 provider。示例中的 provider、时间与数值由页面传入,每个函数只完成一个目标。UTS 代码保留真实类型,javascript 仅用于市场着色。

示例中的服务选择、批量授权与自检

示例将服务名称显示为“自动选择、苹果健康、安卓健康连接、华为健康、鸿蒙健康”,对应的接口参数仍为 auto、healthKit、healthConnect、huaweiHealth、harmonyHealth。自动选择只在一个服务可用时生效;有多个可用服务时请明确选择。

  • 申请单项读取:只申请当前选中指标的读取权限,例如步数。
  • 申请本页全部读取权限:先重新检查当前服务的能力,再一次申请该服务支持读取的全部指标;不申请写入权限。实际业务只申请需要使用的类型即可。
  • 一键自检:检查服务是否可用、支持哪些读取指标,以及系统允许查询的读写授权状态。查看自检详情可看到逐项中文结果;自检不弹出授权、不读取健康明细,也不写入或删除记录,实际读写仍由对应按钮单独验证。
  • 申请扩展历史读取:只在所选安卓健康连接服务支持该功能时可用,点击后重新探测,再单独申请历史权限;不改变普通指标授权,也不会自动读取历史记录。
  • 查看接入指引:按当前服务状态展示可执行步骤,不自动跳转、申请授权或访问健康记录。切换服务后清除旧指引。
  • 全功能测试(iOS):展开后先申请测试读写权限,再手动开始。按当前能力逐项检查读取、统计和写入回读;每次只创建一条合成测试记录,按本次写入返回的 ID 删除并复查。已有记录不会作为自动删除目标。若中途退出或清理失败,先使用“恢复清理本次测试记录”;写入结果未知且没有 ID 时须人工核对,不自动重复写入。测试日志只记录步骤、数量和结果,不输出健康数值或记录 ID。

需要在业务中一次申请多项时,把所需类型放入同一个 readTypes 数组。例如仅在 iOS 苹果健康中申请步数、身高和心率:

import { requestHealthAuthorization } from '@/uni_modules/lizhao-health'

requestHealthAuthorization({
  provider: 'healthKit',
  readTypes: ['stepCount', 'height', 'heartRate'],
  writeTypes: [],
  success() { console.log('授权流程已结束,请按实际可读取的数据继续处理') },
  fail(error) { console.log('授权流程未完成', error.errMsg) }
})

iOS 的读取授权状态为 notObservable,表示系统不提供该状态,不能据此判断允许或拒绝。系统弹窗的项目与名称由本次请求类型和系统决定;已做过选择的权限再次申请时不一定弹窗,可在系统健康设置中核对。

Android 请在应用前台页面获得焦点后,由用户操作发起授权。若授权入口未能启动,会明确失败并释放请求,可回到前台后重试;已打开授权页面后,不会因为用户停留阅读而按启动超时取消授权。

模块一:查看运动距离与活动消耗

适合在运动首页展示今天走了多远、消耗了多少活动能量。

import { aggregateHealthData } from '@/uni_modules/lizhao-health'

// type 选择当前服务支持 sum 的 stepCount、distance、walkingRunningDistance 或 activeEnergyBurned。
// 纯跑步距离通过明细接口读取,不能用通用距离替代。
function readActivityTotal(provider, type, startTime, endTime) {
  aggregateHealthData({
    provider, type, startTime, endTime,
    operation: 'sum',
    bucket: 'none',
    success(result) { console.log('活动统计', result.value, result.unit) },
    fail(error) { console.log('读取活动统计失败', error.errMsg) }
  })
}

distance 表示通用移动距离;walkingRunningDistance 表示步行与跑步合计;runningDistance 只表示能够确认是跑步的距离。当前服务不提供的类型会明确返回不支持。

读取 iOS 跑步记录时,把模块二的 type 改为 runningDistance。返回的是每次跑步训练中系统保存的距离;此类型只读,不提供写入、删除或总量统计。它不会把日常走路算成跑步。

需要趋势图时,可将支持统计的类型设为 bucket: 'day',同时传 timeZone: 'Asia/Shanghai',从 result.buckets 读取逐日值。开始和结束日按实际查询范围裁剪,一次最多 366 个日历日。

模块二:查看身体档案与去脂体重

适合建立身体档案或查看一段时间内的测量历史。

import { queryHealthRecords } from '@/uni_modules/lizhao-health'

// type 使用 height、bodyMass、bodyFatPercentage 或 leanBodyMass。
function readBodyRecords(provider, type, startTime, endTime) {
  queryHealthRecords({
    provider, type, startTime, endTime,
    pageSize: 20,
    success(result) { console.log('本页身体记录数量', result.records.length) },
    fail(error) { console.log('读取身体记录失败', error.errMsg) }
  })
}

身高统一以厘米返回,体重与去脂体重以千克返回,体脂以百分数返回,例如 18.5 表示 18.5%。去脂体重来自服务已有的原始测量,插件不会由体重和体脂率计算。

使用者已有去脂体重测量结果时,可以在申请 leanBodyMass 写入权限、确认能力后保存当前测量。开始和结束时间相同,数值必须为有限正数。

import { writeHealthRecords } from '@/uni_modules/lizhao-health'

// 由“保存去脂体重”按钮调用;kg 来自本次真实测量。
function saveLeanBodyMass(provider, kg) {
  const measuredAt = Date.now()
  writeHealthRecords({
    provider,
    records: [{ type: 'leanBodyMass', startTime: measuredAt, endTime: measuredAt,
      value: kg, unit: 'kg' }],
    success(result) {
      console.log('去脂体重保存结果', result.items[0].status)
      // 仅 written 且非空的 recordId 可保存在页面中供之后核对删除。
    },
    fail(error) { console.log('去脂体重未保存', error.errMsg) }
  })
}

查看最新值时使用 getHealthSummary 的 { type: 'leanBodyMass', operation: 'latest' }。Health Connect 支持明细、最新记录和自有 ID 删除,未提供对应原生统计;iOS 另支持 average/min/max。

模块三:查看心率、血压、血糖等测量记录

适合展示已有的测量结果。读取健康记录本身不会让手机开始测量。

import { queryHealthRecords } from '@/uni_modules/lizhao-health'

// type 选择 heartRate、restingHeartRate、bloodPressure、bloodGlucose、
// oxygenSaturation 或 bodyTemperature 中当前服务支持的类型。
function readMeasurementRecords(provider, type, startTime, endTime) {
  queryHealthRecords({
    provider, type, startTime, endTime,
    pageSize: 20,
    success(result) { console.log('本页测量记录数量', result.records.length) },
    fail(error) { console.log('读取测量记录失败', error.errMsg) }
  })
}

血压记录包含收缩压和舒张压。若只读取到一侧,缺失的一侧保持空值,不显示为 0。心率记录可能包含多个带测量时间的采样点。

模块四:查看睡眠时间与阶段

适合查看某晚的睡眠记录。建议查询从前一天晚上到第二天中午的范围,避免漏掉跨午夜的记录。

import { queryHealthRecords } from '@/uni_modules/lizhao-health'

// 每条睡眠记录保留实际起止时间及平台提供的阶段。
function readSleepRecords(provider, startTime, endTime) {
  queryHealthRecords({
    provider, type: 'sleep', startTime, endTime,
    pageSize: 50,
    success(result) { console.log('本页睡眠记录数量', result.records.length) },
    fail(error) { console.log('读取睡眠记录失败', error.errMsg) }
  })
}

“卧床”不等于“睡着”。系统没有提供深睡、浅睡等阶段时,插件不会自行推算。

模块五:保存自己录入的一条身高

适合使用者填写身高后,主动保存到所选健康数据服务。执行前先申请 height 写入权限,并检查当前服务支持写入。

import { writeHealthRecords } from '@/uni_modules/lizhao-health'

// heightCm 来自使用者输入,由“保存身高”按钮调用。
function saveHeight(provider, heightCm) {
  const measuredAt = Date.now()
  writeHealthRecords({
    provider,
    records: [{
      type: 'height',
      value: heightCm,
      unit: 'cm',
      startTime: measuredAt,
      endTime: measuredAt
    }],
    success(result) {
      // 保存返回的记录标识,用于之后查询或精确删除。
      console.log('身高保存结果', result.items)
    },
    fail(error) {
      // 批量写入时可能部分成功,应先查看逐条结果再决定如何处理。
      console.log('保存身高失败', error.errMsg)
      if (error.items != null) {
        console.log('逐条处理结果', error.items)
      }
    }
  })
}

步数、活动能量等区间记录需要真实的开始和结束时间;血压需要同时填写收缩压和舒张压。不要把所有数据都当作一条瞬时数值。

模块六:删除本应用保存的指定记录

适合纠正自己应用录入的错误记录。删除前由页面让使用者核对目标,再传入查询结果中的那条记录。

import { deleteHealthRecords } from '@/uni_modules/lizhao-health'

// record 来自查询结果;页面只对当前应用的可删除记录提供此按钮。
function deleteOwnRecord(record) {
  if (!record.ownData) {
    console.log('只能删除本应用写入的记录')
    return
  }
  deleteHealthRecords({
    provider: record.provider,
    type: record.type,
    ids: [record.id],
    success() { console.log('删除请求已完成,请刷新记录列表') },
    fail(error) { console.log('删除失败', error.errMsg) }
  })
}

插件还会核验数据来源,不能通过传入其他应用的记录 ID 绕过限制。部分服务无法返回准确删除条数,遇到空值应刷新列表确认,不把它解释为删除了 0 条。

模块七:继续读取下一页历史记录

适合支持分页服务的记录列表“加载更多”。第一页没有 pageToken;后续页同时传上一页返回的令牌和实际 provider,不能继续使用 auto。iOS 和华为 Android 提供有限明细查询,记录过多时需缩小时间范围,不提供这个翻页入口。

import { queryHealthRecords } from '@/uni_modules/lizhao-health'

// 其他查询条件必须与取得令牌的上一页完全一致。
function readNextPage(provider, type, startTime, endTime, pageToken) {
  queryHealthRecords({
    provider, type, startTime, endTime, pageToken,
    pageSize: 20,
    success(result) {
      console.log('本页记录数量', result.records.length)
      console.log('还有下一页', result.nextPageToken != null)
      if (result.hasMore && !result.paginationSupported) {
        console.log('当前服务还有记录,请缩小查询时间范围')
      }
    },
    fail(error) { console.log('读取下一页失败', error.errMsg) }
  })
}

只有 hasMore=false 才表示当前可见范围已读完。nextPageToken 为空时不要再次请求第一页;若仍有记录但当前服务不支持翻页,请缩小时间范围。

模块八:检查当前服务与权限状态

适合决定页面显示哪些按钮,或排查为什么读不到记录。

import { getHealthAuthorizationStatus } from '@/uni_modules/lizhao-health'

// 分别查看步数的读和写状态,避免只用一个“已授权”开关。
function checkStepAuthorization(provider) {
  getHealthAuthorizationStatus({
    provider,
    types: ['stepCount'],
    success(result) { console.log('步数授权状态', result.items) },
    fail(error) { console.log('查询授权状态失败', error.errMsg) }
  })
}

模块九:保存本次饮水量

适合使用者手动记录一次饮水。先确认当前服务支持 hydration 写入并申请该类型的写入权限;单位固定为 mL,开始和结束时间表示本次饮水区间,结束必须晚于开始。

import { writeHealthRecords } from '@/uni_modules/lizhao-health'

// 由“保存饮水量”按钮调用;volumeMl 和时间均来自本次真实录入。
function saveHydration(provider, volumeMl, startTime, endTime) {
  writeHealthRecords({
    provider,
    records: [{ type: 'hydration', startTime, endTime, value: volumeMl, unit: 'mL' }],
    success(result) {
      const item = result.items[0]
      console.log('饮水保存结果', item.status)
      // 页面仅在 item.status 为 written 且 recordId 非空时提供本次记录的删除入口。
    },
    fail(error) { console.log('饮水未全部保存,请核对逐条结果', error.errMsg) }
  })
}

iOS 与 Health Connect 支持饮水量读写、自有 ID 删除及 sum。查看今日饮水总量时,可按前面的今日摘要示例使用 { type: 'hydration', operation: 'sum' };空数据不显示为 0。华为 Android 与 HarmonyOS 当前没有此类型的等价实现。

模块十:按需申请更早的历史读取

适合确实需要查询更早健康记录的业务。该功能只对支持扩展历史授权的 Health Connect 生效;historyRead 表示服务功能可用性,historyReadStatus 才是独立的用户权限状态。其他服务不接受 readHistory: true。

import { getHealthCapabilities, requestHealthAuthorization } from '@/uni_modules/lizhao-health'

// 由独立“申请扩展历史读取”按钮调用,不附带任何指标读写权限。
function requestExtendedHistory() {
  getHealthCapabilities({
    provider: 'healthConnect',
    success(capabilities) {
      const service = capabilities.providers.find(item => item.provider == 'healthConnect')
      if (capabilities.provider != 'healthConnect' || service == null || service.historyRead !== true) {
        console.log('当前服务不支持扩展历史授权,请检查接入指引')
        return
      }
      requestHealthAuthorization({
        provider: 'healthConnect', readTypes: [], writeTypes: [], readHistory: true,
        success(result) { console.log('扩展历史权限状态', result.historyReadStatus) },
        fail(error) { console.log('扩展历史授权未完成', error.errMsg) }
      })
    },
    fail(error) { console.log('检查历史读取功能失败', error.errMsg) }
  })
}

readHistory 省略或为 false 时,不请求历史权限。普通 readTypes / writeTypes 授权调用方式不变;单独申请历史权限时两组数组可以为空。实际读取还需要对应指标的读取权限。默认历史范围受系统与首次授权等规则影响;不能用“当前时间减 30 天”推算精确的最早可读时间,未知时 earliestReadableTime 仍为 null。

模块十一:根据服务状态显示接入指引

适合在首次接入或服务不可用时告诉使用者下一步怎么处理。诊断只返回环境与建议,不会弹出授权或读取、写入健康记录。

import { getHealthDiagnostics } from '@/uni_modules/lizhao-health'

function showHealthSetup(provider) {
  getHealthDiagnostics({
    provider,
    success(result) {
      const guidance = result.guidance
      if (guidance == null || guidance.length == 0) {
        console.log('当前服务说明', result.reason)
        return
      }
      for (const item of guidance) {
        // 在页面按顺序展示 title 和 steps,由使用者执行建议。
        console.log(item.title)
        for (const step of item.steps) console.log(step)
      }
    },
    fail(error) { console.log('无法取得接入指引', error.errMsg) }
  })
}

安卓本机计步

需要由应用自行记录手机步数时使用;这条路径直接采集系统计步传感器,不依赖 Health Connect 自动计步的扩展版本门槛。它与健康平台读写分别展示,不会自动写入微信或健康平台。

先检测手机条件,此调用不申请权限、不启动计步:

import { getAndroidStepCapabilities } from '@/uni_modules/lizhao-health'

getAndroidStepCapabilities({
  success(info) {
    console.log('Android API', info.sdkInt)
    console.log('U 扩展版本', info.sdkExtensionU)
    console.log('系统自动计步条件', info.systemStepTrackingStatus)
    console.log('本机传感器', info.stepCounterAvailable)
  },
  fail(error) { console.log('无法确认手机条件', error.errMsg) }
})

systemStepTrackingStatus 为 supported / unsupported / unknown,只判断系统自动采集条件,不代表健康库已有数据。sdkExtensionU=null 表示无法确认;stepCounterAvailable 是系统报告的能力,仍需授权和真实行走验证。

用户确认后开启记录:需在应用前台展示用途和运行条件,再由用户主动操作。首次按需申请身体活动和通知权限;通知被关闭时会明确失败,允许后重试。

import { startLocalStepCounting, getLocalStepCount, stopLocalStepCounting } from '@/uni_modules/lizhao-health'

// 放在已向用户说明条件、并取得确认的按钮回调中。
function enableLocalSteps() {
  startLocalStepCounting({
    success(result) { console.log('记录状态', result.state, result.todaySteps) },
    fail(error) { console.log('未开启记录', error.errMsg) }
  })
}

function readLocalSteps() {
  getLocalStepCount({
    success(result) { console.log('本应用今日已记录', result.todaySteps, result.reason) },
    fail(error) { console.log('状态尚未确认', error.errMsg) }
  })
}

function stopLocalSteps() {
  stopLocalStepCounting({
    success(result) { console.log('已停止,保留记录', result.todaySteps) },
    fail(error) { console.log('停止尚未确认', error.errMsg) }
  })
}
操作 / 结果 含义
getAndroidStepCapabilities 只读环境检测,返回版本、系统自动采集条件、传感器和权限状态
startLocalStepCounting 前台主动开启,服务及传感器监听真正启动后返回;等待首次样本时不填零
getLocalStepCount 只读已保存的本机记录,不申请权限、不恢复服务
stopLocalStepCounting 取消待启动操作并停止采集、移除通知,保留已记录值
source / day / todaySteps 来源固定 androidStepCounter、设备本地日期、当天本应用已记录量;无可信样本为 null
running / enabled / state 当前真实运行、用户启用意图、记录状态;enabled=true 不代表服务仍在运行
startedAt / dayStartedAt / lastSampleAt 本次启用、当天首个可信样本、最后可信样本时间,Unix 毫秒或 null
partial / unassignedSteps / reason 记录范围不完整;跨日等无法可靠归属的增量单列,原因文字用于展示

进入安卓示例会检测条件;条件不足时先说明限制并询问是否选择本机计步,再展示运行条件,确认后才授权和启动。示例提供复制全部计步日志。

启用后通过带常驻通知的前台服务记录,用户可从示例或通知停止。允许应用后台运行有助于持续记录,但系统结束进程、强制停止或重启后需重新检查并启用;没有静默开机恢复,也不承诺完整全天。离开示例只停止界面刷新,已确认开启的计步继续由用户控制。Android App 需在重新制作的自定义基座或应用包中包含当前插件的新增服务与权限。

首次样本仅建立基线,不能把重启以来累计值当作今天的步数。只保留启用后可信连续区间的增量,不补齐首次启用前及中断期间的数据;跨日、时区或时钟变化导致无法归属的增量不填入某一天。记录保存在本应用内,卸载或清除应用数据会删除。其他平台调用这些接口通过 fail 返回 9097001;success/fail 互斥一次,随后 complete 一次。

API 用途速查

模块 适用业务 常用方法 使用结果
服务与权限 接入检查、按需授权 getHealthCapabilities / requestHealthAuthorization / getHealthAuthorizationStatus 当前能使用的服务、指标与权限状态
明细查询 记录列表、测量历史 queryHealthRecords 带时间与来源的记录及下一页令牌
数据统计 今日步数、活动消耗、饮水总量 aggregateHealthData 统计值、单位与统计范围
多项摘要 首页看板、最近测量与运动 getHealthSummary 与输入同序的逐项状态、统计值或最新记录
保存与删除 身体测量、饮水录入、纠正记录 writeHealthRecords / deleteHealthRecords 可追踪的逐条处理结果
历史授权 需要读取更早的记录 getHealthCapabilities / requestHealthAuthorization 扩展历史功能与用户授权状态分别返回
排查问题 服务不可用、读取受限 getHealthDiagnostics 不包含健康数值的环境摘要与接入步骤

每个方法都支持 success / fail / complete。一次调用只会触发 success 或 fail 中的一个,随后触发一次 complete;只使用需要的回调即可。业务数据从 success 或 fail 获取;complete 返回统一的 operation / provider / success / errCode / errMsg 摘要,用于结束加载状态。

参数 类型 必填 说明 默认值 可选参数
provider string 否 使用哪个健康数据服务;存在多个可用服务时需明确选择 auto auto / healthKit / healthConnect / huaweiHealth / harmonyHealth
type string 是 要处理的健康数据类型 无 见后面的指标表
startTime number 查询时必填 开始时间,Unix 毫秒时间戳 无 无
endTime number 查询时必填 结束时间,不包含这一时刻 无 无
readTypes string[] 申请授权时必填 本次需要读取的类型,不读取可传空数组 无 见指标表
writeTypes string[] 申请授权时必填 本次需要写入的类型,不写入可传空数组 无 见指标表
pageSize number 否 明细查询每页最多返回多少条 100 1–500
pageToken string 否 上一页令牌;同时传上一页实际 provider,查询条件保持一致 无 无

时间可直接使用 Date.getTime()。例如一天的范围应是“当天零点到次日零点”,不需要写成 23:59:59。

详细参数与返回值见本页第 6 节「API 用途速查」,业务增强示例见第 5 节「从基础到进阶:按业务模块使用」。

参数、回调和配置

通用回调与服务选择

参数 类型 必填 说明 默认值 可选参数
provider HealthProvider 否 只有一个可用服务时 auto 自动选定;多个可用服务时返回 9097004 auto healthKit / healthConnect / huaweiHealth / harmonyHealth / auto
success function 否 本次操作成功时异步触发一次,参数见返回值 无 无
fail function 否 本次操作失败时异步触发一次,含 errCode、errMsg 无 无
complete function 否 success 或 fail 后触发一次,用于结束加载状态 无 无

getHealthCapabilities、getHealthDiagnostics 只需上述参数,不弹授权框。getHealthAuthorizationStatus 另传非空且不重复的 types 数组;requestHealthAuthorization 传 readTypes、writeTypes,普通指标授权两者不可同时为空。只有对可用 Health Connect 显式传 readHistory: true 时,才允许仅申请历史权限而将两者传为空。

历史读取字段 含义 缺省行为
HealthAuthorizationOptions.readHistory 仅 Health Connect 可选,请求扩展历史权限 false,不随普通指标授权申请
providers[].historyRead 服务是否支持该功能,不能当成用户已授权 缺省时不认定支持
HealthAuthorizationResult.historyReadStatus 独立的历史权限状态,不代替指标 readStatus 其他服务可缺省

queryHealthRecords 的 type、时间与分页参数见前面的常用参数表。区间记录只要与查询范围重叠就可能返回,并保留整条记录的起止时间和值;瞬时记录按测量时间落入范围筛选。明细按时间从早到晚返回。

统计参数

参数 类型 必填 说明 默认值 可选参数
operation string 是 统计方式,按指标能力选择 无 sum / average / min / max
bucket string 否 整段统计或按日返回 none none / day
timeZone string 按日统计时必填 日历分组使用的时区 无 当前服务支持的 IANA 时区标识

摘要参数与返回值

参数 类型 必填 说明 默认值 可选参数
startTime / endTime number 是 显式查询范围,开始早于结束 无 Unix 毫秒
items HealthSummaryRequest[] 是 按输入顺序执行的非重复摘要项 无 1–30 项
items[].type HealthDataType 是 要读取的指标 无 见指标表与能力结果
items[].operation HealthSummaryOperation 是 最新明细或原生统计 无 latest / sum / average / min / max

每个 HealthSummaryItemResult 都包含 type / operation / status / value / unit / record / errCode / message。统计项使用 value;latest 使用 record,同时在数量型最新记录可提供 value / unit。empty 表示当前可见范围没有数据,unsupported 表示服务不支持该类型或操作,failed 表示该项执行失败。

保存记录参数

writeHealthRecords 另传 records 数组,一次 1–100 条。下面是数组中每条记录的字段。

参数 类型 必填 说明 默认值 可选参数
type HealthDataType 是 要写入的指标 无 见指标表与当前服务能力
startTime / endTime number 是 Unix 毫秒;瞬时数量记录两个时间相同,步数/距离/能量/饮水/睡眠结束晚于开始 无 无
value number 数量记录必填 正确单位下的有限数值;心率序列、血压、睡眠不传此字段 无 无
unit HealthUnit 数量/心率/血压必填 必须与指标匹配;睡眠不传 无 见单位表
systolic / diastolic number 血压必填 同次测量的收缩压/舒张压,必须成对且为正数 无 无
samples HealthHeartRateSample[] 心率必填 每项为 time、value;时间严格升序且位于记录内,值为正整数 无 1–10000 项,平台另有约束
stages HealthSleepStage[] 睡眠必填 每项为 startTime、endTime、stage;按时间排序,不交叠 无 inBed / asleep / awake / light / deep / rem / unknown,按平台能力
clientRecordId string 否 本次输入的业务追踪标识,不是幂等键或删除目标 无 无
relationToMeal string 仅血糖可传 测量与进餐的关系,按平台支持填写 unknown unknown / beforeMeal / afterMeal / fasting / general
specimenSource string 仅血糖可传 血糖样本来源,按平台支持填写 unknown unknown / interstitialFluid / capillaryBlood / plasma / serum / tears / wholeBlood

步数和楼层为非负整数,心率和静息心率为正整数,距离、活动能量、基础能量和饮水量为非负数;百分数范围 0–100,身高、体重、去脂体重、血糖、最大摄氧量、呼吸频率、心率变异性、基础代谢率及两侧血压为正数。血糖统一使用 mmol/L;如果输入来自 mg/dL,先由业务确认并转换,插件不会猜测单位。

血压和血糖写入示例中的数值应来自使用者本次录入:

import { writeHealthRecords } from '@/uni_modules/lizhao-health'

function saveBloodPressure(provider, systolic, diastolic, measuredAt) {
  writeHealthRecords({
    provider,
    records: [{ type: 'bloodPressure', startTime: measuredAt, endTime: measuredAt,
      unit: 'mmHg', systolic, diastolic }],
    success() { console.log('血压已保存') },
    fail(error) { console.log('血压未全部保存', error.errMsg) }
  })
}

function saveBloodGlucose(provider, glucoseMmolL, measuredAt) {
  writeHealthRecords({
    provider,
    records: [{ type: 'bloodGlucose', startTime: measuredAt, endTime: measuredAt,
      unit: 'mmol/L', value: glucoseMmolL }],
    success() { console.log('血糖已保存') },
    fail(error) { console.log('血糖未全部保存', error.errMsg) }
  })
}

iOS 每条心率仅写入一个 sample,起止时间都等于该 sample 的测量时间;多点分为多条 records。每条睡眠也仅写一个 stage,时间与记录一致。Health Connect 心率使用正长度区间,睡眠不接受仅表示在床的 inBed。iOS 血糖进餐关系仅支持 unknown / beforeMeal / afterMeal,样本来源仅支持 unknown;不支持的字段值会明确失败。

删除参数

参数 类型 必填 说明 默认值 可选参数
type HealthDataType 是 与原记录类型一致 无 当前服务支持删除的类型
ids string[] 是 查询所得记录 id,或写入成功返回的非空 recordId;1–100 个且不重复 无 不接受 clientRecordId 或时间范围

删除前先取得相应读写权限,并确认能力表的 delete=true。华为 Android 采样接口不提供精确 ID 删除,本插件对此返回不支持。iOS 血压只删除本插件创建且能完整核验的两侧关联记录。

指标、单位与主要返回值

公开 25 项指标;各服务只提供下方能力表中有等价实现的类型。

指标 type 返回单位或内容
步数 stepCount count
通用距离 / 步行跑步距离 / 纯跑步距离 distance / walkingRunningDistance / runningDistance m
楼层 floorsClimbed count
身高 / 体重 / 体脂 height / bodyMass / bodyFatPercentage cm / kg / %
去脂体重 leanBodyMass kg,原始瞬时测量
饮水量 hydration mL,实际饮水区间
活动能量 / 基础能量 activeEnergyBurned / basalEnergyBurned kcal
基础代谢率 basalMetabolicRate kcal/day
心率 / 静息心率 heartRate / restingHeartRate bpm
SDNN / RMSSD 心率变异性 heartRateVariabilitySdnn / heartRateVariabilityRmssd ms
呼吸频率 respiratoryRate breaths/min
最大摄氧量 vo2Max mL/kg/min
血压 bloodPressure systolic、diastolic,mmHg
血糖 bloodGlucose mmol/L
血氧 / 体温 oxygenSaturation / bodyTemperature % / degC
睡眠 sleep 实际起止时间与 stages
运动记录 exerciseSession 实际起止时间与 exercise;无数量单位
字段 类型 说明
provider string 本次实际使用的数据服务
records 记录数组 当前页可见记录
nextPageToken string 或 null 支持分页时继续查询的令牌;null 时不继续请求
hasMore / paginationSupported boolean 当前范围是否还有记录 / 当前服务是否支持继续翻页
id string 记录标识,与 provider 和 type 一起使用
ownData boolean 是否属于本应用写入的记录
value / unit number 或 null / string 数量记录或整段统计的值与单位;空值不自动当作零
source 来源对象 数据来源标识,以及平台允许提供的名称

服务、授权和记录

返回类型 / 字段 说明
HealthCapabilitiesResult.platform / provider / reason 当前平台、选定服务(无法确定为 null)及原因
providers[].provider / status / reason 各服务的可用、未配置、需更新或不适用状态
providers[].historyRead Health Connect 扩展历史功能可用性,与用户授权状态独立
types[].provider / type / read / write / delete / aggregate / pagination / reason 每个服务逐指标能力,aggregate 列出允许的统计方式;显示按钮前检查此表
HealthAuthorizationResult.requestCompleted 授权流程是否完成,不等于全部授权通过
items[].type / readStatus / writeStatus 逐类型读写状态:granted / denied / notDetermined / notObservable / unsupported
HealthAuthorizationResult.historyReadStatus Health Connect 历史读取权限状态,不能代替逐类型读取权限
HealthRecord.startTime / endTime 原始记录时间,不因查询范围截断数值
HealthRecord.systolic / diastolic / partial 血压两侧数值与是否缺失组成部分;缺失侧为 null
HealthRecord.samples / stages 心率带时间的采样点、睡眠阶段;不相关类型返回空数组
HealthRecord.exercise 运动记录的类别、可用距离和活动能量;非运动记录为 null,不含路线坐标
HealthRecord.relationToMeal / specimenSource 血糖元数据,平台没有提供时为 unknown
HealthRecord.source.id / name 来源标识、可提供的名称;名称缺失时为 null
visibility.startTime / endTime / earliestReadableTime / restricted / reason 查询范围与原生服务可确认的限制;不知道最早时间或限制时保持 null

ownData=true 仅表示已确认记录来源属于本应用,不保证该类型可以删除。id 必须与服务、类型一起保存;有些平台返回的是当前应用会话中的原生记录引用,退出应用后需重新查询,不能把它当作长期业务主键。

统计、保存和删除

返回类型 / 字段 说明
HealthAggregateResult.value / unit 整段统计值与单位;无值为 null,不能自动显示为 0
HealthSummaryResult.items 与请求同序的独立摘要结果;单项状态为 success / empty / unsupported / failed
buckets[].startTime / endTime / value 按日的实际时间边界和值;按日模式顶层 value 为 null
operation / sourcePolicy / visibility 实际算法、原生来源处理策略及可读范围;不承诺与所有健康 App 首页完全一致
HealthWriteResult.items[].index / clientRecordId 对应输入数组的位置(从 0 开始)及可选追踪标识
items[].recordId / status / nativeCode / message 原生 ID(可能为 null)、written / failed / unknown、原生错误码和中文摘要
HealthDeleteResult.submittedIds / deletedCount 已提交目标,及系统可确认的删除条数;无法确认时为 null
HealthDiagnosticsResult.platform / provider / providers / reason 环境摘要,不含健康数值、账号、令牌
HealthDiagnosticsResult.guidance 可选的 provider / status / action / title / steps 接入建议;只说明下一步,不自动执行
HealthFail.errSubject / errCode / errMsg / operation / provider / type / nativeCode / items 统一失败信息;errSubject 固定 lizhao-health;部分写入失败通过 items 保留逐项状态

有任一失败或无法确认的写入项时走 fail,不会回调整体成功。应先处理 items;written 项不要再次提交,unknown 项先查询确认,避免重复记录。

错误码说明

errSubject 为 lizhao-health。保留原始错误码与错误说明,再按下表处理。

所有错误的 errSubject 均为 lizhao-health。先按 errCode 处理,再将 errMsg 显示给使用者。

错误码 含义 说明
9097001 平台不支持 当前平台不能使用所选健康服务
9097002 服务不可用 检查设备是否支持、服务是否已安装或需要更新
9097003 应用配置未完成 按所选服务完成应用身份与健康能力配置
9097004 需要选择服务 多个服务可用时明确传 provider
9097005 权限不足 按需申请该类型读写权限,返回后再次检查
9097006 操作不支持 检查当前服务的指标、算法和字段能力
9097007 参数错误 检查单位、时间、字段组合和数量限制
9097008 游标或引用失效 保持翻页条件一致;原生对象引用过期时重新查询
9097009 不能删除该记录 来源不属于本应用、记录不可见或无法完整核验
9097010 原生操作失败 显示错误摘要,可使用诊断接口检查环境
9097011 写入未全部成功 检查 fail.items,避免重写已成功或结果未知项
9097012 操作取消 使用者取消后结束本次流程

示例与平台接入

完整示例按所选健康服务完成平台配置,再通过页面按钮申请权限和读取数据。具体配置见下方平台说明。

注意事项

App 需使用包含当前插件、健康类型、权限和所选服务配置的自定义基座或正式包;修改原生健康类型、权限或依赖后重新原生联编并安装匹配的新包,Harmony 对应重建 HAP。仅更新页面、wgt 或 appResource 不能替换旧包中的原生实现。

支持平台与服务配置

支持范围按原生服务分别提供;设备服务、应用开通和用户授权会影响实际可用性。先用 getHealthCapabilities 判断,再调用所需操作。

平台 是否支持 说明
iOS 13 及以上 HealthKit 查询、写入、自有记录删除、原生统计;不支持明细游标分页
Android Health Connect Health Connect 查询、写入、自有记录删除、原生统计、游标分页;设备条件见下节
华为 Android HMS Health Kit 查询、写入及部分原生统计;不提供采样 ID 删除和续页令牌
HarmonyOS 5 及以上 Health Service Kit 按下表提供查询、单点写入和原生对象删除;不提供本接口定义的时间范围统计
Web / 小程序 不支持真实健康数据访问 提供明确的不支持结果

uni-app 与 uni-app x 使用同名 API;设备实际可用性以 getHealthCapabilities 返回值为准。Android 应用包最低支持 Android 8;各健康服务的系统版本、应用开通与数据来源要求需分别满足,见下节。首次接入需使用包含插件和相应健康能力配置的新原生安装包。

Android 步数接入条件

先区分“读取健康服务中的已有记录”和“由系统采集本机步数”。这些服务条件同样适用于 uni-app Vue2 / Vue3 与 uni-app x,页面语法仍按对应宿主要求使用。

使用目标 设备与服务条件 授权与数据前提
读取 Health Connect 已有步数 Android 9(API 28)及以上,Health Connect 服务实际可用 stepCount 的读取状态为 granted,所需记录已写入该服务并在当前授权和查询范围内可见;只读不要求步数写入权限
由 Health Connect 自动记录本机步数 Android 14(API 34)及以上,且 Android 14 对应的 SDK Extension 版本至少为 20 系统具备可用计步传感器、手机步数记录功能已开启,并有应用获准读取步数;仍须等到系统实际保存记录后才能查询
读取华为健康服务记录 HMS 健康服务可用,并按后文完成应用与账号接入 相应指标读取授权和运动健康关联授权有效,所需记录已同步并向该应用开放

系统扩展版本指运行时 SdkExtensions.getExtensionVersion(34) 的返回值,与 Android 大版本、项目编译 SDK、插件版本分别判断。仅满足 Android 14、服务 available、读取已授权或传感器可见,都不能单独证明 Health Connect 已自动记录本机步数;getHealthCapabilities 的指标支持状态也不是硬件计步或数据已存在的证明。

自动计步的版本门槛不限制读取其他来源已经写入的记录。 使用支持 Health Connect 步数同步的运动应用或穿戴设备时,仍应开启对应数据共享,并确认记录实际进入当前服务。手机、其他健康 App 显示有步数,不代表同一记录已向当前服务开放。

自动计步条件以 Android 官方手机步数说明 为准;服务安装方式见下方常见问题。需要展示今日总步数时使用支持 sum 的统计接口,明细条数和传感器累计值都不能直接当作今日总步数。

各指标能做什么

“读写删”指读取、保存和删除自有记录;“只读”不能保存或删除。“—”表示没有等价实现,会明确报不支持。

指标 iOS Health Connect 华为 Android HarmonyOS
步数 读写删 读写删 读写 只读
通用距离 — 读写删 读写 只读
步行跑步合计距离 读写删 — — 只读,仅系统标为步行或跑步的点
纯跑步距离 只读,跑步训练 — — 只读,仅系统标为跑步的点
身高 / 体重 读写删 读写删 读写 读写删
去脂体重 读写删 读写删,无原生统计 — —
饮水量 读写删、sum 读写删、sum — —
体脂 读写删 读写删 读写 只读
活动能量 读写删 读写删 — —
楼层 读写删 读写删 — —
最大摄氧量 读写删 读写删 读写 —
呼吸频率 读写删 读写删 — —
SDNN 心率变异性 读写删 — — —
RMSSD 心率变异性 — 读写删 — 读写删,API 18 及以上
基础能量 读写删 — — —
基础代谢率 — 读写删 — —
心率 / 静息心率 读写删 读写删 读写 读写删
血压 读写删,删除需完整核验 读写删 读写 读写删
血糖 读写删 读写删 读写 —
血氧 / 体温 读写删 读写删 读写 读写删
睡眠 读写删 读写删 读写 —
运动记录 只读,无路线 只读,无路线 只读,无路线 只读,无路线

统计支持:iOS 的步数、走跑距离、楼层、活动能量、基础能量和饮水量支持 sum,去脂体重等其他可用数量测量支持 average/min/max;Health Connect 的步数、通用距离、楼层、活动能量和饮水量支持 sum,身高、体重、心率和静息心率支持 average/min/max,去脂体重使用明细或 latest 而非统计;华为 Android 的步数、通用距离支持 sum,体重、心率和最大摄氧量支持 average/min/max。基础代谢率、血压、睡眠和运动记录没有公开的单值统计。最终可用算法仍以能力结果中的 aggregate 数组为准。

华为 Android 明细和 latest 摘要的单次范围必须小于 31 × 24 小时(包括运动记录);等于或超过该范围返回参数错误 9097007,请分段查询,不需要重新授权。整段统计最长约 24 天,较长范围可改为按日统计。若原生返回多个独立分组,会明确报不支持,不自行拼成总数。写入血糖的进餐关系仅支持 unknown/general;心率与睡眠每条只写一个测量点或阶段,睡眠仅能写 light/deep/rem/awake。

HarmonyOS 的步数、距离来自日常活动记录,体脂来自体重记录中的体脂字段;这些投影只读,避免写删时影响同条原生记录的其他指标。单点心率的起止时间与采样点时间保持相同。原生记录引用最多保留 1000 条、有效期 10 分钟,应用重启或引用失效后重新查询;查询期间其他来源增删可能使 offset 分页发生重复或遗漏,刷新列表时按当前引用展示,不把它当作固定快照。跑步筛选单次扫描最多 10000 个原生点,超过时缩小查询范围。

HarmonyOS 删除体重时会删除该条原生体重记录,其中附带的体脂等字段也会一起移除。选择删除前应向使用者展示完整目标含义;只想删除体脂数值时不要调用体重删除。

按所选服务完成接入

  • iOS: 在应用标识与签名中启用 HealthKit,按实际用途调整健康数据读取、写入说明。插件附带所需配置,签名必须允许该能力。
  • Health Connect: 设备须有可用 Health Connect,且数据来源已将记录写入该服务。应用需提供自己的健康数据用途和隐私政策说明;可通过 Android manifest 的 lizhao.health.privacyPolicyUrl 设置 HTTPS 隐私政策地址。
  • 华为 Android: 在华为开发者后台完成包名、签名、健康服务及所需数据权限申请。用户还需完成账号和运动健康关联授权。在宿主 Android manifest 的 application 中加入下面两项;已有 AGConnect 官方 App ID 配置时可沿用。
<meta-data android:name="com.huawei.hms.client.appid" android:value="appid=你的华为应用AppID" />
<meta-data android:name="lizhao.health.huawei.enabled" android:value="true" />
  • HarmonyOS: 完成对应应用的健康服务和数据权限申请,在应用的 module.json5 的 metadata 中配置 client_id。使用自己的应用标识,之后由页面按钮发起用户授权。
"metadata": [
  { "name": "client_id", "value": "你的鸿蒙应用Client ID" }
]

华为服务的配置仅填写公开应用标识,插件不需要 App Secret 或私钥。不同地区、设备、服务版本和数据审批结果可能导致部分指标不可用。更多步骤可查看 Apple HealthKit 接入、Health Connect 接入 和 HarmonyOS 健康服务指南。

常见问题

授权流程成功,为什么没有读到记录

授权流程的 success 表示流程返回;Android 还应检查相应指标的实际 readStatus。查询成功但没有可见记录,可能与数据来源、查询时间或可读范围有关,不能据此认定真实步数为 0 或手机缺少计步硬件。iOS 不会向应用明确公开读授权结果,因此空列表不能直接解释为使用者拒绝授权。

Android 已授权但步数为空,应按什么顺序检查

  1. 确认实际 provider,Health Connect 与华为健康分别检查,不会自动合并两者记录;再用 getHealthAuthorizationStatus 确认 stepCount 的 readStatus。只读场景的 writeStatus: denied 不妨碍已有记录读取。
  2. 核对 startTime、endTime 为 Unix 毫秒,日期和时区符合预期。records: [] 只表示当前范围没有可见明细;若 hasMore 为 true,按实际分页结果继续读取。
  3. 在所选服务中确认对应日期的步数条目、来源和同步状态。Health Connect 可在系统设置的“健康连接”“健康数据共享”或“Health Connect”中查找;系统模块可能没有桌面图标,设置搜索未命中也不能证明底层服务不存在。可按 官方 SDK 的管理页面接入说明 从应用进入,实际入口由系统提供。
  4. 需要系统自动记录本机步数时,按上表核对系统扩展和采集条件。传感器可见不代表记录已经保存;直接访问传感器的身体活动权限,与健康库的步数读取权限分别管理。
  5. visibility.restricted: true 表示存在历史可见范围限制,不能直接解释为今天的数据未获授权。按实际时间和授权规则判断;不要为解决近期空记录而盲目申请额外历史权限,也不要把空记录或缺少统计值显示为 0。
  6. 核对实际安装包包含的插件和原生配置是否与当前接入版本一致,按本节开头的原生包说明处理;页面中的版本文字不能证明实际加载的原生模块版本。空数组本身也不能用来判断 Vue2 等宿主框架不兼容。

手机安装“健康数据共享”后,就一定有步数吗

安装服务后仍需实际的数据来源和读取授权。Android 9–13 使用可用的 Health Connect 独立应用;Android 14 及以上由系统模块提供相关接口,向后兼容的独立 APK 不替代系统模块更新。

服务安装、服务可用、数据读取授权、步数采集和数据同步是不同环节。确认上表自动计步条件已满足,或已有支持 Health Connect 同步的数据来源将步数写入,再查询对应时间范围。安装一个管理应用或开放读写权限,不保证自动生成步数。参见 官方接入说明 和 Android 14 迁移说明。

系统扩展版本如何更新

系统扩展通过 Google Play 系统更新或厂商提供的 OTA 更新分发;具体入口、可用更新和版本取决于设备及 ROM。按手机提供的官方入口检查更新,安装并按提示重启后重新检测。已经使用 Android 14,不代表系统扩展已经满足自动计步门槛,也不能仅凭安全补丁日期推算扩展版本。

升级插件、重新打包 App 或修改项目编译 SDK,都不会直接提升手机的系统扩展版本;没有对应更新时,无法由插件保证补齐该系统能力。更新机制见 SDK Extensions 与 Android 模块化系统更新。

需要应用自己计步时,应怎样接入

健康平台查询接口读取所选服务已保存的记录;应用自主记录可使用“安卓本机计步”模块。该模块需要计步传感器、身体活动与通知权限,并通过前台服务记录启用后的可信增量;不能补齐启用前或中断期间的步数,也不保证与微信或健康平台的全天总数一致。

为什么 iOS 权限页只显示一个开关,别人的页面有多个

HealthKit 只展示本次应用实际请求且系统支持的健康类型。只传 stepCount 时通常只出现步数;示例的“申请本页全部读取权限”会先读取当前服务能力,再把全部可读类型放进一次请求。最终显示数量、名称,以及已经选择过的权限是否再次弹出,仍由 iOS 决定,应用不能自定义系统权限页。

SDNN 和 RMSSD 为什么分成两个类型

它们是不同的心率变异性指标,不能互相替代。Apple HealthKit 提供 SDNN,Health Connect 提供 RMSSD;插件分别使用 heartRateVariabilitySdnn 和 heartRateVariabilityRmssd,不做近似换算。

基础能量和基础代谢率有什么区别

basalEnergyBurned 是时间区间内消耗的基础能量,单位 kcal;basalMetabolicRate 是代谢速率,单位 kcal/day。插件不会把累计能量除以时间后冒充基础代谢率。

手机健康 App 有数据,插件为什么读不到

插件读取的是选定服务中已开放并授权的数据。不同厂商健康 App 的私有记录不会自动进入同一个数据服务。

为什么距离统计和跑步页面不一样

通用距离、步行跑步合计和纯跑步距离含义不同。先确认页面使用的 type 与业务要求一致。

为什么不能把多条步数记录直接相加

手机、手表或其他来源可能存在重叠记录。展示总步数优先使用统计接口,并保留其来源与时间范围。

为什么有些历史记录没有返回

系统、服务和授权范围可能限制可读历史。更早没有返回记录不代表数据一定不存在。

  • 只在使用者主动操作时请求需要的健康权限,读取和写入分别申请。
  • 写入真实测量或使用者明确录入的数据;示例页面加载时不自动写入测试记录。
  • 删除只针对本应用写入的指定记录;不提供清空整个手机健康数据库的入口。
  • 不同服务的数据不会自动互相同步,写入成功不代表所有厂商健康 App 都会展示该记录。
  • iOS 需要启用项目 HealthKit 能力并使用匹配签名;华为 Android 与鸿蒙分别完成所选健康服务的应用开通和身份配置。
  • Health Connect 使用的依赖要求 Android 编译 SDK 36 与 AGP 8.9.1 或更高;打包服务也必须满足这些要求,单改 targetSdk 不能解决依赖兼容问题。
  • iOS 深睡、浅睡、REM 写入需要 iOS 16 及以上;不把未知阶段当成已睡。心率和睡眠的读取结构不一定能直接作为同平台的写入结构,请遵循上方保存参数。
  • 健康数据应按业务需要显示和保存,避免把明细、账号或令牌写入公开日志。插件不会自动把各健康服务的数据复制到自己的服务器。

作者系列 UTS 插件

以下为作者已上架的 UTS 插件,详情见各市场页面或作者主页。

插件 能力方向 插件市场
lizhao-app-keepalive 应用保活、唤醒、自愈与报告 查看插件
lizhao-bg-audio 背景音频播放、队列、倍速与事件 查看插件
lizhao-ble BLE 扫描、连接、读写、通知与自动重连 查看插件
lizhao-call-kit 电话、短信、通讯录原生能力 查看插件
lizhao-camera-pro 原生相机、拍照录像、水印与媒体保存 查看插件
lizhao-cast-screen DLNA 投屏、AirPlay 路由入口 查看插件
lizhao-choose-file 原生文件选择、上传、进度与取消 查看插件
lizhao-device-id 设备标识、隐私策略与诊断 查看插件
lizhao-doc-corrector 文档扫描、矫正、增强与识别 查看插件
lizhao-emu-detect 模拟器环境检测、风险评分与证据 查看插件
lizhao-float-window 悬浮窗、画中画、权限与诊断 查看插件
lizhao-gallery-pro 相册媒体分页、筛选、缩略图与导出 查看插件
lizhao-hce-card NFC 虚拟卡、APDU 交互与 NDEF 标签模拟 查看插件
lizhao-health 健康数据授权、查询、统计与写入 查看插件
lizhao-http-server 本地 HTTP 服务、文件传输与实时通信 查看插件
lizhao-icon-pro SVG 图标组件、多主题与缓存 查看插件
lizhao-id-photo 证件照制作、尺寸换算、换底色与模板换装 查看插件
lizhao-img-eraser 图片去水印、局部修复与原生编辑器 查看插件
lizhao-live-activity 实时活动、系统胶囊与普通通知降级 查看插件
lizhao-nfc-pro NFC 标签读写、NDEF、IsoDep 与诊断 查看插件
lizhao-notify-pro 本地通知、点击动作、进度与定时提醒 查看插件
lizhao-novel-reader 原生小说阅读、仿真翻页与段落评论 查看插件
lizhao-office-view Office 与 PDF 文件预览、进度与缓存管理 查看插件
lizhao-pdf-pro PDF 阅读、签批、真实写回与页面处理 查看插件
lizhao-scan-pro 原生扫码、连续扫码、相册识别 查看插件
lizhao-serial-port 路径串口、USB 串口、多会话收发与诊断 查看插件
lizhao-share-plus 系统分享、远程文件下载后分享 查看插件
lizhao-smart-tts 系统 TTS、云端合成、听书方案 查看插件
lizhao-sqlite-pro 原生 SQLite、迁移、备份与诊断 查看插件
lizhao-sse-pro SSE、Line、JSONL 与 Raw 流式请求 查看插件
lizhao-tcp-pro TCP 客户端、服务端、多连接与诊断 查看插件
lizhao-usb-storage U 盘、移动硬盘文件浏览、读写与批量复制 查看插件
lizhao-video-editor 视频裁剪、压缩、取帧与 FFmpeg/FFprobe 查看插件
lizhao-video-feed 短视频上下滑、短剧选集与分页加载 查看插件
lizhao-video-player 原生视频播放器、清晰度与播放交互 查看插件
lizhao-video-thumb 视频封面、批量取帧与 Base64 返回 查看插件
lizhao-vpn-pro 企业 VPN、IKEv2、安全接入与脱敏诊断 查看插件
lizhao-wechat-kit 微信登录、分享、支付、小程序与客服 查看插件

隐私、权限声明

1. 本插件需要申请的系统权限列表:

按需申请各健康数据类型的读取与写入权限;仅显式启用时申请 Health Connect 扩展历史读取;用户主动启用安卓本机计步时申请身体活动与通知权限并使用健康类型前台服务;iOS 需要 HealthKit 能力;Android Health Connect 需要健康权限;华为 Android 与 HarmonyOS 需要对应应用配置、服务开通和用户授权。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

仅按应用调用和用户授权处理选定健康服务的数据。HealthKit、Health Connect 使用系统数据服务;华为服务可能按华为协议同步数据。用户主动启用的安卓本机计步记录保存在本应用内。插件不向自建服务器上传健康记录。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无广告