如何在AR Core中实现持久化AR会话,可保存环境信息、锚点及虚拟元素?
ARCore 跨会话持久化AR场景实现方案
前置依赖
需要使用ARCore SDK 1.24及以上版本,项目配置满足以下要求:
- targetSdkVersion ≥ 24
- AndroidManifest中正确声明相机权限、AR Core依赖项(可根据需求设置为必填或可选)
实现步骤
1. 环境感知数据的保存与恢复
ARCore自带录制回放API可直接保存环境特征点、相机帧等感知信息,无需手动处理原始数据:
- 保存环境数据:会话正常运行且处于跟踪状态时,调用
session.startRecording(recordingConfig)将环境数据写入本地MP4文件,结束录制时调用session.stopRecording() - 恢复环境数据:下次启动AR会话前,调用
session.setPlaybackDataset(本地文件路径)加载已保存的环境数据集,可跳过重新扫描环境的流程
注意:录制时需保证环境光照充足、纹理特征丰富,弱光或纯白/纯黑无纹理区域会大幅降低后续恢复成功率
2. AR锚点的持久化存储与加载
如果仅需单设备本地使用,优先选择本地持久化锚点方案,实现逻辑如下:
// 初始化会话时开启持久化锚点支持 val config = Config(session) config.persistentAnchorEnabled = true session.configure(config)
- 保存锚点:确认创建的普通锚点处于稳定跟踪状态后,调用锚点的
store()方法获取唯一字符串ID,将该ID存入本地存储(SharedPreferences、本地数据库均可)
val stableAnchor = session.createAnchor(targetPose) val anchorId = stableAnchor.store() // 绑定虚拟元素ID,存入本地 sharedPref.edit().putString("anchor_${virtualElement.id}", anchorId).apply()
- 加载锚点:恢复会话并加载完环境数据后,通过保存的ID调用
session.loadAnchor(anchorId)恢复锚点,若返回锚点的跟踪状态为TRACKING即可正常使用
val savedAnchorId = sharedPref.getString("anchor_${virtualElement.id}", null) savedAnchorId?.let { val restoredAnchor = session.loadAnchor(it) if (restoredAnchor.trackingState == TrackingState.TRACKING) { // 渲染绑定的虚拟元素 renderElement(restoredAnchor.pose, virtualElement) } }
如果需要多设备共享同一场景的锚点,可使用云锚点方案:锚点稳定后调用hostCloudAnchor(anchor)上传锚点获取云锚点ID,后续通过resolveCloudAnchor(云锚点ID)即可恢复。
3. 虚拟元素的持久化
ARCore仅负责锚点的持久化,自定义虚拟元素的属性需要自行存储:
- 每个虚拟元素绑定对应锚点的ID,将虚拟元素的资源ID、相对于锚点的位置/旋转/缩放参数、自定义属性(颜色、文本内容等)序列化为JSON或存入本地SQLite数据库
- 会话恢复时,先加载对应锚点,再读取该锚点绑定的虚拟元素属性,按参数渲染到锚点对应位置即可
常见问题处理
- 锚点恢复失败:若加载的锚点跟踪状态为
STOPPED,说明当前物理环境与保存时差异过大,引导用户扫描之前保存的场景区域即可自动恢复跟踪 - 数据失效:若物理环境发生较大变动(如家具移位、大面积装修),之前保存的环境数据与锚点都会失效,需要引导用户重新录制环境、创建锚点保存
内容的提问来源于stack exchange,提问作者Rafael Ladeia
相关产品推荐
相关产品推荐

