- Qt 4.7 / QML 1.1 application for Symbian Belle (Nokia C7 class), self-signed SIS deployment.
- Generated from the qt-symbian-belle-starter template.
- See
docs/PLAN.mdfor milestones,docs/DEVICE_NOTES.mdfor the device experiment log. - Xiaoyuzhou FM API:
docs/API_NOTES.mdis the working reference. Its source of truth is the ultrazg/xyz Go proxy (v1.10.0), cloned locally atC:\Users\liya\Repos\xyz-go— readdoc/docs/*.md(per-endpoint docs) andhandlers/*.go+service/service.go+constant/url.go(real request/response shapes) directly. No need to run the localhost:23020 proxy to look something up.
- C++ managers in
src/are exposed to QML viasetContextPropertyinmain.cpp:storage(StorageManager),memoryMonitor,tlsChecker,audioEngine. StorageManagerhandles SQLite with multi-candidate writable-path fallback.- QML uses Symbian Components 1.1;
AppWindow.qmlis the root, pages live inqml/.
- NEVER write the
positionproperty on a QMLAudioelement — causes KErrMMAudioDevice (-12014) and bricks ALL audio until phone restart. Drive playback through the C++audioEngine(QMediaPlayer::setPosition()). - Data caging:
/private/<UID>/dirs are writable but invisible toQDir::exists(). Skip exists/mkpath checks and go straight to an I/O test. - SQL driver: prefer
QSYMSQLoverQSQLITEon Symbian. Test with the same driver production code uses. - Path separators: use
QDir::toNativeSeparators()for paths passed to SQL drivers on Symbian.
- No block expressions in property bindings — use a helper function or ternary.
- No named function declarations inside non-root elements — declare functions
at the
Page/root level only. - No negative anchor margins — size a larger
Itemfor touch targets instead. - SVG icon sizing: Symbian renders icons using the SVG
viewBoxdimensions, ignoringwidth/height. To resize, change both thewidth/heightand theviewBox, wrapping paths in<g transform="scale(factor)">.
- Status-panel notifications use the Pigler Notifications API (PNA) — a separate
on-device server the user installs (
Pigler.sisfrom nnproject.cc/pna). The app degrades gracefully without it. This pattern is the reusable way to add any notification to a self-signed Belle app. NowPlayingNotifier(context propertynotifier) wraps the vendoredQPiglerAPI(src/pigler/, from upstreampiglerorg/pigler) and observesplayer. All Pigler code is under#ifdef Q_OS_SYMBIAN; off-Symbian the class is a no-op so the simulator still builds. Tap → app foreground +handleTapsignal → QML (openEpisodeForCurrent). Lifecycle is state-keyed (Playing/Paused).- Build: vendored sources +
LIBS += -lrandom -laknnotifygo ONLY in thesymbian {}scope ofXyz.pro; no capability beyond the four already self-signed. - Gotcha — removeOnTap: Pigler's server default is remove-on-tap, so a tap
deletes the notification. For a persistent one, call
setRemoveOnTap(id, false)at creation (alongsidesetLaunchAppOnTap(id, true)). - Gotcha — slots behind
#ifdef: moc processes headers on every platform, but a slot declared inside#ifdef Q_OS_SYMBIANis missing from the meta-object on other platforms, so a string-basedconnect(SIGNAL(...), SLOT(...))wires up to nothing — silently, at runtime. Declare such slots unconditionally; guard only the body. Compile-checks (both simulator and ARM) will NOT catch this.
- After ANY audio/media/platform-API experiment, record it in
docs/DEVICE_NOTES.mdwith a dated heading (## YYYY-MM-DD — Title), including error codes and failed approaches. Read it before touching audio/media code — Symbian MMF is fragile.