- 在项目中引入expo-notifications库,支持本地推送通知功能 - 实现通知权限管理,用户可选择开启或关闭通知 - 新增通知发送、定时通知和重复通知功能 - 更新个人页面,集成通知开关和权限请求逻辑 - 编写推送通知功能实现文档,详细描述功能和使用方法 - 优化心情日历页面,确保数据实时刷新
376 lines
9.0 KiB
Markdown
376 lines
9.0 KiB
Markdown
# 推送通知功能使用指南
|
||
|
||
## 快速开始
|
||
|
||
### 1. 安装依赖
|
||
|
||
推送通知功能已经集成到项目中,无需额外安装依赖。
|
||
|
||
### 2. 基本使用
|
||
|
||
在组件中使用推送通知功能:
|
||
|
||
```typescript
|
||
import { useNotifications } from '@/hooks/useNotifications';
|
||
|
||
function MyComponent() {
|
||
const { sendNotification, sendWorkoutReminder } = useNotifications();
|
||
|
||
const handleSendNotification = async () => {
|
||
await sendNotification({
|
||
title: '测试通知',
|
||
body: '这是一个测试通知',
|
||
sound: true,
|
||
priority: 'high'
|
||
});
|
||
};
|
||
|
||
const handleSendWorkoutReminder = async () => {
|
||
await sendWorkoutReminder('运动提醒', '该开始今天的普拉提训练了!');
|
||
};
|
||
|
||
return (
|
||
// 你的组件内容
|
||
);
|
||
}
|
||
```
|
||
|
||
### 3. 使用辅助函数
|
||
|
||
```typescript
|
||
import { WorkoutNotificationHelpers, GoalNotificationHelpers } from '@/utils/notificationHelpers';
|
||
|
||
// 发送运动开始提醒
|
||
await WorkoutNotificationHelpers.sendWorkoutStartReminder('张三');
|
||
|
||
// 发送目标达成通知
|
||
await GoalNotificationHelpers.sendGoalAchievementNotification('张三', '每周运动3次');
|
||
|
||
// 安排每日运动提醒
|
||
await WorkoutNotificationHelpers.scheduleDailyWorkoutReminder('张三', 9, 0); // 每天上午9点
|
||
```
|
||
|
||
## 功能特性
|
||
|
||
### ✅ 已实现功能
|
||
|
||
- [x] 立即发送通知
|
||
- [x] 定时发送通知
|
||
- [x] 重复发送通知
|
||
- [x] 通知权限管理
|
||
- [x] 通知点击处理
|
||
- [x] 通知取消功能
|
||
- [x] 多种通知类型支持
|
||
- [x] 通知模板系统
|
||
- [x] 批量通知发送
|
||
- [x] 通知状态查询
|
||
|
||
### 📱 支持的通知类型
|
||
|
||
1. **运动相关**
|
||
- 运动开始提醒
|
||
- 运动完成通知
|
||
- 每日运动提醒
|
||
|
||
2. **目标相关**
|
||
- 目标达成通知
|
||
- 目标进度更新
|
||
- 目标截止提醒
|
||
|
||
3. **心情相关**
|
||
- 心情打卡提醒
|
||
- 每日心情提醒
|
||
|
||
4. **营养相关**
|
||
- 营养记录提醒
|
||
- 三餐提醒
|
||
|
||
5. **通用通知**
|
||
- 欢迎通知
|
||
- 成就通知
|
||
- 系统维护通知
|
||
|
||
## 详细使用示例
|
||
|
||
### 1. 在运动页面中使用
|
||
|
||
```typescript
|
||
import { WorkoutNotificationHelpers } from '@/utils/notificationHelpers';
|
||
|
||
// 运动开始时
|
||
const handleWorkoutStart = async () => {
|
||
await WorkoutNotificationHelpers.sendWorkoutStartReminder(userName);
|
||
// 开始运动逻辑
|
||
};
|
||
|
||
// 运动完成时
|
||
const handleWorkoutComplete = async (duration: number) => {
|
||
await WorkoutNotificationHelpers.sendWorkoutCompleteNotification(userName, duration);
|
||
// 完成运动逻辑
|
||
};
|
||
```
|
||
|
||
### 2. 在目标页面中使用
|
||
|
||
```typescript
|
||
import { GoalNotificationHelpers } from '@/utils/notificationHelpers';
|
||
|
||
// 目标达成时
|
||
const handleGoalAchieved = async (goalName: string) => {
|
||
await GoalNotificationHelpers.sendGoalAchievementNotification(userName, goalName);
|
||
// 目标达成逻辑
|
||
};
|
||
|
||
// 目标进度更新时
|
||
const handleGoalProgress = async (goalName: string, progress: number) => {
|
||
if (progress >= 50 && progress < 100) {
|
||
await GoalNotificationHelpers.sendGoalProgressNotification(userName, goalName, progress);
|
||
}
|
||
};
|
||
```
|
||
|
||
### 3. 在心情页面中使用
|
||
|
||
```typescript
|
||
import { MoodNotificationHelpers } from '@/utils/notificationHelpers';
|
||
|
||
// 安排每日心情打卡提醒
|
||
const setupMoodReminder = async () => {
|
||
await MoodNotificationHelpers.scheduleDailyMoodReminder(userName, 20, 0); // 每天晚上8点
|
||
};
|
||
```
|
||
|
||
### 4. 在营养页面中使用
|
||
|
||
```typescript
|
||
import { NutritionNotificationHelpers } from '@/utils/notificationHelpers';
|
||
|
||
// 安排营养记录提醒
|
||
const setupNutritionReminders = async () => {
|
||
await NutritionNotificationHelpers.scheduleNutritionReminders(userName);
|
||
};
|
||
```
|
||
|
||
## 通知模板使用
|
||
|
||
```typescript
|
||
import { NotificationTemplates } from '@/utils/notificationHelpers';
|
||
import { notificationService } from '@/services/notifications';
|
||
|
||
// 使用模板发送通知
|
||
const sendWorkoutNotification = async (userName: string) => {
|
||
const notification = NotificationTemplates.workout.start(userName);
|
||
await notificationService.sendImmediateNotification(notification);
|
||
};
|
||
|
||
const sendGoalNotification = async (userName: string, goalName: string) => {
|
||
const notification = NotificationTemplates.goal.achievement(userName, goalName);
|
||
await notificationService.sendImmediateNotification(notification);
|
||
};
|
||
```
|
||
|
||
## 权限管理
|
||
|
||
### 检查权限状态
|
||
|
||
```typescript
|
||
import { useNotifications } from '@/hooks/useNotifications';
|
||
|
||
function MyComponent() {
|
||
const { permissionStatus, requestPermission } = useNotifications();
|
||
|
||
const handleRequestPermission = async () => {
|
||
const status = await requestPermission();
|
||
if (status === 'granted') {
|
||
console.log('通知权限已授予');
|
||
} else {
|
||
console.log('通知权限被拒绝');
|
||
}
|
||
};
|
||
|
||
return (
|
||
<View>
|
||
<Text>权限状态: {permissionStatus}</Text>
|
||
<Button title="请求权限" onPress={handleRequestPermission} />
|
||
</View>
|
||
);
|
||
}
|
||
```
|
||
|
||
### 处理权限被拒绝
|
||
|
||
```typescript
|
||
const handleNotificationToggle = async (value: boolean) => {
|
||
if (value) {
|
||
try {
|
||
const status = await requestPermission();
|
||
if (status === 'granted') {
|
||
setNotificationEnabled(true);
|
||
} else {
|
||
Alert.alert(
|
||
'权限被拒绝',
|
||
'请在系统设置中开启通知权限以获得最佳体验',
|
||
[
|
||
{ text: '取消', style: 'cancel' },
|
||
{ text: '去设置', onPress: () => Linking.openSettings() }
|
||
]
|
||
);
|
||
}
|
||
} catch (error) {
|
||
Alert.alert('错误', '请求通知权限失败');
|
||
}
|
||
}
|
||
};
|
||
```
|
||
|
||
## 通知管理
|
||
|
||
### 取消特定通知
|
||
|
||
```typescript
|
||
import { notificationService } from '@/services/notifications';
|
||
|
||
// 取消特定通知
|
||
await notificationService.cancelNotification(notificationId);
|
||
|
||
// 取消所有通知
|
||
await notificationService.cancelAllNotifications();
|
||
|
||
// 取消特定类型的通知
|
||
import { GeneralNotificationHelpers } from '@/utils/notificationHelpers';
|
||
await GeneralNotificationHelpers.cancelNotificationsByType('workout_reminder');
|
||
```
|
||
|
||
### 查询已安排的通知
|
||
|
||
```typescript
|
||
import { notificationService } from '@/services/notifications';
|
||
|
||
// 获取所有已安排的通知
|
||
const notifications = await notificationService.getAllScheduledNotifications();
|
||
console.log('已安排的通知数量:', notifications.length);
|
||
|
||
notifications.forEach(notification => {
|
||
console.log('通知ID:', notification.identifier);
|
||
console.log('通知标题:', notification.content.title);
|
||
console.log('通知内容:', notification.content.body);
|
||
console.log('通知类型:', notification.content.data?.type);
|
||
});
|
||
```
|
||
|
||
## 测试功能
|
||
|
||
### 使用测试组件
|
||
|
||
项目中包含了一个完整的测试组件 `NotificationTest.tsx`,可以用来测试所有通知功能:
|
||
|
||
```typescript
|
||
import { NotificationTest } from '@/components/NotificationTest';
|
||
|
||
// 在开发环境中使用
|
||
function TestScreen() {
|
||
return <NotificationTest />;
|
||
}
|
||
```
|
||
|
||
### 手动测试
|
||
|
||
```typescript
|
||
// 测试立即通知
|
||
await sendNotification({
|
||
title: '测试通知',
|
||
body: '这是一个测试通知',
|
||
sound: true,
|
||
priority: 'high'
|
||
});
|
||
|
||
// 测试定时通知(5秒后)
|
||
const futureDate = new Date(Date.now() + 5000);
|
||
await scheduleNotification(
|
||
{
|
||
title: '定时测试',
|
||
body: '这是一个5秒后的定时通知',
|
||
sound: true
|
||
},
|
||
futureDate
|
||
);
|
||
|
||
// 测试重复通知(每分钟)
|
||
await scheduleRepeatingNotification(
|
||
{
|
||
title: '重复测试',
|
||
body: '这是一个每分钟重复的通知',
|
||
sound: true
|
||
},
|
||
{ minutes: 1 }
|
||
);
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 通知内容设计
|
||
|
||
- **标题**: 简洁明了,不超过50个字符
|
||
- **内容**: 具体有用,不超过200个字符
|
||
- **时机**: 选择合适的发送时间
|
||
- **频率**: 避免过于频繁的通知
|
||
|
||
### 2. 用户体验
|
||
|
||
- 提供通知开关选项
|
||
- 允许用户自定义通知时间
|
||
- 支持通知类型的选择
|
||
- 提供通知历史记录
|
||
|
||
### 3. 错误处理
|
||
|
||
- 始终处理权限请求失败
|
||
- 提供用户友好的错误提示
|
||
- 实现降级处理方案
|
||
|
||
### 4. 性能优化
|
||
|
||
- 避免同时发送大量通知
|
||
- 及时清理不需要的通知
|
||
- 合理使用重复通知
|
||
|
||
## 故障排除
|
||
|
||
### 常见问题
|
||
|
||
1. **通知不显示**
|
||
- 检查权限是否已授予
|
||
- 确认应用是否在前台
|
||
- 验证通知配置是否正确
|
||
|
||
2. **定时通知不触发**
|
||
- 检查设备是否重启
|
||
- 确认应用是否被系统杀死
|
||
- 验证时间设置是否正确
|
||
|
||
3. **权限被拒绝**
|
||
- 引导用户到系统设置
|
||
- 提供权限说明
|
||
- 实现降级处理方案
|
||
|
||
### 调试技巧
|
||
|
||
```typescript
|
||
// 启用详细日志
|
||
console.log('通知权限状态:', await notificationService.getPermissionStatus());
|
||
console.log('已安排通知:', await notificationService.getAllScheduledNotifications());
|
||
|
||
// 测试通知发送
|
||
await notificationService.sendImmediateNotification({
|
||
title: '调试通知',
|
||
body: '这是一个调试通知',
|
||
sound: true
|
||
});
|
||
```
|
||
|
||
## 总结
|
||
|
||
推送通知功能已经完整集成到项目中,提供了丰富的功能和良好的用户体验。开发者可以根据具体需求灵活使用各种通知功能,为用户提供个性化的提醒服务。
|
||
|
||
如有任何问题或建议,请参考 `docs/notification-implementation.md` 文档或联系开发团队。
|