我如何使用 WebRTC 和 Kotlin 构建了一个无服务器、P2P 家长控制应用
Source: Dev.to
简介
作为一名父母兼 Android 开发者,我想在不涉及商业家长控制应用隐私问题的前提下,监控孩子在 TikTok 和 YouTube 上的活动。
几乎所有商业方案的工作方式都相同:
- 收集孩子的数据(位置、历史、应用使用情况)。
- 将所有数据上传到集中式云数据库。
- 在父母的手机上显示。
我不想让孩子的位置信息历史存放在第三方服务器上,于是我使用 Kotlin、Jetpack Compose 和 WebRTC 构建了 SafeStream——一个完全无服务器、点对点的监控系统。
架构:“无后端”方案
核心思路很简单:父母设备充当服务器。数据直接从 设备 A(孩子) 流向 设备 B(父母),中间不进行持久化。
- Guardian App(孩子) – 运行后台服务,本地收集数据并充当 WebRTC 对等方。
- Parent App – 充当观看端对等方,直接接收 JSON 负载并存入本地 Room(SQLite)数据库。
- 信令 – 仅使用 Firebase Realtime Database 进行握手(SDP Offer/Answer 交换)。用户数据不触碰 Firebase。
技术栈
| 组件 | 技术 |
|---|---|
| 语言 | 100 % Kotlin |
| UI | Jetpack Compose(Material 3) – 现代 “Reel‑like” 信息流 |
| P2P | Google 的 WebRTC 库,封装在自定义 WebRTCConnectionManager 中 |
| 穿透 | STUN/TURN 服务器,用于绕过 NAT 和防火墙(4G/5G 环境必需) |
| 加密 | 基于 WebRTC 的 DTLS 之上使用 AES‑256‑GCM(安全等级:高) |
关键技术挑战
1. 提取视频元数据(伦理黑客)
TikTok 和 YouTube 并未提供观看历史的 API。我实现了一个 Accessibility Service(GuardianAccessibilityService.kt),用于扫描 UI 层级:
- 检测用户是否处于视频应用(
com.zhiliaoapp.musically或com.google.android.youtube)。 - 抓取可见视图的
contentDescription或文本,以提取视频标题和频道。
优化: 逻辑经过大量防抖,仅在屏幕内容变化时运行,最大限度降低电池消耗。
2. 后台的 WebRTC 握手
在现代 Android 上保持后台 WebRTC 连接活跃非常困难,因为 Doze 模式和 App Standby Buckets 的限制。
解决方案:
- 使用前台服务并显示持久通知,以保持连接存活。
- 按需开启: 父母端发送高优先级 FCM(Firebase Cloud Message)“唤醒”孩子设备,随后孩子设备发起 WebRTC 信令流程。
3. 点对点传输图片
高分辨率截图会超过 WebRTC 的安全消息大小限制(约 16 KB)。我编写了分块算法:
- 将
Bitmap压缩为 WebP。 - 将二进制数据拆分为小包。
- 通过 DataChannel 按顺序发送这些包。
- 在父母端重新组装。
商业模式(独立开发者现实)
SafeStream 免费发布,但运行 TURN 服务器(带宽中继)会产生费用。为在不采用订阅或出售数据的情况下保持可持续,我引入了 积分系统:
- 文本日志和实时位置免费(低带宽)。
- 下载高分辨率截图会消耗 “积分”。
- 用户每天可获得免费积分,或观看奖励型 AdMob 广告来补充积分,以覆盖 TURN 带宽费用。
接下来计划
我将在下周启动公开 Beta,并征求关于不同网络运营商(尤其是 CGNAT)下 P2P 稳定性的反馈。
如果你对 P2P 实现感兴趣或想亲自测试,请前往这里查看: SafeStream Guardian Architecture – beta subscription
祝编码愉快! 🚀