摘要:本文深入剖析 Rokid CXR-M SDK 的 自定义页面(Custom View) 能力,设计并实现一套面向工业、医疗、运维等领域的 AR 远程专家协作系统。通过手机 App 与 Rokid Glasses 的深度协同,现场人员可实时共享第一视角画面,远程专家则能在手机端绘制标注、发送指令、调用工具,所有操作均以 动态 UI 形式渲染于眼镜端,实现"所见即所得"的沉浸式协作。文章涵盖 JSON UI 设计、图标上传、动态更新、事件监听等全流程,并提供完整代码示例与性能优化建议。

一、引言:为什么需要 AR 远程协作?
在工业巡检、设备维修、医疗会诊等高专业度场景中,现场人员常面临复杂问题,亟需远程专家指导。传统方式(电话、视频通话)存在严重信息不对称:
-
专家看不见现场细节;
-
口头描述易产生歧义;
-
无法精准标注操作位置。
Rokid 智能眼镜凭借 第一视角摄像头 + 透明显示 的特性,天然适合此类场景。而 CXR-M SDK 的自定义页面(Custom View) 功能,更是让开发者无需编写眼镜端原生代码,即可在眼镜上动态渲染远程专家的指令、标注、工具面板,实现真正的 "AR 增强协作"。

二、系统架构与核心流程
2.1 整体架构
-
现场端(Field Worker):
-
佩戴 Rokid Glasses,开启摄像头;
-
手机 App 通过 CXR-M SDK 控制眼镜,并将第一视角视频流推送至云端。
-
-
远程端(Remote Expert):
-
在 Web 或 App 端观看实时视频流;
-
可进行:文字指令、语音通话、屏幕标注(画圈/箭头)、调用工具(手电筒/拍照)。
-
-
眼镜端(Glasses Display):
- 实时渲染远程专家发送的所有指令与标注,叠加于真实视野之上。

✅ 关键创新:所有远程交互内容,均由手机 App 通过 CXR-M SDK 的 Custom View 转化为眼镜端 UI,实现低延迟、高保真的 AR 叠加。
三、自定义页面(Custom View)深度解析
CXR-M SDK 的 openCustomView()
、updateCustomView()
等接口,允许开发者用 JSON 描述 UI,并在眼镜端动态渲染。这是本系统的核心。

3.1 支持的布局与控件
根据 SDK 文档,支持以下组件:

-
布局容器:
-
LinearLayout
(垂直/水平) -
RelativeLayout
(相对定位)
-
-
基础控件:
-
TextView
:显示文本指令 -
ImageView
:显示标注图标(如箭头、圆圈)
-
📏 重要限制:
-
图片需提前上传,分辨率 ≤ 128×128px;
-
仅绿色通道(#00FF00)在眼镜端可见,其他通道将被忽略。
3.2 初始化 JSON 结构设计
我们设计一个包含 指令区、标注区、工具状态区 的三层布局:
json
{
"type": "RelativeLayout",
"props": {
"layout_width": "match_parent",
"layout_height": "match_parent",
"backgroundColor": "#00000000"
},
"children": [
{
"type": "TextView",
"props": {
"id": "instruction",
"layout_width": "wrap_content",
"layout_height": "wrap_content",
"layout_centerHorizontal": "true",
"layout_marginTop": "50dp",
"text": "请检查阀门A",
"textSize": "18sp",
"textColor": "#FF00FF00"
}
},
{
"type": "ImageView",
"props": {
"id": "annotation",
"layout_width": "80dp",
"layout_height": "80dp",
"name": "arrow_right",
"layout_centerInParent": "true"
}
},
{
"type": "TextView",
"props": {
"id": "tool_status",
"layout_width": "wrap_content",
"layout_height": "wrap_content",
"layout_alignParentBottom": "true",
"layout_centerHorizontal": "true",
"layout_marginBottom": "30dp",
"text": "💡手电筒已开启",
"textSize": "14sp",
"textColor": "#FF00FF00"
}
}
]
}
3.3 图标资源准备与上传
远程专家绘制的"箭头""圆圈"等标注,需预先转换为 Base64 图片并上传:
scss
// 将本地 PNG 转为 Base64(仅保留绿色通道)
fun loadIconAsBase64(context: Context, resId: Int): String {
val bitmap = BitmapFactory.decodeResource(context.resources, resId)
val greenOnly = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(greenOnly)
val paint = Paint().apply {
colorFilter = LightingColorFilter(0x00FF00, 0x000000) // 仅保留绿色通道
}
canvas.drawBitmap(bitmap, 0f, 0f, paint)
val stream = ByteArrayOutputStream()
greenOnly.compress(Bitmap.CompressFormat.PNG, 100, stream)
return Base64.encodeToString(stream.toByteArray(), Base64.DEFAULT)
}
// 上传图标
val arrowIcon = IconInfo("arrow_right", loadIconAsBase64(context, R.drawable.arrow_right))
val circleIcon = IconInfo("circle", loadIconAsBase64(context, R.drawable.circle))
CxrApi.getInstance().sendCustomViewIcons(listOf(arrowIcon, circleIcon))
⚠️ 注意:图标上传需在 openCustomView()
之前完成,否则 ImageView 无法显示。
四、核心功能实现
4.1 启动自定义页面
scss
fun startRemoteAssist() {
// 1. 确保蓝牙已连接
if (!CxrApi.getInstance().isBluetoothConnected) return
// 2. 上传图标
uploadIcons()
// 3. 打开自定义页面
val initJson = loadJsonFromAsset("remote_assist_init.json")
CxrApi.getInstance().openCustomView(initJson)
// 4. 监听页面状态
CxrApi.getInstance().setCustomViewListener(customViewListener)
}
4.2 动态更新指令与标注
当远程专家发送新指令或标注时,App 生成 更新 JSON 并推送:
arduino
// 更新文本指令
fun updateInstruction(text: String) {
val updateJson = """
[
{
"action": "update",
"id": "instruction",
"props": { "text": "$text" }
}
]
""".trimIndent()
CxrApi.getInstance().updateCustomView(updateJson)
}
// 更新标注图标(如从箭头变为圆圈)
fun updateAnnotation(iconName: String) {
val updateJson = """
[
{
"action": "update",
"id": "annotation",
"props": { "name": "$iconName" }
}
]
""".trimIndent()
CxrApi.getInstance().updateCustomView(updateJson)
}
4.3 远程控制眼镜功能
专家可远程触发眼镜的 手电筒、拍照、录像 功能:
kotlin
// 开启手电筒(通过控制亮度模拟)
fun turnOnFlashlight() {
CxrApi.getInstance().setGlassBrightness(15) // 最高亮度
updateToolStatus("💡手电筒已开启")
}
// 触发拍照
fun triggerPhoto() {
CxrApi.getInstance().takeGlassPhoto(1920, 1080, 80, photoCallback)
updateToolStatus("📸已拍照")
}
// 开启录像
fun startRecording() {
CxrApi.getInstance().controlScene(CxrSceneType.VIDEO_RECORD, true, null)
updateToolStatus("🎥录像中...")
}
4.4 监听用户交互事件
现场人员可通过 功能键长按 反馈"确认"或"求助":
kotlin
// 设置 AI 事件监听(功能键长按触发 onAiKeyDown)
CxrApi.getInstance().setAiEventListener(object : AiEventListener {
override fun onAiKeyDown() {
// 向远程专家发送"已确认"信号
sendConfirmationToExpert()
// 清除当前指令
updateInstruction("✅ 操作完成")
}
override fun onAiExit() { /* 退出协作模式 */ }
})
五、性能优化与最佳实践
5.1 图标管理策略
-
预加载常用图标:将箭头、圆圈、对勾、叉号等 10 个以内图标一次性上传;
-
避免频繁上传:图标上传是耗时操作,应在会话开始时完成。
5.2 UI 更新频率控制
-
防抖处理:若专家快速连续标注,合并为一次
updateCustomView
调用; -
增量更新:仅更新变化的控件,避免全量刷新。
5.3 资源释放
协作结束时,务必释放资源:
kotlin
fun endRemoteAssist() {
CxrApi.getInstance().closeCustomView()
CxrApi.getInstance().setCustomViewListener(null)
CxrApi.getInstance().setAiEventListener(false)
// 可选:恢复默认亮度/音量
}
5.4 错误处理
-
监听
onOpenFailed
:若 JSON 格式错误,眼镜端会回调此方法; -
网络中断处理:自动隐藏远程指令,显示"连接中断"提示。
六、扩展场景与未来展望
本系统可轻松扩展至更多领域:
-
医疗手术指导:专家标注手术切口位置;
-
仓储拣货:系统自动高亮目标货架;
-
教育培训:叠加操作步骤动画(通过多帧图标切换模拟)。
未来可结合:
-
空间锚点:实现标注在物理空间中的持久化;
-
手势识别:现场人员用手势确认/拒绝指令;
-
多眼镜协同:多位专家同时标注同一场景。
七、总结
本文完整展示了如何利用 Rokid CXR-M SDK 的自定义页面能力,构建一个高价值的 AR 远程专家协作系统。我们深入实践了:
-
JSON UI 的设计与动态更新;
-
绿色通道图标的处理与上传;
-
远程指令与本地硬件的联动;
-
用户交互事件的监听与反馈。
该方案充分发挥了 Rokid Glasses 免手持、第一视角、AR 叠加 的优势,解决了传统远程协作的痛点。开发者可基于此框架,快速定制行业专属解决方案。
让专家"亲临"现场,让知识跨越空间------Rokid CXR-M SDK,助你构建下一代 AR 协作体验。