PythonIDE Docs
中文
简体中文

实时活动与后台任务

Live Activity、有限后台时间、后台刷新和完成通知。

演示 live_activity 启停与更新、background 有限后台时间与 notification 收尾提醒。

#预期效果

运行后会出现实时活动与后台任务控制页,进度、后台刷新和完成通知状态会同步显示。

#完整示例

python
import time

import appui
import background
import haptics
import live_activity
import notification

state = appui.State(
    title="同步任务",
    message="准备开始",
    progress=0.0,
    status="未启动",
    remaining="--",
    supported=False,
)


def set_title(value):
    state.title = value


def set_message(value):
    state.message = value


def set_progress(value):
    progress = max(0.0, min(1.0, float(value)))
    state.batch_update(progress=progress, status=f"进度草稿:{progress:.0%}")


def refresh_support():
    supported = live_activity.is_supported()
    state.batch_update(
        supported=supported,
        status="支持 Live Activity" if supported else "当前设备或系统不支持 Live Activity",
        remaining=f"{background.remaining_time():.0f} 秒",
    )


def start_activity():
    if not live_activity.is_supported():
        state.status = "当前设备不支持 Live Activity"
        haptics.notification("warning")
        return
    live_activity.start(
        title=state.title,
        message=state.message,
        progress=state.progress,
        icon="arrow.triangle.2.circlepath",
        compact_text=f"{state.progress:.0%}",
    )
    state.status = "Live Activity 已启动"
    haptics.notification("success")


def update_activity():
    live_activity.update(
        title=state.title,
        message=state.message,
        progress=state.progress,
        compact_text=f"{state.progress:.0%}",
    )
    state.status = "已更新 Live Activity"
    haptics.selection()


def begin_background_window():
    ok = background.begin_task()
    state.batch_update(
        status="已申请有限后台时间" if ok else "无法申请后台时间",
        remaining=f"{background.remaining_time():.0f} 秒",
    )
    haptics.notification("success" if ok else "error")


def end_workflow():
    live_activity.end(message="任务完成", dismiss_delay=2.0)
    background.end_task()
    notification.request_permission()
    notification.schedule(
        "live-activity-demo-complete",
        state.title,
        "任务已完成",
        delay=1,
    )
    state.batch_update(status="已结束并安排通知", progress=1.0)
    haptics.notification("success")


def schedule_refresh():
    ok = background.schedule_refresh("app.pythonide.demo.refresh", time.time() + 1800)
    state.status = "已提交后台刷新请求" if ok else "后台刷新请求提交失败"


def body():
    return appui.NavigationStack(
        appui.Form(
            [
                appui.Section(
                    [
                        appui.LabeledContent(
                            "Live Activity",
                            value="支持" if state.supported else "未知",
                        ),
                        appui.LabeledContent("剩余后台时间", value=state.remaining),
                        appui.Button("刷新状态", action=refresh_support),
                    ],
                    header="能力",
                ),
                appui.Section(
                    [
                        appui.TextField("标题", text=state.title, on_change=set_title),
                        appui.TextField("状态文案", text=state.message, on_change=set_message),
                        appui.Slider(
                            value=state.progress,
                            minimum=0,
                            maximum=1,
                            on_change=set_progress,
                        ),
                        appui.ProgressView("进度", value=state.progress),
                    ],
                    header="任务",
                ),
                appui.Section(
                    [
                        appui.Button("启动 Live Activity", action=start_activity)
                            .button_style("bordered_prominent"),
                        appui.Button("更新 Live Activity", action=update_activity),
                        appui.Button("申请后台时间", action=begin_background_window),
                        appui.Button("提交后台刷新", action=schedule_refresh),
                        appui.Button("结束任务并通知", action=end_workflow)
                            .foreground_color("systemGreen"),
                    ],
                    header="操作",
                    footer="后台任务由系统调度,不能保证立即执行或永久运行。",
                ),
                appui.Section(
                    [appui.LabeledContent("状态", value=state.status)],
                    header="结果",
                ),
            ]
        ).navigation_title("实时任务")
    )


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

#关键技巧

  • begin_taskend_task 成对使用;schedule_refresh 由系统决定实际执行时机。
  • Live Activity 适合短期可见进度,不适合当作长期保活方案。
  • 用 UI 明确展示是否支持 Live Activity、后台剩余时间与当前流程状态。
  • 拖动进度条只更新本地草稿;需要推送到 Live Activity 时再点击“更新 Live Activity”,避免高频滑动反复调用系统能力。