# Flutter前端推送通知集成方案 ## 技术选型 ### 推送服务选择 考虑到国内环境,推荐使用 **极光推送 (JPush)** 或 **个推 (Getui)** **优势**: - 国内推送到达率高 - 支持iOS和Android - 提供完善的Flutter SDK - 免费版本足够使用 ## 集成步骤 ### 1. 添加依赖 ```yaml dependencies: # 极光推送 jpush_flutter: ^2.5.0 # 本地通知 flutter_local_notifications: ^16.0.0 # 权限管理 permission_handler: ^11.0.0 ``` ### 2. Android配置 **android/app/build.gradle**: ```gradle android { defaultConfig { manifestPlaceholders = [ JPUSH_PKGNAME: applicationId, JPUSH_APPKEY: "你的APPKEY", JPUSH_CHANNEL: "developer-default" ] } } ``` **android/app/src/main/AndroidManifest.xml**: ```xml ``` ### 3. iOS配置 **ios/Runner/Info.plist**: ```xml UIBackgroundModes remote-notification ``` ### 4. 初始化推送 **lib/services/push_service.dart**: ```dart import 'package:jpush_flutter/jpush_flutter.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; class PushService { static final PushService _instance = PushService._internal(); factory PushService() => _instance; PushService._internal(); final JPush jpush = JPush(); final FlutterLocalNotificationsPlugin localNotifications = FlutterLocalNotificationsPlugin(); Future init() async { // 初始化极光推送 jpush.addEventHandler( onReceiveNotification: (Map message) async { print('收到推送: $message'); _handleNotification(message); }, onOpenNotification: (Map message) async { print('点击推送: $message'); _handleNotificationTap(message); }, ); jpush.setup( appKey: '你的APPKEY', channel: 'developer-default', production: false, debug: true, ); // 初始化本地通知 await _initLocalNotifications(); } Future _initLocalNotifications() async { const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings(); final InitializationSettings initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsDarwin, ); await localNotifications.initialize( initializationSettings, onDidReceiveNotificationResponse: (NotificationResponse response) { _handleLocalNotificationTap(response.payload); }, ); } void _handleNotification(Map message) { // 处理推送消息 final title = message['title'] ?? '新消息'; final body = message['alert'] ?? ''; _showLocalNotification(title, body, message); } void _handleNotificationTap(Map message) { // 处理推送点击 final type = message['extras']['type']; switch (type) { case 'order': // 跳转到订单详情 break; case 'asset': // 跳转到资产页面 break; default: // 跳转到首页 break; } } Future _showLocalNotification( String title, String body, Map data, ) async { const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails( 'monisuo_channel', '模拟所通知', channelDescription: '模拟所应用通知', importance: Importance.max, priority: Priority.high, ); const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics); await localNotifications.show( DateTime.now().millisecondsSinceEpoch ~/ 1000, title, body, platformChannelSpecifics, payload: jsonEncode(data), ); } void _handleLocalNotificationTap(String? payload) { if (payload != null) { final data = jsonDecode(payload); _handleNotificationTap(data); } } // 设置别名(通常是用户ID) Future setAlias(String userId) async { jpush.setAlias(userId); } // 删除别名 Future deleteAlias() async { jpush.deleteAlias(); } // 设置标签 Future setTags(List tags) async { jpush.setTags(tags); } } ``` ### 5. 在main.dart中初始化 ```dart void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化推送服务 await PushService().init(); runApp(const MyApp()); } ``` ### 6. 登录后设置别名 ```dart // 用户登录成功后 await PushService().setAlias(userId); // 用户退出登录后 await PushService().deleteAlias(); ``` ## 后端推送接口 **后端需要提供推送接口**: ```java @PostMapping("/api/push/send") public Result sendPush( @RequestParam String userId, @RequestParam String title, @RequestParam String body, @RequestParam(required = false) Map extras ) { // 调用极光推送API JPushClient jpushClient = new JPushClient(appKey, masterSecret); PushPayload payload = PushPayload.newBuilder() .setPlatform(Platform.all()) .setAudience(Audience.alias(userId)) .setNotification(Notification.alert(body)) .setMessage(Message.content(body)) .setOptions(Options.newBuilder().setApnsProduction(false).build()) .build(); jpushClient.sendPush(payload); return Result.success("推送成功"); } ``` ## 推送场景 ### 1. 充值审批通知 ```dart { "title": "充值审批通过", "body": "您的充值订单已审批通过,金额: 100 USDT", "extras": { "type": "order", "orderNo": "F20260324001" } } ``` ### 2. 提现审批通知 ```dart { "title": "提现审批完成", "body": "您的提现申请已处理,金额: 100 USDT", "extras": { "type": "order", "orderNo": "F20260324002" } } ``` ### 3. 资产变动通知 ```dart { "title": "资产变动", "body": "您的账户余额发生变动", "extras": { "type": "asset", "userId": "123" } } ``` ## 测试 ### 1. 测试推送 ```dart // 在开发环境中测试 await PushService()._showLocalNotification( '测试标题', '测试内容', {'type': 'test'}, ); ``` ### 2. 测试极光推送 - 在极光推送控制台发送测试推送 - 检查应用是否收到推送 ## 注意事项 1. **权限申请**: Android需要申请通知权限 2. **iOS证书**: 需要配置APNs证书 3. **测试环境**: 开发时使用开发环境 4. **生产环境**: 上线前切换到生产环境 5. **用户隐私**: 首次启动时请求推送权限 ## 成本估算 - 极光推送免费版:每月100万条推送 - 对于中小规模应用完全够用 - 如需更多,可以升级付费版本 --- **集成时间**: 预计2-3小时 **难度**: 中等 **维护成本**: 低