HarmonyOS for Kids' Education: Technical Deep-Dive into 'Shengqu Guoqitong' App
A HarmonyOS developer shares the full technical practice of building a children's flag-learning app, covering technology selection (Core Speech Kit, ArkTS, Stage model), core feature implementation (offline voice synthesis/recognition, canvas drawing, puzzle game), global state management with AppStorage, performance optimizations for 200+ flags, and future plans for multi-device collaboration and AI integration.
Project Overview
The author, a HarmonyOS developer, built "Shengqu Guoqitong" (声趣国旗通), a children's education app for learning national flags, targeting ages 5-8. The core design principles are cartoonish, ultra-simple, highly interactive . The article details the technology selection process, core feature implementations, data management, performance optimizations, and development insights.
Technology Selection: Why HarmonyOS?
Comparative Analysis of Mobile Frameworks
The author spent a week evaluating four mainstream solutions against five criteria: speech capability, development efficiency, performance, ecosystem maturity, and overall score.
HarmonyOS : Speech ⭐⭐⭐⭐⭐ (native, offline), Development ⭐⭐⭐⭐⭐ (ArkTS declarative UI), Performance ⭐⭐⭐⭐⭐ (native), Ecosystem ⭐⭐⭐⭐ (rapidly growing), Score 95
Android (Kotlin) : Speech ⭐⭐⭐ (requires third-party SDK), Development ⭐⭐⭐⭐ (Jetpack Compose), Performance ⭐⭐⭐⭐⭐ (mature, stable), Ecosystem ⭐⭐⭐⭐⭐ (complete), Score 85
Flutter : Speech ⭐⭐ (plugin-dependent, average), Development ⭐⭐⭐⭐⭐ (hot reload), Performance ⭐⭐⭐⭐ (near-native), Ecosystem ⭐⭐⭐⭐ (active community), Score 75
React Native : Speech ⭐⭐ (third-party plugins), Development ⭐⭐⭐ (moderate learning curve), Performance ⭐⭐⭐ (JS bridge overhead), Ecosystem ⭐⭐⭐⭐ (mature community), Score 65
HarmonyOS won due to decisive advantages in speech capability (core competitiveness) and development efficiency (65% faster). The final decision balanced technical ideals with commercial reality: the project was completed in 2 weeks instead of the estimated 6 weeks .
Five Core Reasons for Choosing HarmonyOS
1. Core Speech Kit: Killer Feature for Children's Education
Why voice interaction matters for 5-8 year olds:
Limited literacy (~500-1500 characters); complex text UIs hinder experience.
Children prefer verbal expression; voice interaction matches cognitive habits.
Multimodal stimulation (voice + visual) boosts memory retention by 60%+ (educational psychology research).
Core Speech Kit technical advantages:
True offline capability, zero network dependency. Compared to third-party SDKs (iFlytek, Baidu) that require cloud API calls (200-500ms latency, ~¥0.002/call, privacy upload), Core Speech Kit runs fully offline, latency <50ms , zero cost, no call limits, local data processing compliant with children's privacy regulations. Real-world test: all voice features work in subway/airplane mode.
Mandarin recognition accuracy 95.5% (tested with 10 children speaking 20 country names). Outperforms iFlytek (92.3%), Baidu (89.7%), Google Speech (76.2%). Specifically optimized for children's voices and dialect tolerance.
Flexible pause control and speech rate adjustment via SSML. Example:
const text = `China's capital is Beijing[p500] Currency is RMB[p500] Language is Mandarin[p1000] Remember?`;Traditional TTS reads in one breath; children can't keep up.
Multiple voice styles (6 voices). Selected standard female voice (person: 0) + interaction-broadcast style; highest child acceptance in testing.
2. ArkTS + ArkUI: Development Efficiency Tripled
Declarative UI revolution: The author prototyped the same continent card (rounded corners, shadow, gradient background, click animation) in three frameworks:
HarmonyOS ArkTS: 15 lines, single file.
Android XML + Kotlin: 35 lines, requires XML + Kotlin + resource files (gradient_bg.xml, click listeners).
Flutter: 25 lines, relatively concise but deep nesting.
Elegant state management: ArkTS provides @State, @Link, @StorageLink decorators for reactive state. Example:
@StorageLink('volume') volume: number = 50; Slider({ value: this.volume }).onChange((value) => { this.volume = value; // auto-triggers updates across all components })This approach is 50%+ more concise than Redux/Vuex with near-zero learning cost.
3. Stage Model: True "Write Once, Deploy Multi-Device"
Stage model supports multi-device form factors at architecture level, not just responsive layout. Configuration in module.json5: "deviceTypes": ["phone", "tablet", "2in1", "tv"]. Responsive grid layout example:
Grid() { ForEach(this.continents, (item) => { GridItem() { ContinentCard(item) } }) }.columnsTemplate('1fr 1fr') // phone: 2 columns // future tablet: .columnsTemplate('1fr 1fr 1fr') // 3 columnsDistributed collaboration vision: Phone → one-hop flow → Smart screen (family learning) → data sync → Tablet (seamless continuation). This device synergy is difficult in iOS/Android ecosystems.
4. DevEco Studio: Delightful Toolchain
Smart code completion >90% accuracy: component property suggestions, quick Kit module imports, real-time syntax checking. Typing Text() auto-suggests all properties sorted by usage frequency, drastically reducing doc lookup.
Previewer real-time rendering:
@Preview @Component struct ContinentCardPreview { build() { ContinentCard('Asia', '48 countries', $r('app.color.continent_asia')) } }UI updates within 0.5 seconds after save, >10x faster than traditional compile-install-run cycle.
5. Ecosystem Dividend: Catching HarmonyOS Growth Window
Official Huawei data (2024): 800M+ HarmonyOS devices , 2.54M+ developers , ecosystem covering 18 domains. Early entrant benefits: more app market exposure, strong official support (technical resources, traffic), less competition (scarce quality children's education apps). Technical forward-looking: HarmonyOS has shed AOSP legacy, enabling deeper system optimization, unified design language, long-term evolution roadmap. Choosing HarmonyOS means growing with China's autonomous OS.
Core Feature Implementation: From Zero to One
Feature 1: Voice Broadcast — Making Flags "Speak"
Challenge: Text display has high cognitive barrier for 5-8 year olds.
Solution: Deep integration of Core Speech Kit TTS. Encapsulated TextToSpeechManager singleton:
// TextToSpeechManager.ets (simplified)
import { textToSpeech } from '@kit.CoreSpeechKit';
export class TextToSpeechManager {
private static instance: TextToSpeechManager;
private ttsEngine: textToSpeech.TextToSpeechEngine | null = null;
createEngine() {
let initParamsInfo: textToSpeech.CreateEngineParams = {
language: 'zh-CN',
person: 0, // voice: standard female
online: 1, // offline mode
extraParams: {
"style": "interaction-broadcast", // interactive broadcast style
"locate": "CN"
}
};
textToSpeech.createEngine(initParamsInfo, (err, engine) => {
if (!err) {
this.ttsEngine = engine;
console.info('TTS engine created');
}
});
}
speak(text: string) {
if (this.ttsEngine?.isBusy()) {
this.ttsEngine?.stop();
}
const speakParams = {
requestId: new Date().getTime().toString(),
extraParams: {
"speed": AppModel.speed, // user-adjustable rate
"volume": AppModel.volume, // user-adjustable volume
"pitch": 1
}
};
this.ttsEngine?.speak(text, speakParams);
}
}Technical highlights:
Smart pause control: Used [p500] SSML tags in flag detail page:
const text = `${country.name}'s capital is ${country.capital}[p500] Currency is ${country.currency}[p500] Language is ${country.language}`;Makes speech natural, easier for kids to understand.
State management: isBusy() prevents overlapping audio streams.
User-configurable: Settings page provides volume/speed sliders (
@Builder SettingsSlider() { Row() { Text('Volume:') Slider({ value: this.volume, min: 0, max: 100 }).onChange((value) => { AppModel.volume = value; }) } }).
Feature 2: Speech Recognition — Kids "Speak" Answers
Challenge: Traditional multiple-choice/fill-in-blank too complex for young children.
Solution: Core Speech Kit ASR for voice quiz. Implemented "press-to-talk, release-to-recognize" interaction:
// TestDetailPage.ets (core logic)
Button() { Image($r('app.media.ic_microphone')).height(36).width(36) }
.onTouch(async (event: TouchEvent) => {
if (event.type == TouchType.Down) {
await this.requestPermission(async (isAuth) => {
if (isAuth) {
await SpeechRecognizerManager.getInstance().startRecording();
} else {
this.showPermissionAlert(); // guide user to grant permission
}
});
} else if (event.type == TouchType.Up) {
SpeechRecognizerManager.getInstance().finishRecognizer();
this.checkAnswer();
}
})SpeechRecognizerManager core implementation:
export class SpeechRecognizerManager {
private asrEngine: speechRecognizer.SpeechRecognitionEngine | null = null;
createEngine() {
let initParamsInfo: speechRecognizer.CreateEngineParams = {
language: 'zh-CN',
online: 1, // offline mode
extraParams: {
"recognizerMode": "short" // short utterance mode (<60s)
}
};
speechRecognizer.createEngine(initParamsInfo, (err, engine) => {
if (!err) this.asrEngine = engine;
});
}
initListener(onResult?: (result: string) => void) {
const listener = {
onResult(sessionId: string, result: speechRecognizer.SpeechRecognitionResult) {
const cleanText = result.result.replace(/[\p{P}\p{S}]/gu, ''); // remove punctuation
if (onResult) onResult(cleanText);
},
onComplete(sessionId: string) { console.info('Recognition complete'); },
onError(sessionId: string, errorCode: number, errorMessage: string) {
console.error(`Recognition failed: ${errorMessage}`);
}
};
this.asrEngine?.setListener(listener);
}
}Technical highlights:
Permission optimization: Dynamic microphone permission request via abilityAccessCtrl with friendly guide dialog on denial.
Smart answer matching: Punctuation removed, fuzzy match with includes():
handlerAnswer() { const isCorrect = this.yourAnswer.includes(this.country.name); const result = isCorrect ? 'Correct!' : 'Wrong, try again'; SilToast.showToast(this.getUIContext(), result); TextToSpeechManager.getInstance().speak(result); }Audio stream handling: AudioCapturer feeds real-time mic data into ASR engine:
this.mAudioCapturer.init((dataBuffer: ArrayBuffer) => { let uint8Array = new Uint8Array(dataBuffer); this.asrEngine?.writeAudio(this.sessionId, uint8Array); });Feature 3: Canvas Drawing — Memorizing Flags by Hand
Challenge: Psychology research shows hands-on practice improves memory retention 3x+ over passive viewing.
Solution: ArkTS Canvas-based flag drawing. Core drawing logic:
// FlagDrawingPage.ets (core drawing logic)
Canvas(this.context)
.width('100%')
.height('100%')
.onTouch((event) => {
if (event.type === TouchType.Down) {
this.x = event.touches[0].x;
this.y = event.touches[0].y;
this.context.beginPath();
this.tempPath = new Path2D();
this.tempPath.moveTo(this.x, this.y);
}
if (event.type === TouchType.Move) {
if (this.isEraserMode) {
this.context.clearRect(event.touches[0].x, event.touches[0].y, 20, 20);
} else {
this.context.strokeStyle = this.penColorList[this.penColor];
this.tempPath.lineTo(event.touches[0].x, event.touches[0].y);
this.context.stroke(this.tempPath);
}
}
})Technical highlights:
Real-time rendering optimization: Path2D object caches path, reduces redraws: private tempPath: Path2D = new Path2D(); Shape tools: Rectangle, circle, triangle drawing. Circle example:
if (this.shapeNum === 1) { let radius = Math.sqrt((x - x0)**2 + (y - y0)**2); this.context.arc(x0, y0, radius, 0, 360); this.context.fillStyle = this.penColor; this.context.fill(); }Reference image: Target flag displayed above canvas to lower difficulty:
Column() { Image(this.flagSrc).height('20%').padding(16) }Feature 4: Flag Sliding Puzzle — Gamified Learning
Challenge: Pure memorization bores kids; need gamification.
Solution: Configurable puzzle system using ArkTS.
// PinTuPage.ets (config-driven design)
@StorageLink('GameConfig') gameConfig: FigMessage = {
w: 1000, // image width
h: 500, // image height
rows: 2, // rows
cols: 3, // columns
isOver: false, // completion flag
imgUrl: $rawfile('images/guoqi/az.png')
};Technical highlights:
Dynamic difficulty: User selects 2x2, 3x3, etc. Grid renders pieces:
Grid() { ForEach(this.pieces, (piece: Piece) => { GridItem() { Image(piece.imgSrc).width(this.pieceWidth).height(this.pieceHeight) }.onClick(() => this.movePiece(piece)) }) }.columnsTemplate(this.gameConfig.cols.toString()).rowsTemplate(this.gameConfig.rows.toString())Shuffle algorithm: Fisher-Yates ensures solvable initial state:
shuffle() { for (let i = this.pieces.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [this.pieces[i], this.pieces[j]] = [this.pieces[j], this.pieces[i]]; } }Win detection: Real-time check:
checkWin() { return this.pieces.every((piece, index) => piece.currentIndex === piece.correctIndex); }Data Management: Leveraging AppStorage for State Sharing
Challenge: Sharing user settings (volume, speech rate) and app state across multiple pages.
Solution: HarmonyOS AppStorage (global singleton) for app-level state:
// AppModel.ets (global state management)
export class AppModel {
static volume: number = 50; // volume
static speed: number = 1.0; // speech rate
static firstBroadcast: boolean = true; // first broadcast flag
static currentIndex: number = 0; // current tab index
static tabsController = new TabsController();
}
// In component
@StorageLink('volume') volume: number = 50;
Slider({ value: this.volume })
.onChange((value) => {
AppModel.volume = value; // globally effective
})Why not LocalStorage? AppStorage is global singleton, suitable for app-level state. LocalStorage suits page-level state isolation. PersistentStorage for data needing persistence (e.g., favorites list). @StorageLink achieves two-way binding; changes sync immediately to all pages.
Performance Optimization: Smooth Rendering of 200+ Flags
The app contains 201 countries with flags and details. Optimization strategies:
1. Data Lazy Loading
// Load only current continent's countries
export function getCountriesByContinent(continent: string): Country[] {
return COUNTRIES.filter(country => country.continent === continent);
}2. Virtual List Rendering
List() {
LazyForEach(this.dataSource, (country: Country) => {
ListItem() { CountryCard(country) }
})
}.cachedCount(5) // cache 5 items3. Image Resource Optimization
Use $rawfile for local assets, avoiding network requests.
Flag images uniformly compressed to under 50KB . .objectFit(ImageFit.ScaleDown) maintains aspect ratio.
Development Insights: Three HarmonyOS Surprises
1. Core Speech Kit Is Truly Powerful
Previously, voice features required third-party SDK integration (complex config, high cost). HarmonyOS native offline speech eliminates those pains. Mandarin recognition accuracy >95% (real-tested) , fully meeting children's education needs.
2. ArkTS Declarative UI Doubles Efficiency
Example: Card with rounded corners and shadow in ArkTS:
Column() { Text('Card content') }.borderRadius(16).shadow({ radius: 8, color: '#1A000000' })Traditional XML+code requires at least 10 lines.
3. Stage Model Lifecycle Management Is Clearer
aboutToAppear()and aboutToDisappear() simplify resource management:
aboutToAppear() {
TextToSpeechManager.getInstance().createEngine();
}
aboutToDisappear() {
TextToSpeechManager.getInstance().stop(); // prevent memory leaks
}Future Outlook: Embracing HarmonyOS Ecosystem Possibilities
Current core features done; planned enhancements:
Multimodal interaction: Leverage device collaboration for phone+tablet dual-screen learning.
AI capability upgrade: Integrate HarmonyOS AI Kit for personalized learning recommendations.
Distributed data sync: Automatic progress sync across devices.
Accessibility optimization: Deep adaptation of HarmonyOS accessibility framework for special-needs children.
Conclusion: Technology's Warmth Lies in Serving People
The author believes good technology should serve people. "Shengqu Guoqitong" is both a technical practice and a reflection on "how to make children's education better with technology." HarmonyOS capabilities turned concept into reality, and the developer invites fellow HarmonyOS developers and children's education enthusiasts to collaborate. "Let's use code to create a better future for kids."
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
51CTO HarmonyOS Developer Community
The HarmonyOS Developer Community is a learning-oriented community for developers to learn, communicate, ask questions, and share.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
