- Split render into FieldTable/Fields/Icons/Layout/Settings modules - Add Fenix8V3Background, Owm (weather), Solar modules - Add tools/ generators (gen_fields/gen_icons/gen_themes/gen_preview_svg) - Tune README/manifest/strings/settings
87 lines
3.4 KiB
MonkeyC
87 lines
3.4 KiB
MonkeyC
import Toybox.Application;
|
||
import Toybox.Background;
|
||
import Toybox.Lang;
|
||
import Toybox.System;
|
||
import Toybox.Time;
|
||
import Toybox.WatchUi;
|
||
import Owm;
|
||
|
||
// ============================================================================
|
||
// 应用入口
|
||
// ----------------------------------------------------------------------------
|
||
// 表盘没有菜单也拿不到输入,所以这个壳子只做三件事:
|
||
// 1. 交出 view
|
||
// 2. 设置变更时请求重绘
|
||
// 3. 管理拉取 OpenWeatherMap 的后台服务
|
||
// ============================================================================
|
||
class Fenix8V3App extends Application.AppBase {
|
||
|
||
// OWM 免费档的调用额度很宽裕,但表盘每分钟才重绘一次、数据本身也是小时级的,
|
||
// 拉太勤只是白白唤醒射频费电。半小时是个合适的折中。
|
||
const OWM_PERIOD_MIN = 30;
|
||
|
||
function initialize() {
|
||
AppBase.initialize();
|
||
}
|
||
|
||
function onStart(state as Dictionary?) as Void {
|
||
}
|
||
|
||
function onStop(state as Dictionary?) as Void {
|
||
}
|
||
|
||
// ⚠️ 定时器的注册必须放在 getInitialView 里,不能放 onStart。
|
||
// 因为 onStart **在后台服务进程里也会被调用一次**,而在后台进程里调
|
||
// registerForTemporalEvent 会抛 Out of Bounds。
|
||
// getInitialView 只在前台进程运行,是安全的位置。
|
||
function getInitialView() as [Views] or [Views, InputDelegates] {
|
||
scheduleWeather();
|
||
return [new Fenix8V3View()];
|
||
}
|
||
|
||
function getServiceDelegate() as [System.ServiceDelegate] {
|
||
return [new Fenix8V3Background()];
|
||
}
|
||
|
||
// 只有用户真的填了 API key 才注册定时器 —— 没填就没什么可拉的,
|
||
// 注册了纯属浪费电。反过来,用户把 key 清空时也要及时注销。
|
||
function scheduleWeather() as Void {
|
||
if (!(Background has :registerForTemporalEvent)) { return; }
|
||
// ⚠️ deleteTemporalEvent 在「本来就没注册」时会抛 Out of Bounds,
|
||
// 而这个错误是 VM 级的,**try/catch 抓不住**。
|
||
// 所以这里不去问系统当前状态,而是自己在 Storage 里记一个标志位。
|
||
// 重复注册本身是无害的(只是重置周期),所以只在状态真的变化时动手。
|
||
var want = Owm.enabled();
|
||
var have = Application.Storage.getValue("bgOn");
|
||
have = (have != null) && (have as Boolean);
|
||
if (want == have) { return; }
|
||
if (want) {
|
||
Background.registerForTemporalEvent(
|
||
new Time.Duration(OWM_PERIOD_MIN * 60));
|
||
} else {
|
||
Background.deleteTemporalEvent();
|
||
}
|
||
Application.Storage.setValue("bgOn", want);
|
||
}
|
||
|
||
// 手机把新设置推下来时触发。
|
||
// view 每次绘制都是现读设置,所以重绘一下就够了;
|
||
// 但天气定时器要跟着新的 key 状态启停,所以先过一遍 scheduleWeather。
|
||
function onSettingsChanged() as Void {
|
||
scheduleWeather();
|
||
WatchUi.requestUpdate();
|
||
}
|
||
|
||
// 后台服务把结果通过这里交回前台。存进 Storage 供表盘读取,然后重绘。
|
||
function onBackgroundData(data as Application.PersistableType) as Void {
|
||
if (data != null) {
|
||
Application.Storage.setValue(Owm.STORE, data);
|
||
WatchUi.requestUpdate();
|
||
}
|
||
}
|
||
}
|
||
|
||
function getApp() as Fenix8V3App {
|
||
return Application.getApp() as Fenix8V3App;
|
||
}
|