PythonIDE Docs
中文
简体中文

通知提醒 MiniApp

notification 权限、本地提醒、取消操作和 storage 表单偏好。

演示 notification 请求权限与 schedule,并用 storage 持久化表单偏好。

#预期效果

运行后会出现通知提醒表单,权限、延迟分钟、本地提醒和取消操作都有可见反馈。

#完整示例

python
import appui
import notification
import storage

STORE_KEY = "reminder_demo_settings"

state = appui.State(
    title="喝水提醒",
    body="该休息一下了",
    minutes=30,
    sound=True,
    status="未安排",
    loaded=False,
)


def load_saved_settings():
    if state.loaded:
        return
    state.loaded = True
    saved = storage.get_json(STORE_KEY, default={}) or {}
    state.title = saved.get("title", state.title)
    state.body = saved.get("body", state.body)
    state.minutes = int(saved.get("minutes", state.minutes))
    state.sound = bool(saved.get("sound", state.sound))


def save_settings():
    storage.set_json(STORE_KEY, {
        "title": state.title,
        "body": state.body,
        "minutes": state.minutes,
        "sound": state.sound,
    })


def set_title(value):
    state.title = str(value)
    save_settings()


def set_body(value):
    state.body = str(value)
    save_settings()


def set_minutes(value):
    state.minutes = int(value)
    save_settings()


def set_sound(value):
    state.sound = bool(value)
    save_settings()


def schedule_reminder():
    perm = notification.request_permission()
    if not isinstance(perm, dict) or not perm.get("granted"):
        state.status = "通知权限未开启"
        return

    delay = max(1, int(state.minutes)) * 60
    result = notification.schedule(
        "demo-reminder",
        state.title,
        state.body,
        delay=delay,
        sound=state.sound,
    )
    if isinstance(result, dict) and result.get("success"):
        state.status = f"已安排:{state.minutes} 分钟后提醒"
    else:
        state.status = f"安排失败:{result}"


def cancel_reminder():
    notification.remove_pending("demo-reminder")
    state.status = "已取消待发提醒"


def body():
    return appui.NavigationStack(
        appui.Form(
            [
                appui.Section(
                    [
                        appui.TextField("标题", text=state.title, on_change=set_title),
                        appui.TextField("内容", text=state.body, on_change=set_body),
                        appui.Stepper(
                            "延迟分钟",
                            value=state.minutes,
                            minimum=1,
                            maximum=240,
                            on_change=set_minutes,
                        ),
                        appui.Toggle("声音", is_on=state.sound, on_change=set_sound),
                    ],
                    header="提醒内容",
                ),
                appui.Section(
                    [
                        appui.Button("安排提醒", action=schedule_reminder)
                            .button_style("bordered_prominent"),
                        appui.Button("取消提醒", action=cancel_reminder)
                            .button_style("bordered"),
                        appui.LabeledContent("状态", value=state.status),
                    ],
                    header="操作",
                ),
            ]
        ).navigation_title("通知提醒")
    ).on_appear(load_saved_settings)


appui.run(body, state=state, presentation="fullscreen_with_close")

#关键技巧

  • request_permission(),再用稳定 identifier 调用 schedule / remove_pending 便于覆盖或取消。
  • request_permission() 返回 dict,无需 json.loads
  • 用户偏好用 storage.get_json / set_jsonon_appearon_change 中同步。