客户端默认指向 jxd.jinniu.ink 的 HTTPS/WSS;登录后把 OpenIM userID 设为极光 alias。 华为 agconnect-services.json 不伪造、不入库。Master Secret 只从服务器文件注入。 Co-authored-by: multica-agent <github@multica.ai>
104 lines
2.8 KiB
Dart
104 lines
2.8 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:jpush_flutter/jpush_flutter.dart';
|
|
import 'package:jpush_flutter/jpush_interface.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
|
|
import '../config.dart';
|
|
import '../nav.dart';
|
|
import '../screens/home_screen.dart';
|
|
import 'im_service.dart';
|
|
|
|
/// 极光推送封装:初始化、通知权限、Registration ID、把 OpenIM userID 设为 alias。
|
|
///
|
|
/// OpenIM 服务端 JPUSH 离线推送按 alias=userID 下发,因此登录后必须 setAlias。
|
|
/// 本阶段只接安卓;iOS 不调用 setup。
|
|
class PushService {
|
|
PushService._();
|
|
|
|
static final PushService instance = PushService._();
|
|
|
|
final JPushFlutterInterface _jpush = JPush.newJPush();
|
|
bool _ready = false;
|
|
String? _boundAlias;
|
|
|
|
Future<void> init() async {
|
|
if (_ready) return;
|
|
if (kIsWeb || !Platform.isAndroid) return;
|
|
try {
|
|
_jpush.addEventHandler(
|
|
onReceiveNotification: (message) async {},
|
|
onOpenNotification: (message) async {
|
|
_onNotificationClick();
|
|
},
|
|
onReceiveMessage: (message) async {},
|
|
onReceiveNotificationAuthorization: (message) async {},
|
|
onConnected: (message) async {},
|
|
onCommandResult: (message) async {},
|
|
);
|
|
_jpush.setAuth(enable: true);
|
|
_jpush.setup(
|
|
appKey: jpushAppKey,
|
|
channel: 'developer-default',
|
|
production: true,
|
|
debug: false,
|
|
);
|
|
_jpush.applyPushAuthority(
|
|
const NotificationSettingsIOS(sound: true, alert: true, badge: true),
|
|
);
|
|
await _requestAndroidNotificationPermission();
|
|
_ready = true;
|
|
await _jpush.getRegistrationID();
|
|
} catch (_) {
|
|
// 推送失败不能挡住登录和聊天
|
|
}
|
|
}
|
|
|
|
Future<void> bindUser(String userID) async {
|
|
if (userID.isEmpty) return;
|
|
await init();
|
|
if (!_ready) return;
|
|
try {
|
|
await _jpush.setAlias(userID);
|
|
_boundAlias = userID;
|
|
} catch (_) {
|
|
// alias 失败时下次登录再试
|
|
}
|
|
}
|
|
|
|
Future<void> unbindUser() async {
|
|
if (!_ready) return;
|
|
try {
|
|
await _jpush.deleteAlias();
|
|
} catch (_) {
|
|
// 本地照常清理
|
|
}
|
|
_boundAlias = null;
|
|
}
|
|
|
|
String? get boundAlias => _boundAlias;
|
|
|
|
Future<void> _requestAndroidNotificationPermission() async {
|
|
try {
|
|
final status = await Permission.notification.status;
|
|
if (!status.isGranted) {
|
|
await Permission.notification.request();
|
|
}
|
|
} catch (_) {
|
|
// 权限申请失败不阻断
|
|
}
|
|
}
|
|
|
|
void _onNotificationClick() {
|
|
final nav = navigatorKey.currentState;
|
|
if (nav == null) return;
|
|
if (!IMService.instance.loggedIn) return;
|
|
nav.pushAndRemoveUntil(
|
|
MaterialPageRoute(builder: (_) => const HomeScreen()),
|
|
(route) => false,
|
|
);
|
|
}
|
|
}
|