Harmony ADK 集成文档
第一章:环境要求
1.1 系统与工具
类别 | 最低版本 | 推荐版本 |
HarmonyOS | 5.0(API 12) | 5.0(API 12) |
DevEco Studio | 5.0 | 5.0 Release |
ohpm | 1.5.0 | 最新稳定版 |
Node.js | 16 | 18+ |
1.2 依赖库
依赖包 | 版本 | 用途 | 是否必需 |
@umeng/common | ≥1.2.0 | 设备标识采集、鉴权、UMID | 是 |
@umeng/adk | ≥0.1.0 | ADK 核心能力 | 是 |
@umeng/analytics | ≥1.0.0 | 统计分析(可选) | 否 |
1.3 权限清单
权限名 | 用途 | 是否必需 |
ohos.permission.INTERNET | 云端推理与网关通信 | 是 |
ohos.permission.GET_NETWORK_INFO | 检测网络状态 | 是 |
ohos.permission.MICROPHONE | ASR 语音识别录音 | 仅 ASR 场景 |
说明:INTERNET 和 GET_NETWORK_INFO 为系统级权限,在 module.json5 中声明即可生效。MICROPHONE 属于敏感权限,需在运行时动态申请。
第二章:友盟 Common SDK 集成
ADK 依赖 @umeng/common 完成设备标识(UMID)采集与鉴权,接入方须在初始化 ADK 前完成 Common SDK 集成。
2.1 ohpm 安装
ohpm install @umeng/common2.2 配置 umconfig.json
在宿主 App 的 AppScope/resources/rawfile/ 目录下创建 umconfig.json:
{
"appKey": "您的AppKey",
"channel": "default"
}字段 | 类型 | 必填 | 说明 |
appKey | string | 是 | 友盟平台分配的 24 位十六进制 AppKey |
channel | string | 否 | 渠道标识,默认 "default" |
2.3 AbilityStage 中初始化
在宿主 App 的 AbilityStage 入口文件中完成 Common SDK 初始化:
// MyAbilityStage.ets
import { AbilityStage } from '@kit.AbilityKit';
import { UMAbridge } from '@umeng/common';
export default class MyAbilityStage extends AbilityStage {
onCreate() {
// 1. 绑定上下文
UMAbridge.getInstance().bindContext(this.context.getApplicationContext());
// 2. 用户授权后调用 agree(隐私合规要求,详见 2.5)
UMAbridge.getInstance().agree();
}
}在 entry 模块的 module.json5 中配置 srcEntry:
{
"module": {
"srcEntry": "./ets/MyAbilityStage.ets",
// ... 其他配置
}
}2.4 初始化顺序约束
接入方须严格按照以下顺序完成初始化:
bindContext → agree → UADK.init → UADK.prepare → 业务调用说明:UADK.init 内部依赖 Common SDK 提供的 UMID 进行鉴权。若 Common SDK 未完成 bindContext 和 agree,ADK 初始化将因鉴权信息缺失而失败。
2.5 隐私合规说明
agree() 表示终端用户已同意隐私政策。接入方须确保:
在用户明确同意隐私政策后再调用
agree()在用户同意前,不得采集任何设备标识信息
bindContext()可在同意前调用,但agree()必须在用户授权后触发
第三章:ADK SDK 集成
3.1 依赖引入
本地 HAR
将 ADK HAR 包放置于项目目录,在 oh-package.json5 中通过 file 协议引用:
{
"dependencies": {
"@umeng/adk": "file:./libs/adk-0.1.0.har"
}
}在线依赖
ohpm install @umeng/adk安装后 oh-package.json5 自动写入依赖:
{
"dependencies": {
"@umeng/adk": "^0.1.0"
}
}3.2 初始化
调用 UADK.init 完成 SDK 初始化,随后调用 UADK.prepare 预加载端侧能力:
static init(context: Context, appKey: string, config?: ADKConfig): booleanADKConfig 参数表:
参数 | 类型 | 必填 | 说明 |
logLevel | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'NONE' | 否 | 日志级别,默认 INFO |
timeoutMs | number | 否 | 全局超时时间(毫秒),默认 30000 |
UADK.prepare() 为异步方法,返回 Promise<boolean>:
static async prepare(): Promise<boolean>说明:prepare()内部完成端侧模型加载与能力探测,调用耗时与设备性能相关。prepare()幂等,重复调用安全返回。
完整初始化代码示例:
import { UADK } from '@umeng/adk';
// 在 EntryAbility.onCreate 中调用
async function initADK(context: Context): Promise<void> {
const config = { logLevel: 'DEBUG' as const, timeoutMs: 30000 };
const inited = UADK.init(context, 'YOUR_APP_KEY', config);
if (!inited) {
console.error('ADK init failed');
return;
}
const ready = await UADK.prepare();
if (ready) {
console.info('ADK is ready');
}
}3.3 调试模式
接入方可通过 ADKConfig.logLevel 控制日志输出级别。开发调试阶段建议设置为 DEBUG,生产环境建议设置为 WARN 或 ERROR。
const config = { logLevel: 'DEBUG' as const };
UADK.init(context, appKey, config);日志级别说明:
级别 | 输出内容 |
DEBUG | 全量调试日志,包含端侧推理细节与网络请求 |
INFO | 初始化状态与关键事件 |
WARN | 降级、超时等警告信息 |
ERROR | 错误与异常 |
NONE | 关闭所有日志 |
3.4 状态查询
接入方可通过以下属性查询 SDK 当前状态:
属性 | 类型 | 说明 |
UADK.isReady | boolean | SDK 是否已就绪(init + prepare 均成功) |
UADK.isDisabled | boolean | SDK 是否已被禁用(云控关闭) |
UADK.appKey | string | 当前使用的 AppKey |
说明:建议在调用业务 API 前检查 UADK.isReady,避免在未就绪状态下发起调用导致 NOT_INITIALIZED 错误。第四章:能力接口使用
4.1 非流式聊天(Chat)
Chat 接口提供与后端大模型的直接对话能力,不走端云路由。
static async chat(request: ChatRequest): Promise<ChatResponse>ChatRequest 参数表:
参数 | 类型 | 必填 | 说明 |
model | string | 否 | 模型标识,不传则使用默认模型 |
messages | Message[] | 是 | 消息列表,role 为 'user' 或 'assistant' |
sessionId | string | 否 | 会话标识,用于关联上下文 |
enableThinking | boolean | 否 | 是否启用思维链推理 |
loadHistory | boolean | 否 | 是否加载历史消息 |
imageParams | ImageParams | 否 | 图像生成参数(仅图像生成场景) |
ChatResponse 返回字段表:
字段 | 类型 | 保证级 | 说明 |
meta | MetaInfo | null | 条件存在 | 元信息,包含 model 与 requestId |
content | string | 恒有 | 模型回复内容 |
reasoning | string | null | 条件存在 | 思维链内容,enableThinking 为 true 时存在 |
usage | UsageInfo | null | 条件存在 | 用量统计,包含 inputTokens 与 outputTokens |
traceId | string | 恒有 | 链路追踪 ID |
rawJson | string | 恒有 | 原始 JSON 响应 |
代码示例:
import { UADK, ChatRequest, ChatResponse } from '@umeng/adk';
const request: ChatRequest = {
messages: [
{ role: 'user', content: '你好,请介绍一下你自己' }
],
sessionId: 'session_001'
};
const response: ChatResponse = await UADK.chat(request);
console.info(`回复:${response.content}`);4.2 模型列表
查询当前可用的模型列表:
static async listAdkModels(): Promise<AdkModelInfo[]>import { UADK } from '@umeng/adk';
const models = await UADK.listAdkModels();
models.forEach(m => console.info(`${m.modelId}: ${m.modelName}`));4.3 场景化能力(七场景)
ADK 提供七类场景化能力,每类场景均支持三种调用方式。
场景总览:
场景 | 接口前缀 | 说明 |
ASR | asr | 语音识别,将语音转为文本 |
TTS | tts | 语音合成,将文本转为语音 |
OCR | ocr | 文字识别,从图片中提取文字 |
VISION | vision | 视觉理解,图片内容分析与描述 |
TEXT | text | 文本处理,生成/摘要/改写 |
NLP | nlp | 自然语言处理,分词/实体识别 |
TRANSLATE | translate | 翻译,多语言互译 |
三种调用方式:
调用方式 | 方法签名 | 说明 |
端云路由(推荐) |
| SDK 自动根据端侧能力与网络状态路由至端侧或云端 |
说明:推荐使用端云路由方式。SDK 内部根据设备 AI 芯片能力、模型加载状态与网络连接情况自动选择最优执行路径,接入方无需关心路由细节。
端云路由机制:
检查端侧是否具备对应场景的推理能力
若端侧可用且网络非必需,优先执行端侧推理
若端侧不可用或推理失败,自动降级至云端
降级原因通过 ScenarioResult.executedBy 与 ScenarioResult.error 反映
4.4 七场景参数与返回明细
4.4.0 公共返回结构 ScenarioResult(阅读各场景前必读)
所有场景化能力均返回 ScenarioResult,接入方须先理解此结构的保证级含义。
字段 | 类型 | 保证级 | 说明 |
executedBy | ExecutedBy | 恒有 | 实际执行方:VENDOR(端侧)/ CLOUD(云端)/ UNKNOWN |
content | string | 恒有 | 主要结果文本 |
structured | Record<string, Object> | null | 条件存在 | 结构化结果,端侧与云端结构可能不同 |
audioUrl | string | null | 条件存在 | 仅 TTS 场景存在,端侧为本地路径,云端为 OSS URL |
usage | UsageInfo | null | 条件存在 | 仅云端执行时存在,包含 token 用量 |
meta | MetaInfo | null | 条件存在 | 仅云端执行时存在,包含 model 与 requestId |
error | ADKError | null | 条件存在 | 执行出错时存在,包含错误码与来源 |
rawJson | string | 恒有 | 原始 JSON 响应字符串 |
traceId | string | 恒有 | 链路追踪 ID |
4.4.1 ASR(语音识别)
路由接口参数(AsrScenarioRequest):
参数 | 类型 | 必填 | 说明 |
audioUrl | string | 否 | 音频远程 URL |
audioFilePath | string | 否 | 音频本地文件路径 |
audioFormat | string | 否 | 音频格式,如 'wav'、'mp3'、'pcm' |
sampleRate | number | 否 | 采样率,默认 16000 |
languageHints | string[] | 否 | 语言提示,如 ['zh-CN'] |
hotwords | string[] | 否 | 热词列表,提升识别准确率 |
说明:audioUrl 与 audioFilePath 至少传一个。Vendor(端侧)调用时通过麦克风实时录音,不需要传入音频文件路径,SDK 内部处理录音逻辑。
返回值差异:
字段 | 端侧(VENDOR) | 云端(CLOUD) |
content | 识别文本 | 识别文本 |
structured |
|
|
代码示例:
import { UADK, AsrScenarioRequest, ScenarioResult } from '@umeng/adk';
// 端云路由
const request: AsrScenarioRequest = {
audioFilePath: '/data/storage/audio/sample.wav',
audioFormat: 'wav',
sampleRate: 16000,
languageHints: ['zh-CN']
};
const result: ScenarioResult = await UADK.asr(request);
console.info(`识别结果:${result.content},执行方:${result.executedBy}`);4.4.2 TTS(语音合成)
路由接口参数(TtsScenarioRequest):
参数 | 类型 | 必填 | 说明 |
text | string | 是 | 待合成的文本 |
voice | string | 否 | 音色标识 |
format | string | 否 | 输出格式,如 'mp3'、'wav' |
sampleRate | number | 否 | 采样率 |
speed | number | 否 | 语速倍率,1.0 为正常语速 |
返回值差异:
字段 | 端侧(VENDOR) | 云端(CLOUD) |
content | 合成状态描述 | 合成状态描述 |
audioUrl | 本地缓存文件路径 | OSS 远程 URL |
说明:端侧 TTS 生成的音频文件存储在应用缓存目录,audioUrl 返回本地绝对路径。云端 TTS 的 audioUrl 为 OSS 远程 URL,接入方需自行下载。
代码示例:
import { UADK, TtsScenarioRequest, ScenarioResult } from '@umeng/adk';
const request: TtsScenarioRequest = {
text: '欢迎使用友盟 ADK',
voice: 'default',
format: 'mp3',
speed: 1.0
};
const result: ScenarioResult = await UADK.tts(request);
if (result.audioUrl) {
console.info(`音频路径:${result.audioUrl}`);
}4.4.3 OCR(文字识别)
路由接口参数(OcrScenarioRequest):
参数 | 类型 | 必填 | 说明 |
imageUrl | string | 否 | 图片远程 URL |
imageFilePath | string | 否 | 图片本地文件路径 |
task | string | 否 | 识别任务类型,如 'general'、'table' |
languageHints | string[] | 否 | 语言提示 |
说明:imageUrl 与 imageFilePath 至少传一个。本地路径场景下 SDK 自动将图片上传至云端(若需云端执行)。
返回值差异:
字段 | 端侧(VENDOR) | 云端(CLOUD) |
content | 识别文本拼接 | 识别文本拼接 |
structured |
|
|
代码示例:
import { UADK, OcrScenarioRequest, ScenarioResult } from '@umeng/adk';
const request: OcrScenarioRequest = {
imageFilePath: '/data/storage/images/sample.png'
};
const result: ScenarioResult = await UADK.ocr(request);
console.info(`识别文本:${result.content}`);4.4.4 VISION(视觉理解)
路由接口参数(VisionScenarioRequest):
参数 | 类型 | 必填 | 说明 |
imageUrl | string | 否 | 图片远程 URL |
imageFilePath | string | 否 | 图片本地文件路径 |
task | string | 否 | 任务类型,如 'describe'、'classify' |
options | Record<string, Object> | 否 | 扩展选项 |
返回值差异:
字段 | 端侧(VENDOR) | 云端(CLOUD) |
content | 图片描述文本 | 图片描述文本 |
structured |
|
|
代码示例:
import { UADK, VisionScenarioRequest, ScenarioResult } from '@umeng/adk';
const request: VisionScenarioRequest = {
imageFilePath: '/data/storage/images/photo.jpg',
task: 'describe'
};
const result: ScenarioResult = await UADK.vision(request);
console.info(`图片描述:${result.content}`);4.4.5 TEXT(文本处理)
路由接口参数(TextScenarioRequest):
参数 | 类型 | 必填 | 说明 |
text | string | 是 | 输入文本 |
task | string | 否 | 任务类型:'generate'(生成)/ 'summarize'(摘要)/ 'rewrite'(改写) |
prompt | string | 否 | 自定义 prompt,优先级高于 task |
maxLength | number | 否 | 最大输出长度 |
style | string | 否 | 输出风格,如 'formal'、'casual' |
language | string | 否 | 输出语言,如 'zh-CN'、'en-US' |
三种子任务说明:
task 值 | 功能 | 典型用途 |
generate | 文本生成 | 根据输入生成新文本 |
summarize | 文本摘要 | 提取关键信息,压缩文本 |
rewrite | 文本改写 | 调整语气、风格或表达 |
代码示例:
import { UADK, TextScenarioRequest, ScenarioResult } from '@umeng/adk';
const request: TextScenarioRequest = {
text: '这是一段需要摘要的长文本内容...',
task: 'summarize',
maxLength: 100
};
const result: ScenarioResult = await UADK.text(request);
console.info(`摘要结果:${result.content}`);4.4.6 NLP(自然语言处理)
路由接口参数(NlpScenarioRequest):
参数 | 类型 | 必填 | 说明 |
text | string | 是 | 输入文本 |
task | string | 否 | 单任务类型,如 'tokenization'、'ner' |
tasks | string[] | 否 | 多任务列表,支持同时执行多种 NLP 任务 |
language | string | 否 | 语言标识 |
说明:tasks 数组支持多任务并发执行,可选值包括 'tokenization'(分词)、'ner'(命名实体识别)等。tasks 与 task 二选一,tasks 优先级更高。
返回值差异:
字段 | 端侧(VENDOR) | 云端(CLOUD) |
content | 主要任务结果文本 | 主要任务结果文本 |
structured.tokens | string[] | object[](含 token、pos 等字段) |
说明:端侧分词结果为纯字符串数组,云端分词结果包含词性标注等附加信息,结构更为丰富。接入方如需统一处理,建议仅解析 content 字段。
代码示例:
import { UADK, NlpScenarioRequest, ScenarioResult } from '@umeng/adk';
const request: NlpScenarioRequest = {
text: '北京是中国的首都',
tasks: ['tokenization', 'ner'],
language: 'zh-CN'
};
const result: ScenarioResult = await UADK.nlp(request);
console.info(`NLP 结果:${result.content}`);
if (result.structured) {
console.info(`结构化:${JSON.stringify(result.structured)}`);
}4.4.7 TRANSLATE(翻译)
路由接口参数(TranslateScenarioRequest):
参数 | 类型 | 必填 | 说明 |
text | string | 是 | 待翻译文本 |
targetLang | string | 是 | 目标语言,如 'zh-CN'、'en-US'、'ja-JP' |
sourceLang | string | 否 | 源语言,不传则自动检测 |
domain | string | 否 | 领域,如 'medical'、'legal'、'tech' |
代码示例:
import { UADK, TranslateScenarioRequest, ScenarioResult } from '@umeng/adk';
const request: TranslateScenarioRequest = {
text: 'Hello, how are you?',
targetLang: 'zh-CN',
sourceLang: 'en-US'
};
const result: ScenarioResult = await UADK.translate(request);
console.info(`翻译结果:${result.content}`);第五章:数据模型参考
5.1 ChatRequest
interface ChatRequest {
model?: string;
messages: Message[];
sessionId?: string;
enableThinking?: boolean;
loadHistory?: boolean;
imageParams?: ImageParams;
}5.2 Message
interface Message {
role: string; // 'user' | 'assistant' | 'system'
content: string;
}5.3 ImageParams
interface ImageParams {
size?: string; // 图片尺寸,如 '1024x1024'
quality?: string; // 质量等级
n?: number; // 生成数量
}5.4 ChatResponse
interface ChatResponse {
meta: MetaInfo | null;
content: string;
reasoning: string | null;
usage: UsageInfo | null;
traceId: string;
rawJson: string;
}5.5 MetaInfo
interface MetaInfo {
model: string;
requestId: string;
}5.6 UsageInfo
interface UsageInfo {
inputTokens: number;
outputTokens: number;
}5.7 ScenarioResult
interface ScenarioResult {
executedBy: ExecutedBy; // 恒有
content: string; // 恒有
structured: Record<string, Object> | null; // 条件存在
audioUrl: string | null; // 条件存在(仅 TTS)
usage: UsageInfo | null; // 条件存在(仅云端)
meta: MetaInfo | null; // 条件存在(仅云端)
error: ADKError | null; // 条件存在
rawJson: string; // 恒有
traceId: string; // 恒有
}5.8 ExecutedBy
type ExecutedBy = 'VENDOR' | 'CLOUD' | 'UNKNOWN';5.9 ADKConfig
interface ADKConfig {
logLevel?: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'NONE';
timeoutMs?: number;
}5.10 ADKError
class ADKError extends Error {
readonly sCode: number;
readonly code: ADKErrorCode;
readonly source: ADKErrorSource;
readonly traceId: string;
}5.11 ADKErrorCode
enum ADKErrorCode {
PARAM = 1001,
NOT_INITIALIZED = 1002,
DISABLED = 1003,
NETWORK = 1004,
CREDENTIAL = 1005,
DEVICE_CAPABILITY_UNAVAILABLE = 1006,
UNKNOWN = 9999
}5.12 ADKErrorSource
enum ADKErrorSource {
LOCAL = 'LOCAL',
NETWORK = 'NETWORK',
GATEWAY = 'GATEWAY',
CREDENTIAL = 'CREDENTIAL'
}5.13 各场景 ScenarioRequest
// ASR
interface AsrScenarioRequest {
audioUrl?: string;
audioFilePath?: string;
audioFormat?: string;
sampleRate?: number;
languageHints?: string[];
hotwords?: string[];
}
// TTS
interface TtsScenarioRequest {
text: string;
voice?: string;
format?: string;
sampleRate?: number;
speed?: number;
}
// OCR
interface OcrScenarioRequest {
imageUrl?: string;
imageFilePath?: string;
task?: string;
languageHints?: string[];
}
// VISION
interface VisionScenarioRequest {
imageUrl?: string;
imageFilePath?: string;
task?: string;
options?: Record<string, Object>;
}
// TEXT
interface TextScenarioRequest {
text: string;
task?: string;
prompt?: string;
maxLength?: number;
style?: string;
language?: string;
}
// NLP
interface NlpScenarioRequest {
text: string;
task?: string;
tasks?: string[];
language?: string;
}
// TRANSLATE
interface TranslateScenarioRequest {
text: string;
targetLang: string;
sourceLang?: string;
domain?: string;
}第六章:错误处理
6.1 ADKError 结构说明
ADK 所有异步操作失败时均抛出 ADKError,包含以下核心字段:
字段 | 类型 | 说明 |
sCode | number | 数字错误码 |
code | ADKErrorCode | 错误码枚举 |
source | ADKErrorSource | 错误来源分类 |
traceId | string | 链路追踪 ID,可用于问题排查 |
message | string | 错误描述信息 |
6.2 ADKErrorSource 枚举含义
来源值 | 说明 |
LOCAL | 本地错误,参数校验失败或 SDK 状态异常 |
NETWORK | 网络层错误,连接超时或网络不可达 |
GATEWAY | 网关层错误,云端服务返回异常 |
CREDENTIAL | 鉴权错误,AppKey 无效或 UMID 缺失 |
6.3 本地错误码表
错误码 | 常量 | 说明 | 处理建议 |
1001 | PARAM | 参数错误 | 检查必填字段是否缺失或格式不合法 |
1002 | NOT_INITIALIZED | 未初始化 | 确认已调用 UADK.init + UADK.prepare |
1003 | DISABLED | SDK 已被禁用 | 联系友盟技术支持确认云控配置 |
1004 | NETWORK | 网络错误 | 检查 INTERNET 权限声明与设备网络连接 |
1005 | CREDENTIAL | 鉴权失败 | 检查 AppKey 是否正确,Common SDK 是否已完成初始化 |
1006 | DEVICE_CAPABILITY_UNAVAILABLE | 端侧能力不可用 | 降级至云端调用(UADK.xxxCloud),或检查设备 AI 芯片支持 |
9999 | UNKNOWN | 未知错误 | 保留 traceId,联系友盟技术支持 |
6.4 错误处理示例
import { UADK, ADKError, TextScenarioRequest } from '@umeng/adk';
try {
const result = await UADK.text({ text: '测试文本', task: 'summarize' });
if (result.error) {
// 执行层错误,通过 ScenarioResult.error 返回
console.warn(`执行失败:${result.error.code} - ${result.error.message}`);
} else {
console.info(`结果:${result.content}`);
}
} catch (e) {
// 抛出层错误(如未初始化、参数校验)
if (e instanceof ADKError) {
console.error(`ADK 错误:[${e.code}] ${e.message},来源:${e.source},traceId:${e.traceId}`);
if (e.sCode === 1002) {
// 未初始化,引导初始化流程
console.error('请先调用 UADK.init 和 UADK.prepare');
}
}
}第七章:工程配置
7.1 module.json5 权限声明
在 entry 模块的 module.json5 中声明所需权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
},
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:microphone_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}说明:MICROPHONE 权限仅在接入方使用 ASR 场景时需要声明。reason 字段需在 string.json 中配置对应的多语言文案。
7.2 混淆配置
若宿主 App 开启了代码混淆,须将 ADK 相关类加入保留列表。在 consumer-rules.pro 或 obfuscation-rules.pro 中添加:
# ADK SDK
-keep class UADK { *; }
-keep class ADKError { *; }
-keep class ADKConfig { *; }
-keep class ScenarioResult { *; }
-keep class ChatRequest { *; }
-keep class ChatResponse { *; }在 build-profile.json5 中配置混淆规则文件:
{
"app": {
"products": [
{
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true
}
}
}
]
}
}7.3 签名配置
HarmonyOS 应用发布需要签名配置。签名材料(.p12 证书与 .p7b 描述文件)在 DevEco Studio 中通过 File > Project Structure > Signing Configs 配置。
若使用自动签名,DevEco Studio 将自动管理证书与描述文件。若使用手动签名,接入方须自行申请并配置签名材料。
说明:签名配置异常(如证书过期、描述文件不匹配)将导致构建失败,详见 FAQ-1。
第八章:注意事项
初始化顺序:Common SDK 必须在 ADK SDK 之前完成初始化。严格遵循 bindContext → agree → UADK.init → UADK.prepare 的调用链。
隐私合规:
agree()须在终端用户明确授权同意隐私政策后调用。在用户同意前调用属于违规行为,可能导致应用审核不通过。网络权限:INTERNET 和 GET_NETWORK_INFO 为 ADK 正常运行的必要权限,缺失将导致所有云端能力与鉴权失败。
ASR 麦克风权限:MICROPHONE 属于敏感权限,须在运行时通过
requestPermissionsFromUser动态申请,仅在 module.json5 中声明不足以获取权限。媒体文件路径:imageFilePath 和 audioFilePath 支持本地绝对路径。当需要云端执行时,SDK 自动将本地文件上传至云端,接入方无需手动上传。
线程安全:UADK 所有 API 均为异步方法,回调在子线程执行。若需在回调中更新 UI,接入方须显式切换至主线程。
幂等性:
UADK.prepare()具有幂等性,重复调用不会重复加载模型或产生副作用,返回结果与首次调用一致。端侧能力依赖:Vendor(强制端侧)能力依赖设备 AI 芯片与厂商 SDK,不同品牌、型号的设备对七场景的支持程度存在差异。建议优先使用端云路由方式。
状态查询:调用业务 API 前,可通过
UADK.isReady检查 SDK 是否已就绪。isReady为 false 时调用业务 API 将抛出 NOT_INITIALIZED 错误。资源释放:应用退出或不再使用 ADK 能力时,须调用
UADK.destroy()释放端侧模型资源与网络连接,避免内存泄漏。全局错误监听:可通过
UADK.onError注册全局错误回调,捕获未被 try-catch 捕获的异步错误,便于统一监控与上报。超时配置:
ADKConfig.timeoutMs控制全局超时,默认 30000ms。对于 TTS、大文件 OCR 等耗时较长的场景,建议适当调大超时值。
第九章:常见问题(FAQ)
FAQ-1:DevEco Studio 构建报错签名材料非法
现象:构建时出现 "The signing material is invalid" 或类似错误。
原因:签名证书过期、描述文件与 BundleName 不匹配,或签名密码错误。
处理建议:
检查证书有效期,若已过期则重新申请
确认描述文件中的 BundleName 与项目 AppScope/app.json5 中一致
若使用自动签名,尝试
File > Project Structure > Signing Configs中勾选 "Automatically generate signature" 重新生成清理构建缓存:
Build > Clean Project,重新构建
FAQ-2:初始化 prepare 回调 1004(zid 不能为 null)
现象:UADK.prepare() 返回失败,错误码 1004,日志中出现 "zid cannot be null"。
原因:Common SDK 未完成初始化,UMID(设备标识)采集失败,导致 ADK 鉴权请求中 zid 字段为空。
处理建议:
确认 MyAbilityStage 中已调用
UMAbridge.getInstance().bindContext(context)确认已在用户授权后调用
UMAbridge.getInstance().agree()确认 umconfig.json 已正确放置于
AppScope/resources/rawfile/目录,且 appKey 格式正确(24 位十六进制)检查网络连接,UMID 采集需要首次联网上报
FAQ-3:端侧能力全部走了云端(FALLBACK_ROUTE)
现象:调用 UADK.xxxVendor() 返回错误,或 UADK.xxx() 的 executedBy 始终为 CLOUD。
原因:设备不具备对应场景的端侧推理能力,或端侧模型加载失败。
处理建议:
检查设备是否支持目标场景的端侧推理(并非所有 HarmonyOS 设备均配备 AI 芯片)
调用
UADK.isReady确认 prepare 已完成查看日志中是否有模型加载失败的 WARN 级别日志
对于不具备端侧能力的设备,建议直接使用
UADK.xxxCloud()避免不必要的端侧探测开销端云路由模式下 FALLBACK_ROUTE 为正常行为,SDK 已自动降级至云端,不影响功能使用