
22. TextReader 朗读与语音交互本章导读语音交互是儿童教育类应用的核心能力之一。「柚兔学伴」中诗词朗读、汉字发音、提醒音效等场景均通过 HarmonyOS SpeechKit 的 TextReader 与第三方 SXPlayer 两套方案实现。本章将详解它们的集成方式与实战用法。22.1 TextReader 初始化TextReader 是 HarmonyOSkit.SpeechKit提供的系统级朗读控件使用前必须在 UIAbility 的onCreate生命周期中完成初始化。// EntryAbility.etsimport{TextReader}fromkit.SpeechKit;import{BusinessError}fromohos.base;exportdefaultclassEntryAbilityextendsUIAbility{asynconCreate(want:Want,launchParam:AbilityConstant.LaunchParam):Promisevoid{if(this.context){constreaderParams:TextReader.ReaderParam{isVoiceBrandVisible:true,businessBrandInfo:{panelName:小艺朗读,panelIcon:$r(app.media.startIcon)}};awaitTextReader.init(this.context,readerParams).then((){console.info(TextReader succeeded in initializing.);}).catch((e:BusinessError){console.error(TextReader failed to initialize. Code:${e.code}, message:${e.message});})}}}关键参数说明参数类型作用isVoiceBrandVisibleboolean是否在朗读面板显示语音品牌标识businessBrandInfo.panelNamestring朗读面板标题如小艺朗读businessBrandInfo.panelIconResource朗读面板图标资源初始化必须在onCreate中完成不能延迟到页面加载阶段否则后续TextReader.start()调用会失败。22.2 PoemReader 朗读工具类为方便多处复用项目将 TextReader 的调用封装为静态工具类PoemReader// PoemReader.etsimport{TextReader}fromkit.SpeechKit;import{BusinessError}fromkit.BasicServicesKit;exportclassPoemReader{staticplay(poem:string,title:string,author:string,date?:string){constreadInfoList:TextReader.ReadInfo[][{id:001,title:{text:title,isClickable:true},author:{text:author,isClickable:true},date:{text:date??newDate().toISOString().split(T)[0],isClickable:false},bodyInfo:poem}];conststartParams:TextReader.StartParams{isMinibarHidden:true,callbackParam:0};TextReader.start(readInfoList,undefined,startParams).then((){console.info(TextReader succeeded in starting);}).catch((e:BusinessError){console.error(TextReader failed to start. Code:${e.code}, message:${e.message});});}}ReadInfo 数据结构interfaceReadInfo{id:string;// 朗读内容唯一标识title:{text:string;isClickable:boolean};// 标题可点击跳转author:{text:string;isClickable:boolean};// 作者可点击跳转date:{text:string;isClickable:boolean};// 日期不可点击bodyInfo:string;// 朗读正文内容}StartParams 参数参数说明isMinibarHidden是否隐藏迷你朗读条true 则全屏朗读面板callbackParam回调参数用于标识本次朗读请求设计要点isClickable控制朗读面板中对应区域是否可交互。对于诗词场景标题和作者可点击查看详情日期设为不可点击。22.3 三大使用场景场景一PoemPage 诗词播读在诗词详情页点击播读按钮调用朗读// PoemPage.etsBuilderbuildBottom(){Row(){Button(播读).layoutWeight(1).borderRadius(5).linearGradient({angle:90,colors:[[0xFF33FF,0.0],[0x8E44FF,1]]}).onClick((){PoemReader.play(this.poemInfo?.poem??);})Blank(10)Button(下一首).layoutWeight(1).borderRadius(5).linearGradient({angle:90,colors:[[0x8E44FF,0.0],[0x1C55FF,1]]}).onClick((){this.generatePoem()})}.width(100%).padding(10)}此处只传入诗词正文标题、作者使用默认空值。朗读面板会以全屏模式展示。场景二StrokeView 汉字发音在笔画查询页面点击 Canvas 区域即可听到当前汉字的读音// StrokeView.etsCanvas(this.context!!).width(100).height(100).onReady((){this.canvasReadytrue;if(!this.isLoading){this.initializeCanvas();this.strokeManager.startAnimation(this.context!!,(){this.updateAnimationInfo();});}}).onClick((){PoemReader.play(this.word);})this.word是单个汉字如样TextReader 会自动识别并朗读该字的发音非常适合儿童识字场景。场景三TodoView 诗词卡片朗读在首页待办视图中点击诗词卡片触发朗读// TodoView.etsColumn({space:12}){Text(this.poem).fontFamily(kaiti).fontWeight(FontWeight.Bold).textAlign(TextAlign.Center).lineSpacing(LengthMetrics.fp(18))}.margin({left:12}).justifyContent(FlexAlign.Center).mainCardStyle().onClick((){PoemReader.play(this.poem);})诗词内容来自每日推荐用户轻触即可聆听朗读实现看诗即听的沉浸体验。22.4 SXPlayer 自定义音频播放对于非朗读类的音频需求如计时结束提醒音项目使用qtfm/smartxplayer模块的 SXPlayer初始化与回调// TodoView.etsimport{AudioEntry,PlayActionCallback,PlayParams,SXPlayer}fromqtfm/smartxplayer;constcontext:common.UIAbilityContextGlobalUIAbilityContext.getContext()Componentexportstruct TodoView{privatecallback:PlayActionCallback{onPlayPrevious:(){},onPlayNext:(){},onToggleFavorite:(assetId){}}privatesxplayer:SXPlayernewSXPlayer(context,{enableLog:true,bundleName:com.youtoo.study.partner,abilityName:EntryAbility,playActionCallback:this.callback})}播放提醒音倒计时结束时读取 rawfile 中的铃声文件并播放onTimerFinishedasync(){this.alarmVisibletrueletfileDescriptorawaitcontext.resourceManager.getRawFd(ringtone_youtoo.mp3);letentity:AudioEntry{fd:fileDescriptor}letparams:PlayParams{audioEntry:[entity],playWhenPrepared:true,hasPrevious:false,hasNext:false,isLive:false}this.sxplayer!.play(params)}PlayParams 参数说明参数类型说明audioEntryAudioEntry[]音频数据源支持 fd 文件描述符playWhenPreparedboolean准备就绪后自动播放hasPreviousboolean是否有上一首hasNextboolean是否有下一首isLiveboolean是否为直播流smartxplayer 模块导出export{SXPlayer,SXWorkerPlayer,SXBaseAudioPlayer,SXCastPlayer,ISXAudioPlayer}SXPlayer标准播放器适合短音频播放SXWorkerPlayerWorker 线程播放器避免阻塞 UISXBaseAudioPlayer基础播放器抽象类SXCastPlayer投播播放器ISXAudioPlayer播放器接口定义22.5 两套方案对比与选型建议对比维度TextReaderSXPlayer适用场景文本朗读诗词、汉字音频文件播放铃声、音乐输入类型文本字符串文件描述符fd系统依赖SpeechKit第三方模块朗读面板内置 UI 面板无 UI纯后台播放个性化支持品牌信息定制支持播放控制回调选型原则需要系统级朗读 UI 文本转语音 → TextReader需要播放预置音频文件 自定义控制逻辑 → SXPlayer两者可共存互不冲突本章小结本章介绍了「柚兔学伴」中语音交互的完整实现方案。TextReader 在 EntryAbility.onCreate 中初始化通过 PoemReader 工具类在诗词页、笔画页、首页卡片三处统一调用SXPlayer 则负责计时提醒等纯音频播放场景。两者各司其职共同构建了应用的语音交互体系。下一章将介绍字帖生成与 PDF 导出功能。