超视距遥操(Teleop)示例 · Android
超视距遥操(Teleop)示例 · Android
⚠️ 尚未上线:本能力为 v1.5.0-SNAPSHOT 开发中特性,接口与协议可能调整,正式发布前请勿用于生产环境。
v1.5.0 新增。本页给出 Android 端只调用 AgentSDK 公开接口的最小遥操示例,展示
enter → startAudio → appendAudioDelta → doneAudio → exit全流程。API 与 Java v1.5.0 · 遥操示例 完全一致,此处按 Android 惯例(Activity + 运行时权限 + 主线程回调切换)改写。视频拉流不属于 AgentSDK,见 遥操指南 · 视频拉流与拉流授权。
权限
xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
RECORD_AUDIO 是危险权限,首次 startAudio 前需 ActivityCompat.requestPermissions 申请。
最小示例
java
import com.agibot.aiem.sdk.AgentAuthCallback;
import com.agibot.aiem.sdk.AgentParam;
import com.agibot.aiem.sdk.AgentSdk;
import com.agibot.aiem.sdk.IdGenerator;
import com.agibot.aiem.sdk.teleop.TeleopEnterCallback;
import com.agibot.aiem.sdk.teleop.TeleopExitCallback;
import com.agibot.aiem.sdk.teleop.TeleopRequest;
public class TeleopDemo {
private static final String URL = "wss://open.agibot.com/api/V1/open-portal/app/wss/agent-sdk";
private static final String APP_ID = "<灵心开放平台应用 appId>";
private static final String APP_KEY = "<灵心开放平台应用 appKey>";
private static final String APP_SECRET = "<灵心开放平台应用 appSecret>";
private static final String AGENT_ID = "<目标机器人 agentId>";
private AgentSdk agentSdk;
private TeleopRequest teleopRequest;
private String audioEventId;
// 1. 创建 SDK + 注册鉴权 + 初始化
void connect() {
agentSdk = AgentSdk.create(URL, APP_ID, APP_KEY, APP_SECRET);
agentSdk.registerAuth(new AgentAuthCallback() {
@Override
public void onAuthState(String appId, int code, String msg) {
// code == 0 后才可 enter(回调在非 UI 线程)
}
});
agentSdk.initialize();
}
// 2. 注册遥操会话 + 进入
void enter() {
String teleopId = IdGenerator.generateTeleopId();
teleopRequest = new TeleopRequest(agentSdk, AGENT_ID, teleopId);
agentSdk.registerTeleop(teleopRequest);
AgentParam enterParam = AgentParam.create();
teleopRequest.enter(enterParam, new TeleopEnterCallback() {
@Override
public void onEnterAck(String teleopId, String eventId, int code, String msg) {
// code == 0 成功;-1 服务端拒绝;1000 本地连接已关闭
// 需要更新 UI 请 runOnUiThread / Handler.post
}
}, 2000);
}
// 3. 开麦:每段讲话一次 startAudio,拿到 eventId
void startTalking() {
AgentParam startParam = AgentParam.create()
.setString("role", "male") // male / female
.setInteger("threshold", 0); // -14 ~ 14
audioEventId = teleopRequest.startAudio(startParam);
}
// 4. 推流:麦克风回调里每 20ms 一片,base64 后 append
void onPcmFrame(byte[] pcm20ms) { // 640 bytes @16kHz mono s16le
String base64 = android.util.Base64.encodeToString(pcm20ms, android.util.Base64.NO_WRAP);
teleopRequest.appendAudioDelta(audioEventId, base64);
}
// 5. 关麦(结束一段讲话,不退出遥操)
void stopTalking() {
teleopRequest.doneAudio(audioEventId);
}
// 6. 退出 + 释放
void exit() {
teleopRequest.exit(new TeleopExitCallback() {
@Override
public void onExitAck(String teleopId, String eventId, int code, String msg) {
agentSdk.unregisterTeleop(teleopId);
}
}, 2000);
}
}
定时探活(keepalive)
enter 拿到 code == 0 后,业务侧应每 10 秒探活一次;onKeepaliveAck 收到 code != 0 即视为机器人离线,需停止定时、退出遥操、注销资源。Android 侧用 Handler + postDelayed 最自然:
java
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private final AtomicBoolean robotOnline = new AtomicBoolean(true);
private Runnable keepaliveTick;
void startKeepAlive() {
keepaliveTick = () -> {
if (!robotOnline.get()) return;
teleopRequest.keepalive(new TeleopKeepaliveCallback() {
@Override
public void onKeepaliveAck(String teleopId, String eventId, int code, String msg) {
if (code == 0) { // 在线,安排下一轮
mainHandler.postDelayed(keepaliveTick, 10_000);
return;
}
if (!robotOnline.compareAndSet(true, false)) return;
mainHandler.removeCallbacks(keepaliveTick); // 离线:停止定时 + 退出
teleopRequest.exit(new TeleopExitCallback() {
@Override
public void onExitAck(String teleopId, String eventId, int code, String msg) {
agentSdk.unregisterTeleop(teleopId);
}
}, 2000);
}
}, 2000);
};
mainHandler.postDelayed(keepaliveTick, 10_000);
}
主动 exit 后也应 mainHandler.removeCallbacks(keepaliveTick) 停止探活。
回调线程:
onEnterAck/onKeepaliveAck/onExitAck均在 SDK 消息分发线程(非 UI 线程)回调,更新界面请切回主线程。
常见改写要点
| 想做 | 改哪里 |
|---|---|
| 一次遥操中多次讲话 | 每段重新 startAudio(startParam) 拿新 eventId,appendAudioDelta / doneAudio 用该 eventId;无需 exit 再 enter |
| 切换音色 / 灵敏度 | 每段 startAudio 时重填 AgentParam 的 role / threshold;不影响前一段 |
| 中途取消遥操 | 直接 exit(...),不再补 doneAudio |
| 感知鉴权 / 断连 | 在 AgentAuthCallback.onAuthState 维护 authed 标志,enter 前 double-check;或在 onEnterAck 收到 code == 1000 后等重连 |
| 多机器人同时遥操 | 每个 agentId 建一个 TeleopRequest;SDK 按 teleopId 索引,互不冲突 |
| 叠加视频拉流 | 见 遥操指南 · 视频拉流与拉流授权(拉流由第三方 WebRTC SDK 承担,不属于 AgentSDK) |