一间动感单车教室,墙上挂着屏幕,实时显示每位学员所处的心率区间——这类功能,工作室往往要付出不低的代价。通常意味着某家厂商的硬件、某家厂商的应用,再加上按门店收取的月费。
![]()
拆开来看,底层是三道硬集成:实时读取手表或胸带的数据;把读数从手机里足够快地取出来,快到有意义;以及在 iOS 和 Android 两端都跑通——这两个平台把健康数据存放在完全不同的地方。
Codename One 是一个开源框架,用同一套 Java 或 Kotlin 代码库构建原生 iOS、Android、桌面和 Web 应用。Pulse 则是一个工作室模板,上述集成已经做完,放在一个你持有源码的 Java 项目里。会员的手机记录课程,教练的手机显示全场。可以从 Initializr 以 Fitness studio 生成,署你自己的名字和包名,源码采用 MIT-0 许可。
从手腕到墙面
会员签到进入课程时,应用只请求一次权限,随后开启一个采集心率的训练会话。在 iOS 上这是 HealthKit 训练会话,也会把配对的 Apple Watch 纳入进来;在 Android 上是 Health Connect。两端是同一份代码:请求写入训练、读取心率、写入心率的授权,然后以骑行活动类型创建训练配置,启动会话并挂上监听器,再配对胸带。
蓝牙胸带
不少会员用胸带而不是手表训练,胸带本身也更准。市面上每一条胸带都遵循标准的蓝牙心率协议,Pulse 因此扫描该协议、连接找到的第一条,并把它接入同一个训练会话——胸带采集的心跳也就进入了会员自己的健康历史。
自动重连比看上去更重要。有人擦一下胸口,胸带就会掉线一秒,而教练的屏幕不该因此整节课都丢了这个人的数据。
胸带报告每一次心跳;手表经由平台报告的是运行统计值。Pulse 因此对两者分别读取:收到数量样本且类型为心率时,按每分钟次数取整上报;训练统计更新时,则取心率平均值上报。
教练屏幕上的区间
读数被送到工作室后端。服务器只在内存里保留每位会员的最新一条读数,并把它换算成区间:以 220 减去会员年龄为基准,读数占该基准的比例,从 50% 起按五等分划分。区间 1 是热身,区间 5 是全力。教练的手机通过实时通道接收这些区间,全场视图随学员发力而更新,教练能看出谁在划水、谁该收一收。
单条读数从不写入数据库。一条读数只在几秒内有意义;整节训练会被保留,在课程结束时完整送达,同时也会存进会员自己的 HealthKit 或 Health Connect 存储。
读回历史
过往训练——包括其他应用记录的——会喂给会员的进度页面。一条查询在两端通用:按训练类型、最近 14 天、上限 30 条、倒序排列读取样本,再把训练转成到店次数、分钟数和积分。训练变成积分、连续打卡和徽章,朋友之间可以互送鼓励,这也是让人在一月份还愿意回来的那部分。
健康数据是受监管的数据
心率属于健康数据。在欧盟,它是 GDPR 下的特殊类别数据;在美国,视持有方而定可能落入 HIPAA 范围;苹果和谷歌对读取 HealthKit 或 Health Connect 的应用各有规则,包括可以存什么、必须披露什么。Pulse 默认就站在合规这一侧:只请求它用到的类型,并让实时读数不进数据库。实施指南列出了上线前你仍需自己完成的事项,这部分应当和负责隐私政策的人一起读。
工作室的其余部分
健康是这套模板的重点,但 Pulse 是一整个工作室应用。服务器决定账号拥有哪些角色,因此同一份安装在家里是会员应用,在教练手机上就是教练应用。
- 会员可以预约课程、加入候补、把孩子加进家庭账户,并用门禁通行:轮换的二维码让旧截图失效,或者用 NFC 轻触。
- 店主从同一套代码库拿到桌面端:营收、高峰时段、报名不足的课程、即将流失的会员、套餐与定价、营销活动、员工排班,以及带催款阶梯的账单处理。
两条命令试起来
模拟器里没有手表也没有胸带,所以开发后端会把演示心率灌进实时视图。它以开发配置运行,使用内存数据库,短信和推送打印到控制台,支付为模拟。
用指南里的演示账号分别登录店主、教练、前台三个角色,就能看到各自的界面。用户指南走遍每个屏幕,实施指南则解释账单、门禁、健康,以及要改成你自己工作室的应用需要动哪些地方。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.