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

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

现场端(Field Worker):
佩戴 Rokid Glasses,开启摄像头;
手机 App 通过 CXR-M SDK 控制眼镜,并将第一视角视频流推送至云端。
远程端(Remote Expert):
在 Web 或 App 端观看实时视频流;
可进行:文字指令、语音通话、屏幕标注(画圈/箭头)、调用工具(手电筒/拍照)。
眼镜端(Glasses Display):

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

根据 SDK 文档,支持以下组件:

布局容器:
LinearLayout(垂直/水平)
RelativeLayout(相对定位)
基础控件:
TextView:显示文本指令
ImageView:显示标注图标(如箭头、圆圈)
重要限制:
图片需提前上传,分辨率 ≤ 128×128px;
仅绿色通道(#00FF00)在眼镜端可见,其他通道将被忽略。
我们设计一个包含 指令区、标注区、工具状态区 的三层布局:
{
"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"
}
}
]
}
远程专家绘制的“箭头”“圆圈”等标注,需预先转换为 Base64 图片并上传:
// 将本地 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 无法显示。
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)
}
当远程专家发送新指令或标注时,App 生成 更新 JSON 并推送:
// 更新文本指令
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)
}
专家可远程触发眼镜的 手电筒、拍照、录像 功能:
// 开启手电筒(通过控制亮度模拟)
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("录像中...")
}
现场人员可通过 功能键长按 反馈“确认”或“求助”:
// 设置 AI 事件(功能键长按触发 onAiKeyDown)
CxrApi.getInstance().setAiEventListener(object : AiEventListener {
override fun onAiKeyDown() {
// 向远程专家发送“已确认”信号
sendConfirmationToExpert()
// 清除当前指令
updateInstruction(" 操作完成")
}
override fun onAiExit() { /* 退出协作模式 */ }
})
预加载常用图标:将箭头、圆圈、对勾、叉号等 10 个以内图标一次性上传;
避免频繁上传:图标上传是耗时操作,应在会话开始时完成。
防抖处理:若专家快速连续标注,合并为一次 updateCustomView 调用;
增量更新:仅更新变化的控件,避免全量刷新。
协作结束时,务必释放资源:
fun endRemoteAssist() {
CxrApi.getInstance().closeCustomView()
CxrApi.getInstance().setCustomViewListener(null)
CxrApi.getInstance().setAiEventListener(false)
// 可选:恢复默认亮度/音量
}
onOpenFailed:若 JSON 格式错误,眼镜端会回调此方法;
网络中断处理:自动隐藏远程指令,显示“连接中断”提示。
本系统可轻松扩展至更多领域:
医疗手术指导:专家标注手术切口位置;
仓储拣货:系统自动高亮目标货架;
教育培训:叠加操作步骤动画(通过多帧图标切换模拟)。
未来可结合:
空间锚点:实现标注在物理空间中的持久化;
手势识别:现场人员用手势确认/拒绝指令;
多眼镜协同:多位专家同时标注同一场景。
本文完整展示了如何利用 Rokid CXR-M SDK 的自定义页面能力,构建一个高价值的 AR 远程专家协作系统。我们深入实践了:
JSON UI 的设计与动态更新;
绿色通道图标的处理与上传;
远程指令与本地硬件的联动;
用户交互事件的与反馈。
该方案充分发挥了 Rokid Glasses 免手持、第一视角、AR 叠加 的优势,解决了传统远程协作的痛点。开发者可基于此框架,快速定制行业专属解决方案。
让专家“亲临”现场,让知识跨越空间——Rokid CXR-M SDK,助你构建下一代 AR 协作体验。