使用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
相关产品推荐
相关产品推荐

