app-starlock/lib/tools/push/xs_jPhush.dart

225 lines
8.5 KiB
Dart
Raw Permalink Normal View History

import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:jpush_flutter/jpush_flutter.dart';
2024-06-01 13:35:03 +08:00
import 'package:star_lock/flavors.dart';
import 'package:star_lock/login/register/entity/checkIP_entity.dart';
import 'package:star_lock/mine/minePersonInfo/minePersonInfoEditAccount/minePersonInfoEditAccount/mineUnbindPhoneOrEmail_entity.dart';
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/callkit_handler.dart';
import 'package:star_lock/tools/debounce_throttle_tool.dart';
import 'package:star_lock/tools/push/message_management.dart';
import 'package:star_lock/tools/push/notification_service.dart';
import 'package:star_lock/tools/storage.dart';
import '../../app_settings/app_settings.dart';
2024-04-26 15:38:59 +08:00
class XSJPushProvider {
static const Map<int, String> channelTypeMapping = <int, String>{
1: 'xiaomi',
2: 'huawei',
3: 'meizu',
4: 'oppo',
5: 'vivo',
7: 'honor',
8: 'fcm',
9: 'jiguang',
10: 'apns',
};
final JPush jpush = JPush();
DebounceThrottleTool? _debounceThrottleTool;
Future<void> resetJPushService() async {
debugPrint("resetJPushService start");
for (final MapEntry<int, String> entry in channelTypeMapping.entries) {
await Storage.removeData('old_${entry.value}');
}
debugPrint("resetJPushService end");
}
// appKey: 251fc8074820d122b6de58d2--鑫泓佳AppKey
// appKey: 7ff37d174c1a568a89e98dad--sky
Future<void> initJPushService() async {
debugPrint("initJPushService start");
final String? data = await Storage.getString(saveUserLoginData);
if (data == null || data.isEmpty) {
AppLog.log('No user data found.');
return;
}
_debounceThrottleTool = DebounceThrottleTool(
const Duration(milliseconds: 1500),
(dynamic param) {
bindPushChannels();
},
);
AppLog.log('jPushKey ${F.jPushKey}');
2025-02-13 10:56:24 +08:00
// final String? bundleIdentifier =
// await NativeInteractionTool().getBundleIdentifier();
// print('bundleIdentifier: $bundleIdentifier');
jpush.setup(
appKey: F.jPushKey,
channel: 'flutter_channel',
production: F.isProductionEnv,
debug: !F.isProductionEnv,
);
jpush.setAuth(enable: true);
2024-05-29 17:31:55 +08:00
jpush.applyPushAuthority(
const NotificationSettingsIOS(sound: true, alert: true, badge: false),
);
addJPushEventHandler();
AppLog.log('JPush initialized.');
debugPrint("initJPushService end");
2024-05-29 17:31:55 +08:00
}
static const int CMD_GET_REGISTRATION_ID = 2005; //getRegistrationID 异步回调
static const int CMD_GET_TOKEN = 10000; //厂商 token 注册回调
2024-05-29 17:31:55 +08:00
//极光推送事件处理方法
void addJPushEventHandler() {
jpush.addEventHandler(
onCommandResult: (Map<String, dynamic> data) async {
AppLog.log('onCommandResult: $data');
debugPrint("addJPushEventHandler onCommandResult:$data");
final int cmdCode = data['cmd'];
switch (cmdCode) {
case CMD_GET_REGISTRATION_ID:
final bool isNullOrBlank =
GetUtils.isNullOrBlank(data['message']) ?? true;
if (!isNullOrBlank) {
AppLog.log(
'flutter get jiguang registration id : ${data['message']}');
await Storage.setString('jiguang', data['message']);
_debounceThrottleTool?.trigger(data['message']);
}
break;
case CMD_GET_TOKEN:
final bool isNullOrBlank =
GetUtils.isNullOrBlank(data['token']) ?? true;
if (!isNullOrBlank) {
await Storage.setString(
channelTypeMapping[data['platform']] ?? '', data['token']);
_debounceThrottleTool?.trigger(data['token']);
}
break;
}
},
onReceiveNotification: (Map<String, dynamic> message) async {
AppLog.log('onReceiveNotification: $message');
debugPrint('addJPushEventHandler onReceiveNotification:$message');
// showCustomNotification(message);
},
onOpenNotification: (Map<String, dynamic> message) async {
AppLog.log('onOpenNotification: $message');
debugPrint("addJPushEventHandler onOpenNotification:$message");
},
onReceiveMessage: (Map<String, dynamic> message) async {
AppLog.log('onReceiveMessage: $message');
debugPrint("addJPushEventHandler onReceiveMessage:$message");
//这里接收自定义消息
MessageManagement.shunting(message);
},
onReceiveNotificationAuthorization: (Map<String, dynamic> message) async {
AppLog.log('onReceiveNotificationAuthorization: $message');
debugPrint(
"addJPushEventHandler onReceiveNotificationAuthorization:$message");
},
onInAppMessageShow: (Map<String, dynamic> message) async {
AppLog.log('onInAppMessageShow: $message');
debugPrint("addJPushEventHandler onInAppMessageShow:$message");
},
onConnected: (Map<String, dynamic> message) async {
return Future.value();
},
);
}
// jpush 统一推送通道设备绑定
Future<void> bindPushChannels() async {
try {
debugPrint("BindPushChannels start");
bool needReBindPushToken = false;
final Map<String, String> newVendorsPushToken = <String, String>{};
final Map<String, String> oldVendorsPushToken = <String, String>{};
for (final String channel in channelTypeMapping.values) {
debugPrint("BindPushChannels channel $channel");
final String? newVendorToken = await Storage.getString(channel);
debugPrint("BindPushChannels newVendorToken $newVendorToken");
newVendorsPushToken[channel] = newVendorToken ?? '';
final String? oldVendorToken = await Storage.getString('old_$channel');
debugPrint("BindPushChannels oldVendorToken $oldVendorToken");
oldVendorsPushToken['old_$channel'] = oldVendorToken ?? '';
if (newVendorToken != oldVendorToken) {
needReBindPushToken = true;
}
}
if (!needReBindPushToken) {
AppLog.log('vendorToken 未变动,无需重新绑定');
return;
}
final List<Map<String, dynamic>> channels = newVendorsPushToken.entries
.where((entry) => !(GetUtils.isNullOrBlank(entry.value) ?? true))
.map((entry) => <String, dynamic>{
'channel': entry.key,
'channelToken': entry.value
})
.toList();
if (Platform.isIOS) {
final CheckIPEntity entity =
await ApiRepository.to.checkIpAction(ip: '');
debugPrint('entity: ${jsonEncode(entity)}');
if (entity.errorCode!.codeIsSuccessful) {
if ('中国' != entity.data!.name) {
String? token = await CallKitHandler.getVoipToken();
if (token != null && token.isNotEmpty) {
2025-07-03 17:10:12 +08:00
channels.forEach((element) {
if(element['channel'] == 'apns') {
element['voipToken'] = token;
}
});
} else {
debugPrint(
'iOS VoIP Token is null or empty, not adding to channels');
}
} else {
debugPrint('国内用户不上报VOIP Token');
}
}
}
debugPrint("BindPushChannels ${channels}");
final String? deviceID = await Storage.getString(appDeviceID);
final MineUnbindPhoneOrEmailEntity entity =
await ApiRepository.to.pushBindChannels(deviceID!, channels);
if (entity.errorCode!.codeIsSuccessful) {
AppLog.log('vendorToken绑定成功准备更新本地缓存');
await Future.wait(channels.map((Map<String, dynamic> entry) =>
Storage.setString(
'old_${entry['channel']}', entry['channelToken'])));
AppLog.log('vendorToken绑定成功更新本地缓存完成');
} else {
AppLog.log('绑定失败');
}
} catch (e) {
AppLog.log('vendorToken绑定失败下次重启应用重新绑定');
AppLog.log('Error binding device ID: $e');
}
}
void showCustomNotification(Map<String, dynamic> data) {
final String title = data['notification']['android']['title'] ?? '默认标题';
final String content = data['notification']['android']['alert'] ?? '默认内容';
final String imageUrl = data['notification']['android']['extras']
?['image_url']; // 从 extras 获取图片
NotificationService().showImageNotification(title, content, imageUrl);
}
}