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

使用expo-notifications实现带动态内容的每周重复本地通知问题

解决expo-notifications每周动态随机名言通知的方案

别用expo-notifications自带的重复通知配置——它的重复通知内容是创建时就固定死的,没法动态更新。靠谱的做法是用单次通知+触发后自动创建下一次通知,这样每次触发前都能从本地JSON里挑随机名言生成新内容。

具体实现步骤

1. 准备本地名言库

把所有名言存在本地JSON文件(比如quotes.json):

[
  "人生如逆旅,我亦是行人。",
  "长风破浪会有时,直挂云帆济沧海。",
  "海内存知己,天涯若比邻。"
]

2. 写个随机选名言的工具函数

import quotes from './quotes.json';

const getRandomQuote = () => {
  const randomIndex = Math.floor(Math.random() * quotes.length);
  return quotes[randomIndex];
};

3. 封装创建单次周通知的函数

这个函数负责计算下一次触发时间(比如每周一早9点),再用随机名言生成通知:

import * as Notifications from 'expo-notifications';

const scheduleWeeklyQuoteNotification = async () => {
  // 计算下周一9点的时间点
  const now = new Date();
  let nextTrigger = new Date(now.setDate(now.getDate() + (1 - now.getDay() + 7) % 7));
  nextTrigger.setHours(9, 0, 0, 0);
  
  // 如果今天已经过了9点,就顺延到下下周的周一
  if (nextTrigger < new Date()) {
    nextTrigger.setDate(nextTrigger.getDate() + 7);
  }

  // 拿随机名言
  const randomQuote = getRandomQuote();

  // 创建单次通知
  await Notifications.scheduleNotificationAsync({
    content: {
      title: '每周一句',
      body: randomQuote,
    },
    trigger: {
      date: nextTrigger,
    },
  });
};

4. 配置后台任务,触发后自动续期

要让App在后台甚至被杀死时,也能自动创建下一次通知,得用expo的TaskManager配置后台任务:

4.1 先在app.json加权限配置

{
  "expo": {
    "ios": {
      "backgroundModes": ["remote-notifications"]
    },
    "android": {
      "permissions": ["RECEIVE_BOOT_COMPLETED"],
      "useNextNotificationsApi": true
    },
    "plugins": [
      [
        "expo-notifications",
        {
          "color": "#2196F3"
        }
      ]
    ]
  }
}

4.2 注册后台任务

import * as TaskManager from 'expo-task-manager';
import * as Notifications from 'expo-notifications';

const WEEKLY_QUOTE_TASK = 'weekly-quote-task';

// 定义后台任务:通知触发后,立刻安排下一周的通知
TaskManager.defineTask(WEEKLY_QUOTE_TASK, async () => {
  try {
    await scheduleWeeklyQuoteNotification();
  } catch (err) {
    console.error('续期通知失败:', err);
  }
});

// 把任务绑定到通知触发事件
Notifications.registerTaskAsync(WEEKLY_QUOTE_TASK);

4.3 App启动时初始化第一次通知

在App入口(比如App.js)加个初始化逻辑,确保第一次通知能被创建:

import { useEffect } from 'react';

useEffect(() => {
  const init = async () => {
    // 请求通知权限
    const { status } = await Notifications.requestPermissionsAsync();
    if (status !== 'granted') {
      alert('得开通知权限才能用这个功能哦');
      return;
    }

    // 检查有没有已安排的通知,没有就创建第一次
    const scheduled = await Notifications.getAllScheduledNotificationsAsync();
    if (scheduled.length === 0) {
      await scheduleWeeklyQuoteNotification();
    }
  };

  init();
}, []);

关键说明

  • 为什么不用自带的重复通知?因为expo的重复通知是“静态重复”——创建时的内容会被固定,每次触发都显示同一句话,没法动态替换。
  • 后台任务的兼容性:Android上要注意把App加到电池优化白名单,不然系统可能杀死后台任务;iOS上依赖系统的后台调度,稳定性没问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:01:22