HarmonyOS开发:车载语音——让驾驶员嘴巴比手快

举报
Jack20 发表于 2026/06/26 16:20:56 2026/06/26
【摘要】 HarmonyOS开发:车载语音——让驾驶员嘴巴比手快📌 核心要点:车载语音的核心不是语音识别,而是免唤醒词模式、多轮对话上下文理解、语音控车三大能力的整合,让驾驶员真正解放双手。 背景与动机开车的时候你想调个空调温度,你得:低头找空调按钮→看屏幕→点温度→调到想要的值→视线回到路面。整个过程至少3秒,高速上3秒车已经飞出去80多米了。要是能直接说一句"把空调调到24度"呢?0.5秒说完...

HarmonyOS开发:车载语音——让驾驶员嘴巴比手快

📌 核心要点:车载语音的核心不是语音识别,而是免唤醒词模式、多轮对话上下文理解、语音控车三大能力的整合,让驾驶员真正解放双手。

背景与动机

开车的时候你想调个空调温度,你得:低头找空调按钮→看屏幕→点温度→调到想要的值→视线回到路面。整个过程至少3秒,高速上3秒车已经飞出去80多米了。

要是能直接说一句"把空调调到24度"呢?0.5秒说完,0.5秒系统响应,视线始终在路面上。这就是车载语音的价值——把3秒的手动操作压缩到1秒的语音指令

但车载语音跟家里的智能音箱不一样。你跟音箱说"播放音乐",它说"好的",你再说"下一首",它又说"好的"。每次都要先喊唤醒词,再说指令——这在车里是不可接受的。你总不能开车时每隔几秒就喊一次"小艺小艺"吧?

HarmonyOS车载语音的杀手锏是免唤醒词模式——你不需要先喊唤醒词,直接说指令就行。而且支持多轮对话,你说"导航到中关村",它问"哪条路",你说"最快的",它直接开始导航。整个过程像跟副驾的人说话一样自然。

核心原理

车载语音交互架构

车载语音不是简单的"语音识别→执行指令"。它涉及唤醒、识别、理解、执行、反馈五个阶段,每个阶段都有车机特有的要求。

graph LR
    A[语音输入] --> B{免唤醒检测}
    B -->|检测到指令| C[语音识别 ASR]
    B -->|未检测到| D[静默等待]
    
    C --> E[语义理解 NLU]
    E --> F{意图分类}
    
    F -->|导航意图| G[导航服务]
    F -->|控车意图| H[车辆控制]
    F -->|媒体意图| I[媒体播放]
    F -->|通用意图| J[系统操作]
    
    G --> K[语音反馈 TTS]
    H --> K
    I --> K
    J --> K
    
    K --> L{需要继续对话?}
    L -->|| A
    L -->|| D

    classDef input fill:#4CAF50,stroke:#2E7D32,color:#fff
    classDef process fill:#2196F3,stroke:#1565C0,color:#fff
    classDef intent fill:#FF9800,stroke:#E65100,color:#fff
    classDef action fill:#9C27B0,stroke:#6A1B9A,color:#fff
    classDef feedback fill:#E91E63,stroke:#880E4F,color:#fff

    class A,B,D input
    class C,E,F process
    class G,H,I,J intent
    class K,L feedback

免唤醒词模式原理

免唤醒词不是真的"不唤醒",而是用一种更智能的方式判断用户是否在对车机说话:

  1. 声源定位:通过车内多个麦克风,判断声音来自驾驶员还是乘客
  2. 关键词检测:不需要完整的唤醒词,而是检测"指令性"关键词(如"导航到"、“打开”、“调高”)
  3. 上下文关联:如果上一轮对话还没结束,后续语音自动关联,不需要唤醒词

免唤醒模式的触发条件:

  • 驾驶模式开启时自动启用
  • 导航、音乐等特定场景下自动启用
  • 用户手动开启"连续对话"模式

多轮对话状态机

多轮对话的核心是维护一个"对话上下文"——系统得记住你上一句说了什么,才能理解你下一句的意思。

用户: 导航到中关村
系统: 找到3条路线,最快路线28分钟,是否选择?
用户: 有不走高速的吗
系统: 有一条不走高速的路线,35分钟,是否选择?
用户: 就这条
系统: 好的,开始导航

这个对话涉及3轮,系统必须维护"目的地=中关村"、"偏好=不走高速"这些上下文信息。

代码实战

基础用法:语音识别与指令执行

先实现最基础的功能——语音识别并执行简单指令。

// CarVoiceAssistant.ets - 基础语音助手
import { speechRecognizer } from '@kit.AIKit';
import { textToSpeech } from '@kit.AIKit';

// 语音指令
export interface VoiceCommand {
  intent: string;       // 意图:navigate/control/media/system
  action: string;       // 动作:如 open/close/set
  target: string;       // 目标:如 空调/车窗/导航
  value: string;        // 值:如 24度/50%/中关村
  confidence: number;   // 置信度 0-1
}

export class CarVoiceAssistant {
  private asrEngine: speechRecognizer.SpeechRecognizer | null = null;
  private ttsEngine: textToSpeech.TextToSpeechEngine | null = null;
  private isListening: boolean = false;
  private onCommand?: (command: VoiceCommand) => void;

  // 初始化语音引擎
  async init(): Promise<void> {
    // 初始化ASR(语音识别)
    const asrParams: speechRecognizer.CreateEngineParams = {
      language: 'zh-CN',
      extraParams: { 'recognizeMode': 'continuous' },
    };
    this.asrEngine = await speechRecognizer.createEngine(asrParams);

    // 初始化TTS(语音合成)
    const ttsParams: textToSpeech.CreateEngineParams = {
      language: 'zh-CN',
      person: 0,
      online: 1,
    };
    this.ttsEngine = await textToSpeech.createEngine(ttsParams);

    console.info('[Voice] 语音引擎初始化完成');
  }

  // 开始监听(免唤醒模式)
  startListening(): void {
    if (!this.asrEngine || this.isListening) return;

    this.isListening = true;
    const listener: speechRecognizer.RecognitionListener = {
      // 识别结果回调
      onResult: (result: speechRecognizer.RecognitionResult) => {
        if (result.isFinal) {
          const text = result.result;
          console.info(`[Voice] 识别结果: ${text}`);
          // 解析语音指令
          const command = this.parseVoiceCommand(text);
          if (command && command.confidence > 0.6) {
            this.onCommand?.(command);
          }
        }
      },
      // 错误回调
      onError: (error: speechRecognizer.SpeechError) => {
        console.error(`[Voice] 识别错误: ${error.errorCode}`);
        this.isListening = false;
      },
      // 开始识别
      onStart: () => {
        console.info('[Voice] 开始识别');
      },
      // 结束识别
      onComplete: () => {
        console.info('[Voice] 识别完成');
        // 免唤醒模式:自动重新开始监听
        if (this.isListening) {
          this.startListening();
        }
      },
    };

    this.asrEngine.listen({
      sessionId: 'car_voice_' + Date.now(),
      audioInfo: { audioType: 'pcm', sampleRate: 16000, soundChannel: 1 },
      extraParams: { 'vadBegin': 2000, 'vadEnd': 3000 }, // 语音端点检测
    }, listener);
  }

  // 停止监听
  stopListening(): void {
    if (this.asrEngine && this.isListening) {
      this.asrEngine.finish('car_voice_session');
      this.isListening = false;
    }
  }

  // 语音播报
  speak(text: string): void {
    if (!this.ttsEngine) return;
    const params: textToSpeech.SpeakParams = {
      requestId: Date.now().toString(),
      extraParams: { speed: 1.0, pitch: 1.0, volume: 2.0 },
    };
    this.ttsEngine.speak(text, params);
  }

  // 解析语音指令(简化版,实际应使用NLU服务)
  private parseVoiceCommand(text: string): VoiceCommand | null {
    // 导航指令
    const navMatch = text.match(/导航到(.+)/);
    if (navMatch) {
      return {
        intent: 'navigate',
        action: 'navigate_to',
        target: '导航',
        value: navMatch[1],
        confidence: 0.9,
      };
    }

    // 空调温度
    const acTempMatch = text.match(/空调.*?(\d+)度/);
    if (acTempMatch) {
      return {
        intent: 'control',
        action: 'set',
        target: '空调温度',
        value: acTempMatch[1],
        confidence: 0.85,
      };
    }

    // 打开/关闭
    const switchMatch = text.match(/(打开|关闭)(空调|车窗|座椅加热|后备箱)/);
    if (switchMatch) {
      return {
        intent: 'control',
        action: switchMatch[1] === '打开' ? 'open' : 'close',
        target: switchMatch[2],
        value: '',
        confidence: 0.9,
      };
    }

    // 播放音乐
    const musicMatch = text.match(/播放(.+?)的(.+)/);
    if (musicMatch) {
      return {
        intent: 'media',
        action: 'play',
        target: '音乐',
        value: `${musicMatch[1]} - ${musicMatch[2]}`,
        confidence: 0.85,
      };
    }

    // 简单播放指令
    const playMatch = text.match(/播放(.+)/);
    if (playMatch) {
      return {
        intent: 'media',
        action: 'play',
        target: '音乐',
        value: playMatch[1],
        confidence: 0.8,
      };
    }

    return null;
  }

  // 设置指令回调
  setOnCommand(callback: (command: VoiceCommand) => void): void {
    this.onCommand = callback;
  }

  // 销毁
  destroy(): void {
    this.stopListening();
    this.asrEngine = null;
    this.ttsEngine = null;
  }
}

进阶用法:多轮对话与上下文管理

单轮指令只能处理简单场景。真正的车载语音必须支持多轮对话——系统得"记住"你上一句说了什么。

// VoiceDialogManager.ets - 多轮对话管理
// 对话状态
export enum DialogState {
  IDLE = 'idle',             // 空闲
  WAITING_INPUT = 'waiting', // 等待用户输入
  CONFIRMING = 'confirming', // 确认中
  EXECUTING = 'executing',  // 执行中
}

// 对话上下文
export interface DialogContext {
  intent: string;            // 当前意图
  slots: Record<string, string>; // 已填充的槽位
  missingSlots: string[];    // 缺失的槽位
  turnCount: number;         // 对话轮次
  lastPrompt: string;        // 上次系统的提示语
}

export class VoiceDialogManager {
  private dialogState: DialogState = DialogState.IDLE;
  private context: DialogContext | null = null;
  private dialogTimeout: number = 15000; // 15秒无输入结束对话
  private timeoutTimer: number = -1;

  // 意图定义(槽位模板)
  private intentTemplates: Record<string, { requiredSlots: string[], optionalSlots: string[] }> = {
    navigate: {
      requiredSlots: ['destination'],
      optionalSlots: ['route_preference', 'avoid'],
    },
    climate_control: {
      requiredSlots: ['action'],
      optionalSlots: ['temperature', 'fan_speed', 'zone'],
    },
    media_play: {
      requiredSlots: ['content'],
      optionalSlots: ['artist', 'album'],
    },
  };

  // 处理语音指令(带上下文)
  processCommand(command: VoiceCommand): string {
    // 重置超时计时器
    this.resetTimeout();

    // 如果当前没有活跃对话,创建新上下文
    if (this.dialogState === DialogState.IDLE) {
      this.context = {
        intent: command.intent,
        slots: {},
        missingSlots: [],
        turnCount: 0,
        lastPrompt: '',
      };
    }

    // 填充槽位
    this.fillSlots(command);

    // 检查是否所有必需槽位都已填充
    const template = this.intentTemplates[this.context!.intent];
    if (!template) {
      return this.endDialog('抱歉,我无法理解您的请求');
    }

    this.context!.missingSlots = template.requiredSlots.filter(
      slot => !this.context!.slots[slot]
    );

    if (this.context!.missingSlots.length > 0) {
      // 还有缺失的槽位,追问
      return this.askForMissingSlot();
    }

    // 所有槽位已填充,执行指令
    return this.executeCommand();
  }

  // 填充槽位
  private fillSlots(command: VoiceCommand): void {
    if (!this.context) return;

    // 根据意图类型填充不同的槽位
    switch (this.context.intent) {
      case 'navigate':
        if (command.value) this.context.slots['destination'] = command.value;
        if (command.action === 'avoid_highway') this.context.slots['avoid'] = '高速';
        break;
      case 'control':
        this.context.slots['action'] = command.action;
        if (command.target.includes('温度') && command.value) {
          this.context.slots['temperature'] = command.value;
        }
        if (command.target) this.context.slots['zone'] = command.target;
        break;
      case 'media':
        if (command.value) this.context.slots['content'] = command.value;
        break;
    }

    this.context.turnCount++;
  }

  // 追问缺失槽位
  private askForMissingSlot(): string {
    if (!this.context) return '';

    const missing = this.context.missingSlots[0];
    let prompt = '';

    switch (missing) {
      case 'destination':
        prompt = '请问您要导航到哪里?';
        break;
      case 'action':
        prompt = '请问您要打开还是关闭?';
        break;
      case 'content':
        prompt = '请问您想播放什么?';
        break;
      default:
        prompt = '请补充更多信息';
    }

    this.context.lastPrompt = prompt;
    this.dialogState = DialogState.WAITING_INPUT;
    return prompt;
  }

  // 执行指令
  private executeCommand(): string {
    if (!this.context) return '';

    this.dialogState = DialogState.EXECUTING;
    let response = '';

    switch (this.context.intent) {
      case 'navigate':
        response = `好的,正在为您导航到${this.context.slots['destination']}`;
        if (this.context.slots['avoid']) {
          response += `,避开${this.context.slots['avoid']}`;
        }
        break;
      case 'control':
        response = `好的,已${this.context.slots['action'] === 'open' ? '打开' : '关闭'}${this.context.slots['zone'] || '空调'}`;
        if (this.context.slots['temperature']) {
          response += `,温度设为${this.context.slots['temperature']}`;
        }
        break;
      case 'media':
        response = `好的,正在播放${this.context.slots['content']}`;
        break;
    }

    // 执行完毕,结束对话
    this.endDialog(response);
    return response;
  }

  // 结束对话
  private endDialog(message: string): string {
    this.dialogState = DialogState.IDLE;
    this.context = null;
    if (this.timeoutTimer !== -1) {
      clearTimeout(this.timeoutTimer);
      this.timeoutTimer = -1;
    }
    return message;
  }

  // 重置超时
  private resetTimeout(): void {
    if (this.timeoutTimer !== -1) {
      clearTimeout(this.timeoutTimer);
    }
    this.timeoutTimer = setTimeout(() => {
      this.endDialog('对话超时,语音助手已退出');
    }, this.dialogTimeout) as unknown as number;
  }

  // 获取当前对话状态
  getState(): DialogState {
    return this.dialogState;
  }
}

完整示例:车载语音助手页面

把语音识别、多轮对话、指令执行、语音反馈整合到一个完整的页面里。

// CarVoicePage.ets - 车载语音助手完整页面
@Entry
@Component
struct CarVoicePage {
  @State isListening: boolean = false;
  @State recognizedText: string = '';
  @State dialogHistory: string[] = [];
  @State voiceLevel: number = 0;
  @State currentResponse: string = '';

  build() {
    Column({ space: 20 }) {
      // 标题
      Row() {
        Text('语音助手')
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.White)
        Text(this.isListening ? '🎤 正在聆听...' : '点击开始')
          .fontSize(14)
          .fontColor(this.isListening ? '#4CAF50' : '#888888')
          .margin({ left: 16 })
      }
      .width('100%')
      .padding({ left: 30, top: 20 })

      // 语音波形动画
      Row({ space: 4 }) {
        ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], (_: number, index: number) => {
          Column()
            .width(4)
            .height(this.isListening ? 8 + Math.random() * 32 : 8)
            .backgroundColor(this.isListening ? '#4FC3F7' : '#333333')
            .borderRadius(2)
            .animation({ duration: 150, curve: Curve.EaseInOut })
        })
      }
      .justifyContent(FlexAlign.Center)
      .height(50)

      // 当前识别文本
      if (this.recognizedText) {
        Text(`"${this.recognizedText}"`)
          .fontSize(18)
          .fontColor('#4FC3F7')
          .padding({ left: 30, right: 30 })
          .textAlign(TextAlign.Center)
      }

      // 系统回复
      if (this.currentResponse) {
        Row({ space: 8 }) {
          Text('🤖')
            .fontSize(20)
          Text(this.currentResponse)
            .fontSize(16)
            .fontColor(Color.White)
            .layoutWeight(1)
        }
        .width('100%')
        .padding({ left: 20, right: 20, top: 12, bottom: 12 })
        .margin({ left: 30, right: 30 })
        .backgroundColor('#1A3A5C')
        .borderRadius(12)
      }

      // 对话历史
      List({ space: 8 }) {
        ForEach(this.dialogHistory, (msg: string, index: number) => {
          ListItem() {
            Row({ space: 8 }) {
              Text(index % 2 === 0 ? '👤' : '🤖')
                .fontSize(16)
              Text(msg)
                .fontSize(14)
                .fontColor(index % 2 === 0 ? '#CCCCCC' : '#4FC3F7')
                .layoutWeight(1)
            }
            .width('100%')
            .padding(12)
            .backgroundColor(index % 2 === 0 ? '#1A1A2E' : '#1A2A3E')
            .borderRadius(8)
          }
        })
      }
      .layoutWeight(1)
      .padding({ left: 30, right: 30 })

      // 快捷指令
      Row({ space: 12 }) {
        this.QuickCommand('导航回家')
        this.QuickCommand('打开空调')
        this.QuickCommand('播放音乐')
        this.QuickCommand('关闭车窗')
      }
      .padding({ left: 30, right: 30 })

      // 语音按钮
      Button(this.isListening ? '停止聆听' : '开始语音')
        .fontSize(20)
        .fontColor(Color.White)
        .backgroundColor(this.isListening ? '#F44336' : '#4CAF50')
        .borderRadius(28)
        .width(200)
        .height(56)
        .margin({ bottom: 30 })
        .onClick(() => {
          this.isListening = !this.isListening;
          if (this.isListening) {
            this.simulateRecognition();
          }
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#0D1117')
  }

  @Builder
  QuickCommand(text: string) {
    Text(text)
      .fontSize(13)
      .fontColor('#4FC3F7')
      .padding({ left: 16, right: 16, top: 8, bottom: 8 })
      .backgroundColor('#1A2A3E')
      .borderRadius(16)
      .onClick(() => {
        this.recognizedText = text;
        this.processQuickCommand(text);
      })
  }

  // 模拟语音识别
  private simulateRecognition(): void {
    setTimeout(() => {
      this.recognizedText = '导航到中关村软件园';
      this.dialogHistory.push(this.recognizedText);
      this.currentResponse = '找到3条路线,最快的28分钟,是否选择?';
      this.dialogHistory.push(this.currentResponse);
    }, 2000);
  }

  // 处理快捷指令
  private processQuickCommand(text: string): void {
    this.dialogHistory.push(text);
    switch (text) {
      case '导航回家':
        this.currentResponse = '好的,正在为您导航回家';
        break;
      case '打开空调':
        this.currentResponse = '好的,空调已打开,默认24度';
        break;
      case '播放音乐':
        this.currentResponse = '好的,正在播放您喜欢的歌单';
        break;
      case '关闭车窗':
        this.currentResponse = '好的,全车窗已关闭';
        break;
    }
    this.dialogHistory.push(this.currentResponse);
  }
}

踩坑与注意事项

坑1:车内噪声干扰

车内噪声源太多了——发动机、风噪、胎噪、空调、音乐、乘客聊天。这些噪声会严重干扰语音识别的准确率。

应对策略:

  • 使用麦克风阵列做波束成形,增强驾驶员方向的声音
  • 主动降噪:播放音乐时自动降低音量再识别
  • 语音识别前做噪声估计,噪声过大时提示用户"环境嘈杂,请靠近说话"

坑2:误触发问题

免唤醒词模式最大的风险就是误触发——你跟副驾聊天说"打开窗户透透气",车机真的把窗户打开了。

解决方案:

  • 声源定位:只响应来自驾驶员方向的声音
  • 指令前缀检测:要求指令以特定动词开头(导航到、打开、关闭、播放等)
  • 置信度阈值:识别置信度低于0.6的不执行
  • 高风险操作(解锁车门等)必须二次确认

坑3:方言和口音

普通话不标准的用户,语音识别准确率会大幅下降。尤其是南方方言区,“导航"可能被识别成"道航”,“空调"变成"空条”。

解决方案:

  • 支持方言模型切换(粤语、四川话等)
  • 提供语音训练功能,让用户读几段话来适配口音
  • 对于低置信度的识别结果,用TTS确认:“您是说导航到中关村吗?”

坑4:TTS与ASR的回声问题

语音播报(TTS)的时候,麦克风会同时录到TTS的声音,导致ASR把TTS的播报内容也识别了,形成回声循环。

解决方案:

  • TTS播报期间暂停ASR
  • 使用AEC(Acoustic Echo Cancellation,声学回声消除)算法
  • 播报结束后延迟500ms再恢复ASR

坑5:多轮对话的上下文丢失

多轮对话最怕上下文丢失——用户说"导航到中关村",系统问"走哪条路",用户说"最快的",结果系统把"最快的"当成新的独立指令去处理了。

原因:对话超时后上下文被清空,或者ASR引擎重启导致会话ID变化。

解决方案:

  • 对话上下文持久化,不要存在内存里
  • ASR引擎重启时恢复上次的会话ID
  • 设置合理的超时时间(15-30秒),太短容易断,太长浪费资源

HarmonyOS 6适配说明

HarmonyOS 6在车载语音方面做了几项重要更新:

  1. 大模型驱动的NLU:语音理解从规则匹配升级为大模型推理,支持更自然的表达方式。之前你必须说"导航到中关村",现在说"我想去中关村"也能识别。

  2. 多音区识别:支持车内4个座位独立识别,驾驶员和乘客的指令分开处理。副驾说"打开窗户"只开副驾的窗,不会全车窗户都打开。

  3. 视觉辅助:新增唇语识别辅助——在嘈杂环境下,结合唇语判断用户是否在对车机说话,减少误触发。

  4. 离线语音:新增离线语音模型,隧道等无网络环境下也能使用基础语音功能。离线模型比在线模型小(约200MB),识别准确率略低但够用。

适配代码:

// HarmonyOS 6 多音区语音识别
import { speechRecognizer } from '@kit.AIKit';

async function startMultiZoneRecognition(): Promise<void> {
  const asrEngine = await speechRecognizer.createEngine({
    language: 'zh-CN',
    extraParams: {
      'recognizeMode': 'continuous',
      'audioSource': 'multi_channel',  // 多声道输入
      'zoneDetection': true,            // 启用音区检测
    },
  });

  asrEngine.on('zoneResult', (zoneId: number, text: string, confidence: number) => {
    const zoneNames: Record<number, string> = {
      0: '驾驶员', 1: '副驾', 2: '左后', 3: '右后',
    };
    
    console.info(`[Voice] ${zoneNames[zoneId]}: ${text} (置信度: ${confidence})`);
    
    // 只响应驾驶员的指令
    if (zoneId === 0 && confidence > 0.7) {
      // 执行指令
    }
  });
}

总结

车载语音的核心不是"能听懂你说什么",而是"在驾驶场景下可靠地听懂并执行"。免唤醒词模式解决了交互效率问题,多轮对话解决了复杂指令问题,语音控车解决了安全操作问题。但这三者整合起来,还要面对噪声干扰、误触发、方言口音、回声消除、上下文丢失这些工程难题。解决不了这些,语音助手就是个噱头。

维度 评价
学习难度 ⭐⭐⭐⭐ 语音识别API简单,但多轮对话和噪声处理复杂
使用频率 ⭐⭐⭐⭐⭐ 车载语音是智慧出行的标配功能
重要程度 ⭐⭐⭐⭐⭐ 直接影响驾驶安全和便利性

一句话:车载语音做得好不好,不是看识别率多高,而是看驾驶员愿不愿意用——如果他还得伸手去按按钮,说明你的语音助手还不够靠谱。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。