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

React Native(Expo)实现无限期本地定时通知的最优方案

最优实现方案(基于Expo,无需Eject)

核心技术栈

依赖Expo官方提供的 expo-notifications(本地通知调度)、expo-task-manager(后台任务管理)、expo-background-fetch(后台定时唤醒),完全无需Eject即可实现需求。


分步实现

1. 配置权限与项目设置

在app.json中声明后台运行权限与通知相关配置:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "UIBackgroundModes": ["fetch", "remote-notification"]
      }
    },
    "android": {
      "permissions": ["RECEIVE_BOOT_COMPLETED", "SCHEDULE_EXACT_ALARM"],
      "useNextNotificationsApi": true
    },
    "plugins": [
      [
        "expo-notifications",
        {
          "icon": "./assets/notification-icon.png",
          "color": "#2196F3",
          "sounds": ["./assets/notification-sound.wav"]
        }
      ]
    ]
  }
}
  • iOS:开启fetch后台模式,允许系统唤醒App执行后台任务
  • Android:添加开机自启与精确闹钟权限,确保任务在重启后仍能生效

2. 注册每周后台任务

定义一个用于生成当周通知的后台任务,包含清除旧通知、读取用户配置、生成动态通知逻辑:

import * as TaskManager from 'expo-task-manager';
import * as Notifications from 'expo-notifications';
import * as BackgroundFetch from 'expo-background-fetch';
import AsyncStorage from '@react-native-async-storage/async-storage';

// 任务唯一标识
const WEEKLY_NOTIFICATION_TASK = 'weekly-notification-setup';

// 注册后台任务
TaskManager.defineTask(WEEKLY_NOTIFICATION_TASK, async () => {
  try {
    // 清除上周遗留的通知
    await Notifications.cancelAllScheduledNotificationsAsync();

    // 获取用户自定义配置(从AsyncStorage读取)
    const storedConfigs = await AsyncStorage.getItem('userNotificationConfigs');
    const userConfigs = JSON.parse(storedConfigs) || [];

    // 计算当前周的周日基准日期
    const now = new Date();
    const sunday = new Date(now.setDate(now.getDate() - now.getDay()));

    // 遍历用户配置,生成当周对应通知
    for (const config of userConfigs) {
      // 计算本周对应星期的目标日期
      const targetDate = new Date(sunday);
      targetDate.setDate(sunday.getDate() + config.weekDay); // 0=周日,1=周一...
      targetDate.setHours(config.hour, config.minute, 0);

      // 生成动态通知内容(示例:根据日期和配置生成文本)
      const notificationContent = {
        title: `本周${getWeekDayName(config.weekDay)}提醒`,
        body: config.contentTemplate.replace('{{date}}', formatDate(targetDate)),
      };

      // 调度本地通知
      await Notifications.scheduleNotificationAsync({
        content: notificationContent,
        trigger: { date: targetDate },
      });
    }

    // 返回任务成功状态,告知系统任务完成
    return BackgroundFetch.Result.NewData;
  } catch (err) {
    console.error('每周通知生成失败:', err);
    return BackgroundFetch.Result.Failed;
  }
});

// 辅助工具函数
function getWeekDayName(day) {
  return ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][day];
}

function formatDate(date) {
  return `${date.getMonth() + 1}月${date.getDate()}日`;
}

3. 启动后台定时任务

在App初始化时(如App.js的useEffect中)完成权限请求、任务注册与首次执行:

import { useEffect } from 'react';
import * as Notifications from 'expo-notifications';
import * as BackgroundFetch from 'expo-background-fetch';

useEffect(() => {
  async function initBackgroundTask() {
    // 请求通知权限
    const { status } = await Notifications.requestPermissionsAsync();
    if (status !== 'granted') {
      alert('请开启通知权限,否则无法使用提醒功能');
      return;
    }

    // 注册后台任务(仅当未注册时)
    const isRegistered = await TaskManager.isTaskRegisteredAsync(WEEKLY_NOTIFICATION_TASK);
    if (!isRegistered) {
      await BackgroundFetch.registerTaskAsync(WEEKLY_NOTIFICATION_TASK, {
        minimumInterval: 7 * 24 * 60 * 60, // 每周触发一次(单位:秒)
        stopOnTerminate: false, // Android:App终止后仍保留任务
        startOnBoot: true, // Android:设备重启后自动启动任务
      });
    }

    // 首次启动时立即执行一次,避免用户等待一周
    await TaskManager.executeTaskAsync(WEEKLY_NOTIFICATION_TASK);
  }

  initBackgroundTask();
}, []);

4. 动态内容与配置持久化

  • 用户的自定义时间、星期、内容模板需通过AsyncStorage持久化存储,后台任务读取后动态生成通知内容
  • 若需更复杂的动态内容(如结合本地数据、时区信息),可在后台任务中直接编写计算逻辑,无需依赖外部接口

关键注意事项

  • iOS后台Fetch受系统调度限制,无法保证精确在周日触发,若需更高精度,可额外设置一个周日的触发通知,在通知回调中执行任务
  • Android 12+的SCHEDULE_EXACT_ALARM权限需用户手动授权,需在App中引导用户前往系统设置开启
  • 后台任务执行时间有限制(iOS最多30秒,Android最多10分钟),需保证任务逻辑简洁高效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:50:28