You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tizen穿戴设备后台定时提醒APP开发问题求助

Tizen穿戴设备后台定时提醒解决方案

问题根源

基于Web的Tizen应用切换到后台后,JavaScript执行线程会被系统挂起,setInterval这类前端定时机制无法持续工作。仅添加background-category不足以让应用在后台保持活跃,需要使用Tizen提供的Alarm API或**后台服务(Service Application)**来实现可靠的后台定时提醒。


方案一:使用Alarm API(推荐,适合定时提醒场景)

Alarm API是Tizen专门用于定时任务的原生接口,即使应用在后台或未运行,也能触发提醒,无需保持应用持续运行。

1. 确认config.xml配置

你已添加alarm权限,无需额外调整,原配置可保留:

<tizen:privilege name="http://tizen.org/privilege/alarm"/>

2. 重写main.js,替换setInterval为Alarm

核心逻辑:设置重复闹钟,触发时自动唤醒执行提醒操作,用本地存储保存任务信息供回调使用。

document.addEventListener('DOMContentLoaded', function () {
    var taskForm = document.getElementById('taskForm');
    var stopButton = document.getElementById('stopButton');
    var message = document.getElementById('message');
    var currentAlarmId = null;

    // 监听物理返回键,隐藏应用而非退出
    document.addEventListener('tizenhwkey', function(e) {
        if (e.keyName === 'back') {
            try {
                tizen.application.getCurrentApplication().hide();
            } catch (err) {
                console.error(err.message);
            }
        }
    });

    // 闹钟触发时的回调逻辑
    function onAlarmTriggered(alarmId) {
        if (alarmId !== currentAlarmId) return;
        
        try {
            // 唤醒屏幕
            tizen.power.turnScreenOn();
            // 震动提醒
            navigator.vibrate(1000);
            // 获取存储的任务名称
            var taskName = localStorage.getItem('currentTaskName');
            // 发送通知
            var notificationDict = {
                content: `Time to do: ${taskName}`,
                vibration: true,
                iconPath: "icon.png"
            };
            var notification = new tizen.UserNotification('SIMPLE', 'Task Reminder', notificationDict);
            tizen.notification.post(notification);
        } catch (error) {
            console.error("Error: " + error.message);
        }
    }

    taskForm.addEventListener('submit', function (e) {
        e.preventDefault();
        // 清除已有闹钟
        if (currentAlarmId) {
            try {
                tizen.alarm.remove(currentAlarmId);
            } catch (err) {
                console.error(err.message);
            }
        }

        var taskName = document.getElementById('taskName').value;
        // 这里改为小时单位,若需秒级可调整为interval * 1000
        var intervalHours = parseInt(document.getElementById('interval').value);
        // 存储任务名称,供闹钟触发时读取
        localStorage.setItem('currentTaskName', taskName);

        // 创建重复闹钟:首次触发为当前时间+间隔,之后每隔相同间隔重复
        var alarm = tizen.alarm.createAbsoluteRepeatAlarm(
            new Date(Date.now() + intervalHours * 3600 * 1000),
            intervalHours * 3600 * 1000,
            onAlarmTriggered
        );
        currentAlarmId = alarm.id;

        message.textContent = `Reminder for ${taskName} set every ${intervalHours} hours`;
    });

    stopButton.addEventListener('click', function () {
        if (currentAlarmId) {
            tizen.alarm.remove(currentAlarmId);
            currentAlarmId = null;
            localStorage.removeItem('currentTaskName');
            message.textContent = 'Reminder stopped';
        }
    });
});

方案说明

  • 支持RelativeAlarm(相对当前时间的间隔)和AbsoluteRepeatAlarm(绝对时间重复)两种类型,可根据需求切换。
  • 闹钟触发时,系统会自动唤醒应用执行回调,无需应用持续后台运行,更节省电量。

方案二:创建后台服务(Service Application)

如果需要复杂的持续后台逻辑,可创建独立的后台服务进程,与前台UI应用分离。

1. 创建后台服务项目

在Tizen Studio中新建Wearable Web Service Application项目,作为后台服务载体。

2. 配置前台APP的config.xml

添加后台服务关联,替换为你的服务ID:

<tizen:service-app id="UmkARFYyuP.IntervalService" package="UmkARFYyuP" required_version="7.0"/>

3. 后台服务的main.js(服务端)

负责接收前台指令,执行定时任务:

var intervalId;
var taskName;

// 监听前台传递的启动/停止指令
tizen.application.setAppControlListener({
    onReceived: function(appControl, appControlData) {
        if (appControl.operation === "http://tizen.org/appcontrol/operation/start") {
            taskName = appControlData[0].value;
            var intervalHours = parseInt(appControlData[1].value);
            var intervalMs = intervalHours * 3600 * 1000;

            // 启动定时任务
            intervalId = setInterval(function() {
                try {
                    tizen.power.turnScreenOn();
                    navigator.vibrate(1000);
                    var notificationDict = {
                        content: `Time to do: ${taskName}`,
                        vibration: true,
                        iconPath: "icon.png"
                    };
                    var notification = new tizen.UserNotification('SIMPLE', 'Task Reminder', notificationDict);
                    tizen.notification.post(notification);
                } catch (error) {
                    console.error("Error: " + error.message);
                }
            }, intervalMs);
        } else if (appControl.operation === "http://tizen.org/appcontrol/operation/stop") {
            if (intervalId) {
                clearInterval(intervalId);
                intervalId = null;
            }
        }
    }
});

// 服务启动日志
window.onload = function() {
    console.log("Background service started");
};

4. 修改前台APP的main.js,调用后台服务

替换原定时逻辑,改为向后台服务发送指令:

document.addEventListener('DOMContentLoaded', function () {
    var taskForm = document.getElementById('taskForm');
    var stopButton = document.getElementById('stopButton');
    var message = document.getElementById('message');

    taskForm.addEventListener('submit', function (e) {
        e.preventDefault();
        var taskName = document.getElementById('taskName').value;
        var intervalHours = parseInt(document.getElementById('interval').value);

        // 发送启动指令到后台服务
        var appControl = new tizen.ApplicationControl(
            "http://tizen.org/appcontrol/operation/start",
            null,
            null,
            [new tizen.ApplicationControlData("taskName", [taskName]),
             new tizen.ApplicationControlData("interval", [intervalHours.toString()])]
        );
        tizen.application.launchAppControl(
            appControl,
            "UmkARFYyuP.IntervalService",
            function() {
                message.textContent = `Reminder for ${taskName} set every ${intervalHours} hours (running in background)`;
            },
            function(error) {
                console.error("Failed to launch service: " + error.message);
            }
        );
    });

    stopButton.addEventListener('click', function () {
        // 发送停止指令到后台服务
        var appControl = new tizen.ApplicationControl(
            "http://tizen.org/appcontrol/operation/stop"
        );
        tizen.application.launchAppControl(
            appControl,
            "UmkARFYyuP.IntervalService",
            function() {
                message.textContent = 'Reminder stopped';
            },
            function(error) {
                console.error("Failed to stop service: " + error.message);
            }
        );
    });
});

方案说明

  • 后台服务是独立进程,不会因前台应用挂起而停止,适合需要持续后台运行的复杂场景。
  • 前台与后台通过ApplicationControl传递数据和指令,实现双向通信。

关键注意事项

  • 务必在真实设备上测试后台功能,模拟器的后台行为与真机存在差异。
  • 后台服务需合理控制资源消耗,避免过度耗电,Tizen系统会限制长期运行的后台进程。
  • 使用Alarm API时,避免设置过短的重复间隔,防止被系统判定为恶意应用。

内容的提问来源于stack exchange,提问作者Beel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 08:05:55