跳转至

接口参考

本页记录当前语音助手向设备内应用开放的 gRPC 与用户信息 Provider,以及维护者使用的内部业务事件。字段以当前源码为准;内部 ChatEvent 不是稳定的跨进程 JSON 协议。

集成顺序和运行边界见 Omni 接入,业务能力见业务能力

接口位置与数据流

契约 工程中的定位路径
Omni Proto core/grpc-server/src/main/proto/OmniAgentProto.proto
用户信息字段 data/src/main/java/com/jidouauto/voiceassistant/data/provider/user/UserSessionContract.kt
内部业务事件 domain/src/main/java/com/jidouauto/voiceassistant/domain/dialogue/entity/ChatEvent.kt

以上是工程内的代码定位路径,公开文档站不包含 Android 源码。使用 Proto 时从配套工程版本取得文件,并与 Launcher 端协商同步。

flowchart LR
    SDK[SDK 与后端结果] --> Event[ChatEvent]
    Event --> Broadcast[GrpcEventBroadcaster]
    Event --> Dispatch[AppCtrlDispatcher]
    Broadcast --> Push[ServerPushMessage / ToolsConfirmToast]
    Dispatch --> Ctrl[AppCtrlRequest]
    Push --> Launcher[Omni Launcher]
    Ctrl --> Launcher
    Launcher --> Reply[AppCtrlResponse]
    Account[登录会话存储] --> Provider[UserProvider]
    Provider --> App[设备内接入应用]

Omni RPC 一览

包名为 omniagent,Java 包为 com.jidouauto.omni.agent.grpc,使用 proto3,服务名称为 OmniAgentService

RPC 请求 → 响应 当前用途
StartOmniAgent EmptySimpleResponse 更新内部运行标记
StopOmniAgent EmptySimpleResponse 更新内部停止标记
QueryOmniAgentStatus EmptyAgentStatusResponse 查询内部 Agent 状态
SubscribeServerStream StreamSubscription → 流式 ServerPushMessage 接收文本、UI 状态、心跳等
ToastStream 流式 ConfirmResponse → 流式 ToolsConfirmToast 通知/确认与动作卡片
AppCtrl 流式 AppCtrlResponse → 流式 AppCtrlRequest 应用控制与回执
SyncDemoMode DemoModeRequestSimpleResponse 当前记录模式参数,尚未实际切换

SimpleResponse 包含 successmsg_stringerror_code。Start/Stop 正常成功时错误码为 0,控制器返回失败时为 1,RPC 捕获异常时为 -1。这些方法成功不代表真实语音会话已经启动或停止。

AgentStatusResponse 包含 status 和毫秒时间戳 timestamp;查询异常时返回 AGENT_STATUS_UNKNOWN。当前服务端构造的消息时间戳采用 System.currentTimeMillis()

订阅与推送

StreamSubscription 字段 Proto 类型 当前语义
client_id string 稳定客户端标识,空值自动生成
subscribed_types repeated StreamType 协议约定空列表订阅全部;当前实现未过滤
max_reconnect_attempts optional int32 已定义,当前服务端未使用
heartbeat_interval optional int32 协议单位秒,当前服务端固定 30 秒

ServerPushMessage 使用 oneof message_type,一次只携带一种消息;外层还有 timestamp = 10message_id = 11

oneof 字段 编号 类型与用途
chat_text 1 ChatTextStream,用户或 AI 文本
tts_audio 2 TTSAudioStream,PCM;当前关闭推送
tts_event 3 TTSCtrlEvent,播控事件
cabin_tags 4 CabinTags,JSON 标签;协议已定义
heartbeat 5 Heartbeat,含 timestampclient_id
error 6 StreamError
vad_event 7 VADEvent,协议保留的辅助事件
agent_status 8 AgentStatus,内部状态
assistant_state 12 AssistantState,Launcher UI 状态

StreamType 编号为 CHAT_TEXT=0TTS_AUDIO=1TTS_CONTROL=2CABIN_TAGS=3VAD_EVENT=4AGENT_STATUS=5ASSISTANT_STATE=7;不要自行把编号间隙补齐。

AssistantState 依次为 IDLE 0、LISTENING 1、THINKING 2、SPEAKING 3,完整枚举名带 ASSISTANT_STATE_ 前缀。AgentStatus 依次为 UNKNOWN 0、RUNNING 1、STOPPED 2、THINKING 3、REJECTED 4、BUSY 5、WORKING 6,前缀为 AGENT_STATUS_

文本、音频与错误

消息 关键字段
ChatTextStream typetextchat_idmessage_idis_finalsequence
TTSAudioStream pcm_datasample_ratechannelsbits_per_sampleis_last_chunkchunk_index
StreamError error_codeerror_messagestream_typemessage_idshould_reconnect

文本角色为 CHAT_TEXT_TYPE_AI=0CHAT_TEXT_TYPE_USER=1sequence 当前保留,不能依赖它排序。外层消息标识和文本内层消息标识是两个字段,客户端不能假设每个增量都有不同标识。

TTSCtrlEvent 为 START 0、STOP 1、PAUSE 2、RESUME 3,前缀为 TTS_CTRL_。PCM 字段存在不等于当前有音频推送;本地语音助手是当前播报端。

当前业务错误广播设置通用提示和 should_reconnect=true;其他错误字段未完整赋值。不要把默认 error_code=0 当成“没有错误”,应先检查 oneof 是否为 error,也不要将业务错误直接当作长连接必须永久终止的信号。

AppCtrl 与通知字段

AppCtrlRequest 包含 app_idrequest_idcommandparameters,并在 text_inputbinary_datajson_data 中通过 oneof 选择一种负载。当前调度主要使用 APP_CTRL_STARTAPP_CTRL_INPUT

AppCtrlCommand 编号
APP_CTRL_START 0
APP_CTRL_STOP 1
APP_CTRL_RESTART 2
APP_CTRL_INPUT 3
APP_CTRL_GET_STATE 4

AppCtrlResponse 包含 typerequest_idapp_idsuccessmessagedata。类型为 APP_CTRL_RSP_BY_REQ=0APP_CTRL_RSP_BY_APP_STATE_CHANGED=1APP_CTRL_RSP_BY_APP_MSG=2。按请求回执必须携带原 request_id

ToolsConfirmToast 的通用字段包括工具类型、通知类型、toast_idtimeout_mstitlemessagechoicesdefault_choice_index、确认/取消按钮文字、icon_urlextraselicitation_ui_json_str

ConfirmResponsetoast_id 关联通知,携带 confirmedresponse_timeselected_optionuser_inputextras。协议定义了确认回执通道;当前主要业务动作卡片为 NOTIFY,不能据此假定所有交互式确认均已完成业务闭环。

ToastType 包含 OK_ONLY、OK_CANCEL、NOTIFY、CHOICE、INPUT、ELICITATION,编号依次为 0..5,前缀为 TOAST_TYPE_。具体卡片扩展字段和导航回执示例见 Omni 接入

用户登录信息 Provider

Provider 是只读查询入口,当前没有提供跨应用登录、登出或令牌刷新接口。

项目 当前值
Authority com.jidouauto.voiceassistant.provider
查询 URI content://com.jidouauto.voiceassistant.provider/user/current
MIME vnd.android.cursor.item/vnd.tech.jidouauto.current_user
user_id 字符串,来自登录结果 relateSign
user_phone 字符串,来自登录结果 userMobile
已登录结果 存在登录结果且 accessToken 非空时,返回一行
未登录结果 返回包含列定义的空 Cursor

权限与返回值

当前主 Manifest 将 Provider 设置为 exported=true,未声明专用 readPermission。历史资料中的 READ_USER_SESSION 是条件性接入示例,不是当前必需权限。Provider 不返回 access token;调用方也不要将空 Cursor 当成网络或权限错误。

当前 query() 不使用传入的 projection、selection 或 sortOrder,始终返回两列。未知 URI 抛出 IllegalArgumentExceptioninsert() 返回 nullupdate()delete() 返回 0,不会修改登录态。

Android 接入示例

Android 11 及以上,在接入方 Manifest 中声明 Provider 可见性:

<queries>
    <provider android:authorities="com.jidouauto.voiceassistant.provider" />
</queries>

以下函数应在 IO 线程调用;无用户返回 null,Provider 不可用或权限错误向上抛出,由调用方呈现读取失败。

data class CurrentUser(val userId: String, val userPhone: String)

fun queryCurrentUser(resolver: ContentResolver): CurrentUser? {
    val uri = Uri.parse(
        "content://com.jidouauto.voiceassistant.provider/user/current",
    )
    val cursor = checkNotNull(resolver.query(uri, null, null, null, null)) {
        "用户信息 Provider 不可用"
    }
    return cursor.use {
        if (!it.moveToFirst()) return@use null
        CurrentUser(
            userId = it.getString(it.getColumnIndexOrThrow("user_id")),
            userPhone = it.getString(it.getColumnIndexOrThrow("user_phone")),
        )
    }
}

在所需生命周期内注册 ContentObserver,监听查询 URI,或监听 authority 根 URI 并设置 notifyForDescendants=true。回调仅通知数据变化,收到后重新在 IO 线程查询;在生命周期结束时注销。

UserSessionStore.saveLoginResult()updateAccessToken()clearSession() 在同步持久化数据后通知查询 URI。不要仅监听前台页面,否则切到登录页时注销观察者可能错过变更;多用户车机应确保双方位于同一 Android user。

验证与故障定位

adb shell am get-current-user
adb shell content query --user current --uri content://com.jidouauto.voiceassistant.provider/user/current

查询可能输出真实用户信息,只在授权测试设备执行,不要将输出原样放入公开问题、文档或截图。公开验证记录仅保留“零行/一行”和列名。

现象 应检查的事实
找不到 Provider 安装状态、authority、包可见性、Android user
返回空 Cursor 是否存在已保存登录结果且 token 非空
能查询但页面不更新 Observer 生命周期、监听 URI、登录态保存/清除通知
安全异常 当前设备实际安装包的合并 Manifest 与调用方权限

内部业务事件

ChatEvent.Business.Result 包含 processTypemessagedataidfunctionNameshowOnUipendingCommands

  • processType 决定业务处理路径;data 是内部对象,当前类型为 Any?,不能直接当成固定对外 JSON。
  • showOnUi=false 控制业务结果文字展示,不表示无需执行命令,也不表示必须禁止动作卡片。
  • pendingCommands 承载后续执行的命令,实际执行时机由调度器的业务分支决定。
  • StreamingDelta.incrementalContent 是增量文本;fullMessage 为可选完整文本,当前 gRPC 广播使用增量字段。
  • GRPC_NOTIFYcommand_result 是内部调度完成信号,不是支付、导航或车控成功凭证。

验证接口变更时至少覆盖 Proto 编解码、文本 final 更新、AppCtrl 原标识回执与超时、Provider 空行与登录通知。更多场景见调试与维护