Explorar o código

[new]增加引力引擎流程

zk hai 1 ano
pai
achega
a944ef997d
Modificáronse 87 ficheiros con 231 adicións e 218 borrados
  1. 9 0
      lib/data/consts/build_config.dart
  2. 28 3
      lib/data/consts/constants.dart
  3. 6 3
      lib/data/repositories/account_repository.dart
  4. 2 0
      lib/data/repositories/task_repository.dart
  5. 0 7
      lib/device/device_info_util.dart
  6. 1 2
      lib/device/platform_android_info.dart
  7. 16 2
      lib/device/platform_ios_info.dart
  8. 19 2
      lib/main.dart
  9. 7 4
      lib/module/splash/controller.dart
  10. 1 1
      lib/module/store/controller.dart
  11. 5 2
      lib/module/store/payment_status_manager.dart
  12. 112 6
      lib/sdk/gravity/gravity_helper.dart
  13. 1 0
      lib/utils/app_info_util.dart
  14. 5 4
      lib/utils/async_util.dart
  15. 0 0
      plugin/atmob_channel_reader/example/.gitignore
  16. 0 0
      plugin/atmob_channel_reader/example/README.md
  17. 0 28
      plugin/atmob_channel_reader/example/analysis_options.yaml
  18. 0 0
      plugin/atmob_channel_reader/example/android/.gitignore
  19. 0 0
      plugin/atmob_channel_reader/example/android/app/build.gradle
  20. 0 0
      plugin/atmob_channel_reader/example/android/app/src/debug/AndroidManifest.xml
  21. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/AndroidManifest.xml
  22. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/java/com/atmob/channel/atmob_channel_reader_example/MainActivity.java
  23. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/drawable-v21/launch_background.xml
  24. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/drawable/launch_background.xml
  25. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  26. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  27. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  28. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  29. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  30. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/values-night/styles.xml
  31. 0 0
      plugin/atmob_channel_reader/example/android/app/src/main/res/values/styles.xml
  32. 0 0
      plugin/atmob_channel_reader/example/android/app/src/profile/AndroidManifest.xml
  33. 0 0
      plugin/atmob_channel_reader/example/android/build.gradle
  34. 0 0
      plugin/atmob_channel_reader/example/android/gradle.properties
  35. 0 0
      plugin/atmob_channel_reader/example/android/gradle/wrapper/gradle-wrapper.jar
  36. 0 0
      plugin/atmob_channel_reader/example/android/gradle/wrapper/gradle-wrapper.properties
  37. 0 0
      plugin/atmob_channel_reader/example/android/gradlew
  38. 0 0
      plugin/atmob_channel_reader/example/android/gradlew.bat
  39. 0 0
      plugin/atmob_channel_reader/example/android/local.properties
  40. 0 0
      plugin/atmob_channel_reader/example/android/settings.gradle
  41. 0 0
      plugin/atmob_channel_reader/example/ios/.gitignore
  42. 0 0
      plugin/atmob_channel_reader/example/ios/Flutter/AppFrameworkInfo.plist
  43. 0 0
      plugin/atmob_channel_reader/example/ios/Flutter/Debug.xcconfig
  44. 0 0
      plugin/atmob_channel_reader/example/ios/Flutter/Release.xcconfig
  45. 0 0
      plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/project.pbxproj
  46. 0 0
      plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  47. 0 0
      plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  48. 0 0
      plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  49. 0 0
      plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  50. 0 0
      plugin/atmob_channel_reader/example/ios/Runner.xcworkspace/contents.xcworkspacedata
  51. 0 0
      plugin/atmob_channel_reader/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  52. 0 0
      plugin/atmob_channel_reader/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  53. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/AppDelegate.swift
  54. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
  55. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  56. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  57. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  58. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  59. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  60. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  61. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  62. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  63. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  64. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  65. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  66. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  67. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  68. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  69. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  70. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
  71. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  72. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  73. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  74. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
  75. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
  76. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Base.lproj/Main.storyboard
  77. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Info.plist
  78. 0 0
      plugin/atmob_channel_reader/example/ios/Runner/Runner-Bridging-Header.h
  79. 0 0
      plugin/atmob_channel_reader/example/ios/RunnerTests/RunnerTests.swift
  80. 0 63
      plugin/atmob_channel_reader/example/lib/main.dart
  81. 0 0
      plugin/atmob_channel_reader/example/pubspec.lock
  82. 0 85
      plugin/atmob_channel_reader/example/pubspec.yaml
  83. 0 0
      plugin/atmob_channel_reader/example/test/widget_test.dart
  84. 3 3
      plugin/atmob_channel_reader/lib/atmob_channel_reader.dart
  85. 6 3
      plugin/gravity_engine/lib/gravity_engine_method_channel.dart
  86. 8 0
      pubspec.lock
  87. 2 0
      pubspec.yaml

+ 9 - 0
lib/data/consts/build_config.dart

@@ -0,0 +1,9 @@
+import 'package:flutter/foundation.dart';
+
+class BuildConfig {
+  BuildConfig._();
+
+  static bool get isDebug => kDebugMode;
+  static const String gravityAppId = "";
+  static const String gravityAccessToken = "";
+}

+ 28 - 3
lib/data/consts/constants.dart

@@ -1,3 +1,9 @@
+import 'dart:io';
+
+import 'package:electronic_assistant/utils/mmkv_util.dart';
+
+import '../../utils/common_utils.dart';
+
 class Constants {
   Constants._();
 
@@ -22,6 +28,12 @@ class Constants {
 
   static const String userAgreement =
       "https://cdn.v8dashen.com/static/xt-xm-clause.html";
+
+  static final String privacyPolicyKey = stringToUnicode('privacyPolicyKey');
+
+  static const String appDefaultChannel = "Android";
+  static const int appDefaultAppId = 0;
+  static const int appDefaultTgPlatformId = 0;
 }
 
 String getBaseUrl() {
@@ -37,16 +49,29 @@ String getBaseUrl() {
   }
 }
 
+bool isAgreePrivacyPolicy() {
+  return Platform.isAndroid ||
+      KVUtil.getBool(Constants.privacyPolicyKey, false);
+}
+
+void setPrivacyPolicy(bool isAgree) {
+  KVUtil.putBool(Constants.privacyPolicyKey, isAgree);
+}
+
 class PayPlatform {
   static const int android = 1;
-  static const int ios = 2;
-  static const int qrCode = 4;
+  static const int apple = 2;
 }
 
 class PayMethod {
   static const int alipay = 1;
   static const int wechat = 2;
-  static const int ios = 3;
+  static const int apple = 3;
   static const int google = 4;
   static const int douYin = 5;
 }
+
+class Currency {
+  static const String cny = "CNY";
+  static const String usd = "USD";
+}

+ 6 - 3
lib/data/repositories/account_repository.dart

@@ -10,6 +10,7 @@ import 'package:electronic_assistant/utils/mmkv_util.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:get/get.dart';
 import '../../resource/string.gen.dart';
+import '../../sdk/gravity/gravity_helper.dart';
 import '../../utils/http_handler.dart';
 import '../api/request/login_request.dart';
 import '../api/request/user_info_update_request.dart';
@@ -77,8 +78,8 @@ class AccountRepository {
     if (_getUserInfoFuture != null) {
       _getUserInfoFuture?.cancel();
     }
-    _getUserInfoFuture = AsyncUtil.retryWithExponentialBackoff(
-        () => _getUserInfo(), 10, (error) {
+    _getUserInfoFuture =
+        AsyncUtil.retryWithExponentialBackoff(() => getUserInfo(), 10, (error) {
       if (error is ServerErrorException) {
         return error.code != ErrorCode.errorCodeNoLogin;
       }
@@ -87,7 +88,7 @@ class AccountRepository {
     return _getUserInfoFuture;
   }
 
-  Future<UserInfoResponse> _getUserInfo() {
+  Future<UserInfoResponse> getUserInfo() {
     return atmobApi
         .userInfo(AppBaseRequest())
         .then(HttpHandler.handle(false))
@@ -117,6 +118,7 @@ class AccountRepository {
     taskRepository.startUnfinishedTask();
 
     eventBus.emit(EventUserLogin);
+    GravityHelper.onLogin();
   }
 
   void logout() {
@@ -129,6 +131,7 @@ class AccountRepository {
     _userInfo.value = null;
 
     eventBus.emit(EventUserLogout);
+    GravityHelper.onLogout();
   }
 
   getUserSubName(String? phone) {

+ 2 - 0
lib/data/repositories/task_repository.dart

@@ -2,6 +2,7 @@ import 'package:electronic_assistant/base/app_base_request.dart';
 import 'package:electronic_assistant/data/api/atmob_api.dart';
 import 'package:electronic_assistant/data/api/response/talk_query_response.dart';
 import 'package:electronic_assistant/data/bean/talks.dart';
+import 'package:electronic_assistant/data/repositories/account_repository.dart';
 import 'package:electronic_assistant/data/repositories/agenda_repository.dart';
 import 'package:electronic_assistant/data/repositories/talk_repository.dart';
 import 'package:electronic_assistant/utils/async_util.dart';
@@ -107,6 +108,7 @@ class TaskRepository {
       showAnalyseSuccessDialog(onViewClick: () {
         TalkPage.start(element);
       });
+      accountRepository.refreshUserInfo();
       agendaRepository.requestHomeAgendaData();
     } else if (element.status.value == TalkStatus.analysisFail) {
       debugPrint('生成失败-${element.id}');

+ 0 - 7
lib/device/device_info_util.dart

@@ -1,17 +1,10 @@
 import 'package:electronic_assistant/device/platform_ios_info.dart';
-
 import 'platform_android_info.dart';
-import '../utils/common_utils.dart';
 
 class DeviceInfoUtil {
   DeviceInfoUtil._();
 
-  // final String privacyPolicyKey = stringToUnicode('privacyPolicyKey');
-
   init() async {
-    // if (!KVUtil.getBool(privacyPolicyKey, false)) {
-    //   return;
-    // }
     await PlatformAndroidInfo.init();
     await PlatformIosInfo.init();
   }

+ 1 - 2
lib/device/platform_android_info.dart

@@ -3,10 +3,9 @@ import 'dart:io';
 import 'package:device_info_plus/device_info_plus.dart';
 import 'package:electronic_assistant/device/atmob_platform_info.dart';
 import 'package:android_id/android_id.dart';
-import 'package:flutter/widgets.dart';
 
 class PlatformAndroidInfo {
-  static init() async {
+  static Future<void> init() async {
     if (Platform.isAndroid) {
       DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
       AndroidDeviceInfo androidInfo = await deviceInfoPlugin.androidInfo;

+ 16 - 2
lib/device/platform_ios_info.dart

@@ -1,17 +1,31 @@
 import 'dart:io';
 
+import 'package:app_tracking_transparency/app_tracking_transparency.dart';
 import 'package:device_info_plus/device_info_plus.dart';
-
 import 'atmob_platform_info.dart';
 
 class PlatformIosInfo {
-  static init() async {
+  static Future<void> init() async {
     if (Platform.isIOS) {
       DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
       IosDeviceInfo iosInfo = await deviceInfoPlugin.iosInfo;
       atmobPlatformInfo
           .setModel(iosInfo.model)
           .setIdfv(iosInfo.identifierForVendor);
+
+      final TrackingStatus status =
+          await AppTrackingTransparency.trackingAuthorizationStatus;
+      if (status == TrackingStatus.notDetermined) {
+        final TrackingStatus newStatus =
+            await AppTrackingTransparency.requestTrackingAuthorization();
+        if (newStatus == TrackingStatus.authorized) {
+          atmobPlatformInfo.setIdfa(
+              await AppTrackingTransparency.getAdvertisingIdentifier());
+        }
+      } else if (status == TrackingStatus.authorized) {
+        atmobPlatformInfo
+            .setIdfa(await AppTrackingTransparency.getAdvertisingIdentifier());
+      }
     }
   }
 }

+ 19 - 2
lib/main.dart

@@ -1,5 +1,6 @@
 import 'dart:io';
 
+import 'package:atmob_channel_reader/atmob_channel_reader.dart';
 import 'package:electronic_assistant/resource/colors.gen.dart';
 import 'package:electronic_assistant/resource/string.gen.dart';
 import 'package:electronic_assistant/resource/string_source.dart';
@@ -16,6 +17,8 @@ import 'package:get/get.dart';
 import 'package:get/get_navigation/src/root/get_material_app.dart';
 import 'package:pull_to_refresh/pull_to_refresh.dart';
 
+import 'data/consts/Constants.dart';
+
 void main() async {
   WidgetsFlutterBinding.ensureInitialized();
 
@@ -25,13 +28,27 @@ void main() async {
   smartConfig();
   //mmkv
   await KVUtil.init();
+
+  //渠道信息
+  await AtmobChannelReader.default4Test(Constants.appDefaultChannel,
+      Constants.appDefaultTgPlatformId, Constants.appDefaultAppId);
+
+  //初始化
+  await initAfterGrant();
+
+  runApp(const MyApp());
+}
+
+Future<void> initAfterGrant() async {
+  if (!isAgreePrivacyPolicy()) {
+    return;
+  }
   //获取包信息
   await appInfoUtil.init();
   //获取设备信息
   await deviceInfoUtil.init();
-
+  //引力引擎
   GravityHelper.init();
-  runApp(const MyApp());
 }
 
 void smartConfig() {

+ 7 - 4
lib/module/splash/controller.dart

@@ -6,12 +6,13 @@ import 'package:electronic_assistant/data/consts/constants.dart';
 import 'package:electronic_assistant/module/browser/view.dart';
 import 'package:electronic_assistant/router/app_pages.dart';
 import 'package:electronic_assistant/utils/expand.dart';
-import 'package:electronic_assistant/utils/mmkv_util.dart';
 import 'package:electronic_assistant/widget/alert_dialog.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/gestures.dart';
 import 'package:get/get.dart';
 
+import '../../main.dart';
+
 class SplashController extends BaseController {
   final splashDelayedTime = 2;
 
@@ -20,7 +21,7 @@ class SplashController extends BaseController {
     // TODO: implement onInit
     super.onReady();
 
-    final isAgreePrivacy = KVUtil.getBool('isAgreePrivacyKey', false);
+    final isAgreePrivacy = isAgreePrivacyPolicy();
     if (isAgreePrivacy) {
       Timer(Duration(seconds: splashDelayedTime), () {
         Get.offNamed(RoutePath.mainTab);
@@ -78,9 +79,11 @@ class SplashController extends BaseController {
           EAAlertDialog.dismiss();
           exit(0);
         },
-        confirmOnTap: () {
+        confirmOnTap: () async {
           EAAlertDialog.dismiss();
-          KVUtil.putBool('isAgreePrivacyKey', true);
+          setPrivacyPolicy(true);
+          await initAfterGrant();
+          await Future.delayed(const Duration(seconds: 1));
           Get.offNamed(RoutePath.mainTab);
         },
       );

+ 1 - 1
lib/module/store/controller.dart

@@ -103,7 +103,7 @@ class StoreController extends BaseController implements PaymentStatusCallback {
               timestamp: bean.timeStamp,
               sign: bean.sign);
         }
-      } else if (payPlatform == PayPlatform.ios) {
+      } else if (payPlatform == PayPlatform.apple) {
         payInfo = ApplePayInfo(
             storeItem.appleGoodsId,
             storeItem.subscribable == 1

+ 5 - 2
lib/module/store/payment_status_manager.dart

@@ -1,5 +1,6 @@
 import 'package:electronic_assistant/data/repositories/account_repository.dart';
 import 'package:electronic_assistant/data/repositories/store_repository.dart';
+import 'package:electronic_assistant/sdk/gravity/gravity_helper.dart';
 import 'package:electronic_assistant/utils/async_util.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:synchronized/synchronized.dart';
@@ -67,8 +68,10 @@ class PaymentStatusManager {
     });
   }
 
-  void reportPaySuccess(
-      int price, String orderId, String itemName, int paymentWay) {}
+  void reportPaySuccess(int price, String orderId, String itemName,
+      int paymentWay) {
+    GravityHelper.reportPay(price, orderId, itemName, paymentWay);
+  }
 
   void checkPaymentStatus(
       String orderNo, PaymentWay paymentWay, StoreItem storeItemBean) {

+ 112 - 6
lib/sdk/gravity/gravity_helper.dart

@@ -1,13 +1,119 @@
+import 'dart:async';
+import 'package:atmob_channel_reader/atmob_channel_reader.dart';
+import 'package:electronic_assistant/data/repositories/account_repository.dart';
+import 'package:electronic_assistant/utils/async_util.dart';
+import 'package:electronic_assistant/utils/mmkv_util.dart';
+import 'package:flutter/widgets.dart';
 import 'package:gravity_engine/gravity_engine.dart';
+import 'package:gravity_engine/gravity_engine_method_channel.dart';
+import '../../data/api/response/user_info_response.dart';
+import '../../data/consts/Constants.dart';
+import '../../data/consts/build_config.dart';
+import '../../utils/cancel_future.dart';
+
+typedef GravitySuccessCallback = void Function();
 
 class GravityHelper {
-  static init() {
-    GravityEngine.initialize(
-        "appid","3q4k1zgleJpExobevRf0c6G2Owb5nIas", "test", "test", true)
-        .then((isAttributed) {
-      print("isAttributed: $isAttributed");
+  static const String _keyCurrentSsid = "current_ssid";
+  static CancelableFuture<bool>? _initFuture;
+  static String? _currentClientId;
+
+  static bool? _isFromPromote;
+
+  static init() async {
+    _initialize(false);
+  }
+
+  static _initialize(bool refreshSSID,
+      {GravitySuccessCallback? callback}) async {
+    if (_initFuture != null) {
+      _initFuture?.cancel();
+    }
+    _initFuture = AsyncUtil.retryWithExponentialBackoff<bool>(() async {
+      String ssid = await _getSSID(refreshSSID);
+      CancelableFuture<bool> initFuture = _gravityInitialize(ssid);
+      _initFuture = initFuture;
+      return await initFuture;
+    }, 5, null);
+    _initFuture?.then((isPromote) {
+      _isFromPromote = isPromote;
+      callback?.call();
     }).catchError((error) {
-      print("error: $error");
+      _initialize(refreshSSID, callback: callback);
+    });
+  }
+
+  static Future<String> _getSSID(bool refreshSSID) async {
+    String? currentSSID = _getCurrentSSID();
+    if (currentSSID == null || refreshSSID) {
+      UserInfoResponse userInfo = await accountRepository.getUserInfo();
+      KVUtil.putString(_keyCurrentSsid, userInfo.ssid);
+      return userInfo.ssid;
+    }
+    return currentSSID;
+  }
+
+  static String? _getCurrentSSID() {
+    return KVUtil.getString(_keyCurrentSsid, null);
+  }
+
+  static CancelableFuture<bool> _gravityInitialize(String ssid) {
+    return AsyncUtil.retryWithExponentialBackoff<bool>(() async {
+      String? channel = await AtmobChannelReader.getChannel();
+      return GravityEngine.initialize(
+              BuildConfig.gravityAppId,
+              BuildConfig.gravityAccessToken,
+              ssid,
+              channel ?? '',
+              BuildConfig.isDebug)
+          .then((data) {
+        debugPrint('gravity initialize($ssid) success');
+        GravityHelper._currentClientId = ssid;
+        return data;
+      });
+    }, 5, null);
+  }
+
+  static void onLogin() {
+    _clearCurrentSSID();
+    _initialize(true, callback: () {
+      if (_currentClientId != null) {
+        GravityEngine.login(_currentClientId!);
+      }
     });
   }
+
+  static void onLogout() async {
+    _currentClientId = null;
+    await GravityEngine.logout();
+    _initialize(false, callback: null);
+  }
+
+  static void _clearCurrentSSID() {
+    KVUtil.putString(_keyCurrentSsid, null);
+  }
+
+  static bool? getIsFromPromote() {
+    return _isFromPromote;
+  }
+
+  static void report(String eventId, {Map<String, dynamic>? params}) {
+    GravityEngine.trackEvent(eventId, eventProperties: params);
+  }
+
+  static void reportPay(
+      int payAmount, String orderNo, String productName, int payWay) {
+    PayType payType;
+    if (payWay == PayMethod.alipay) {
+      payType = PayType.alipay;
+    } else if (payWay == PayMethod.wechat) {
+      payType = PayType.wechat;
+    } else if (payWay == PayMethod.apple) {
+      payType = PayType.apple;
+    } else {
+      payType = PayType.unknown;
+    }
+    GravityEngine.trackPay(
+        orderNo, productName, payAmount, Currency.cny, payType);
+  }
 }

+ 1 - 0
lib/utils/app_info_util.dart

@@ -1,3 +1,4 @@
+import 'package:electronic_assistant/data/consts/constants.dart';
 import 'package:package_info_plus/package_info_plus.dart';
 
 class AppInfoUtil {

+ 5 - 4
lib/utils/async_util.dart

@@ -9,7 +9,7 @@ class AsyncUtil {
   AsyncUtil._();
 
   static CancelableFuture<T> retryWithExponentialBackoff<T>(
-      FutureCallback<T> callback, int maxRetry, Predicate<dynamic> predicate) {
+      FutureCallback<T> callback, int maxRetry, Predicate<dynamic>? predicate) {
     const Duration initialInterval = Duration(seconds: 1);
     int retryCount = 0;
     Timer? timer;
@@ -20,7 +20,7 @@ class AsyncUtil {
           completer.complete(value);
         }
       }).catchError((error) {
-        if (retryCount < maxRetry && predicate(error)) {
+        if (retryCount < maxRetry && (predicate == null || predicate(error))) {
           retryCount++;
           Duration nextInterval = initialInterval * (1 << (retryCount - 1));
           timer = Timer(nextInterval, () => attempt(completer));
@@ -78,8 +78,9 @@ class AsyncUtil {
     });
   }
 
-  static CancelableFuture<T> retry<T>(FutureCallback<T> callback, int maxRetry,
-      Duration interval, [Duration? timeout]) {
+  static CancelableFuture<T> retry<T>(
+      FutureCallback<T> callback, int maxRetry, Duration interval,
+      [Duration? timeout]) {
     return retryWhen(callback, maxRetry, interval, (error) => true, timeout);
   }
 

+ 0 - 0
plugin/atmob_channel_reader/example/.gitignore


+ 0 - 0
plugin/atmob_channel_reader/example/README.md


+ 0 - 28
plugin/atmob_channel_reader/example/analysis_options.yaml

@@ -1,28 +0,0 @@
-# This file configures the analyzer, which statically analyzes Dart code to
-# check for errors, warnings, and lints.
-#
-# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
-# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
-# invoked from the command line by running `flutter analyze`.
-
-# The following line activates a set of recommended lints for Flutter apps,
-# packages, and plugins designed to encourage good coding practices.
-include: package:flutter_lints/flutter.yaml
-
-linter:
-  # The lint rules applied to this project can be customized in the
-  # section below to disable rules from the `package:flutter_lints/flutter.yaml`
-  # included above or to enable additional rules. A list of all available lints
-  # and their documentation is published at https://dart.dev/lints.
-  #
-  # Instead of disabling a lint rule for the entire project in the
-  # section below, it can also be suppressed for a single line of code
-  # or a specific dart file by using the `// ignore: name_of_lint` and
-  # `// ignore_for_file: name_of_lint` syntax on the line or in the file
-  # producing the lint.
-  rules:
-  # avoid_print: false  # Uncomment to disable the `avoid_print` rule
-  # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule
-
-# Additional information about this file can be found at
-# https://dart.dev/guides/language/analysis-options

+ 0 - 0
plugin/atmob_channel_reader/example/android/.gitignore


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/build.gradle


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/debug/AndroidManifest.xml


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/AndroidManifest.xml


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/java/com/atmob/channel/atmob_channel_reader_example/MainActivity.java


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/drawable-v21/launch_background.xml


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/drawable/launch_background.xml


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/values-night/styles.xml


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/main/res/values/styles.xml


+ 0 - 0
plugin/atmob_channel_reader/example/android/app/src/profile/AndroidManifest.xml


+ 0 - 0
plugin/atmob_channel_reader/example/android/build.gradle


+ 0 - 0
plugin/atmob_channel_reader/example/android/gradle.properties


+ 0 - 0
plugin/atmob_channel_reader/example/android/gradle/wrapper/gradle-wrapper.jar


+ 0 - 0
plugin/atmob_channel_reader/example/android/gradle/wrapper/gradle-wrapper.properties


+ 0 - 0
plugin/atmob_channel_reader/example/android/gradlew


+ 0 - 0
plugin/atmob_channel_reader/example/android/gradlew.bat


+ 0 - 0
plugin/atmob_channel_reader/example/android/local.properties


+ 0 - 0
plugin/atmob_channel_reader/example/android/settings.gradle


+ 0 - 0
plugin/atmob_channel_reader/example/ios/.gitignore


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Flutter/AppFrameworkInfo.plist


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Flutter/Debug.xcconfig


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Flutter/Release.xcconfig


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/project.pbxproj


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner.xcworkspace/contents.xcworkspacedata


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/AppDelegate.swift


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Base.lproj/LaunchScreen.storyboard


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Base.lproj/Main.storyboard


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Info.plist


+ 0 - 0
plugin/atmob_channel_reader/example/ios/Runner/Runner-Bridging-Header.h


+ 0 - 0
plugin/atmob_channel_reader/example/ios/RunnerTests/RunnerTests.swift


+ 0 - 63
plugin/atmob_channel_reader/example/lib/main.dart

@@ -1,63 +0,0 @@
-import 'package:flutter/material.dart';
-import 'dart:async';
-
-import 'package:flutter/services.dart';
-import 'package:atmob_channel_reader/atmob_channel_reader.dart';
-
-void main() {
-  runApp(const MyApp());
-}
-
-class MyApp extends StatefulWidget {
-  const MyApp({super.key});
-
-  @override
-  State<MyApp> createState() => _MyAppState();
-}
-
-class _MyAppState extends State<MyApp> {
-  String _platformVersion = 'Unknown';
-  final _atmobChannelReaderPlugin = AtmobChannelReader();
-
-  @override
-  void initState() {
-    super.initState();
-    initPlatformState();
-  }
-
-  // Platform messages are asynchronous, so we initialize in an async method.
-  Future<void> initPlatformState() async {
-    String platformVersion;
-    // Platform messages may fail, so we use a try/catch PlatformException.
-    // We also handle the message potentially returning null.
-    try {
-      platformVersion = await _atmobChannelReaderPlugin.getPlatformVersion() ??
-          'Unknown platform version';
-    } on PlatformException {
-      platformVersion = 'Failed to get platform version.';
-    }
-
-    // If the widget was removed from the tree while the asynchronous platform
-    // message was in flight, we want to discard the reply rather than calling
-    // setState to update our non-existent appearance.
-    if (!mounted) return;
-
-    setState(() {
-      _platformVersion = platformVersion;
-    });
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return MaterialApp(
-      home: Scaffold(
-        appBar: AppBar(
-          title: const Text('Plugin example app'),
-        ),
-        body: Center(
-          child: Text('Running on: $_platformVersion\n'),
-        ),
-      ),
-    );
-  }
-}

+ 0 - 0
plugin/atmob_channel_reader/example/pubspec.lock


+ 0 - 85
plugin/atmob_channel_reader/example/pubspec.yaml

@@ -1,85 +0,0 @@
-name: atmob_channel_reader_example
-description: "Demonstrates how to use the atmob_channel_reader plugin."
-# The following line prevents the package from being accidentally published to
-# pub.dev using `flutter pub publish`. This is preferred for private packages.
-publish_to: 'none' # Remove this line if you wish to publish to pub.dev
-
-environment:
-  sdk: ^3.5.0
-
-# Dependencies specify other packages that your package needs in order to work.
-# To automatically upgrade your package dependencies to the latest versions
-# consider running `flutter pub upgrade --major-versions`. Alternatively,
-# dependencies can be manually updated by changing the version numbers below to
-# the latest version available on pub.dev. To see which dependencies have newer
-# versions available, run `flutter pub outdated`.
-dependencies:
-  flutter:
-    sdk: flutter
-
-  atmob_channel_reader:
-    # When depending on this package from a real application you should use:
-    #   atmob_channel_reader: ^x.y.z
-    # See https://dart.dev/tools/pub/dependencies#version-constraints
-    # The example app is bundled with the plugin so we use a path dependency on
-    # the parent directory to use the current plugin's version.
-    path: ../
-
-  # The following adds the Cupertino Icons font to your application.
-  # Use with the CupertinoIcons class for iOS style icons.
-  cupertino_icons: ^1.0.8
-
-dev_dependencies:
-  integration_test:
-    sdk: flutter
-  flutter_test:
-    sdk: flutter
-
-  # The "flutter_lints" package below contains a set of recommended lints to
-  # encourage good coding practices. The lint set provided by the package is
-  # activated in the `analysis_options.yaml` file located at the root of your
-  # package. See that file for information about deactivating specific lint
-  # rules and activating additional ones.
-  flutter_lints: ^4.0.0
-
-# For information on the generic Dart part of this file, see the
-# following page: https://dart.dev/tools/pub/pubspec
-
-# The following section is specific to Flutter packages.
-flutter:
-
-  # The following line ensures that the Material Icons font is
-  # included with your application, so that you can use the icons in
-  # the material Icons class.
-  uses-material-design: true
-
-  # To add assets to your application, add an assets section, like this:
-  # assets:
-  #   - images/a_dot_burr.jpeg
-  #   - images/a_dot_ham.jpeg
-
-  # An image asset can refer to one or more resolution-specific "variants", see
-  # https://flutter.dev/to/resolution-aware-images
-
-  # For details regarding adding assets from package dependencies, see
-  # https://flutter.dev/to/asset-from-package
-
-  # To add custom fonts to your application, add a fonts section here,
-  # in this "flutter" section. Each entry in this list should have a
-  # "family" key with the font family name, and a "fonts" key with a
-  # list giving the asset and other descriptors for the font. For
-  # example:
-  # fonts:
-  #   - family: Schyler
-  #     fonts:
-  #       - asset: fonts/Schyler-Regular.ttf
-  #       - asset: fonts/Schyler-Italic.ttf
-  #         style: italic
-  #   - family: Trajan Pro
-  #     fonts:
-  #       - asset: fonts/TrajanPro.ttf
-  #       - asset: fonts/TrajanPro_Bold.ttf
-  #         weight: 700
-  #
-  # For details regarding fonts from package dependencies,
-  # see https://flutter.dev/to/font-from-package

+ 0 - 0
plugin/atmob_channel_reader/example/test/widget_test.dart


+ 3 - 3
plugin/atmob_channel_reader/lib/atmob_channel_reader.dart

@@ -7,15 +7,15 @@ class AtmobChannelReader {
         .default4Test(channel, tgPlatformId, appId);
   }
 
-  Future<String?> getChannel() {
+  static Future<String?> getChannel() {
     return AtmobChannelReaderPlatform.instance.getChannel();
   }
 
-  Future<int?> getAppId() {
+  static Future<int?> getAppId() {
     return AtmobChannelReaderPlatform.instance.getAppId();
   }
 
-  Future<int?> getTgPlatformId() {
+  static Future<int?> getTgPlatformId() {
     return AtmobChannelReaderPlatform.instance.getTgPlatformId();
   }
 }

+ 6 - 3
plugin/gravity_engine/lib/gravity_engine_method_channel.dart

@@ -81,7 +81,8 @@ class MethodChannelGravityEngine extends GravityEnginePlatform {
 enum PayType {
   alipay,
   wechat,
-  appStore,
+  apple,
+  unknown,
 }
 
 extension PayTypeExtension on PayType {
@@ -91,8 +92,10 @@ extension PayTypeExtension on PayType {
         return "支付宝";
       case PayType.wechat:
         return "微信";
-      case PayType.appStore:
-        return "AppStore";
+      case PayType.apple:
+        return "苹果支付";
+      default:
+        return "未知";
     }
   }
 }

+ 8 - 0
pubspec.lock

@@ -46,6 +46,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.4.0"
+  app_tracking_transparency:
+    dependency: "direct main"
+    description:
+      name: app_tracking_transparency
+      sha256: "64d9745931e565790abdea91b518ac8dc3cebe6d0d0aaf7119343271b983259a"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.6"
   archive:
     dependency: "direct main"
     description:

+ 2 - 0
pubspec.yaml

@@ -86,6 +86,8 @@ dependencies:
   #获取设备信息
   device_info_plus: ^10.1.2
   android_id: ^0.4.0
+  # 隐私追踪
+  app_tracking_transparency: ^2.0.5
 
   #文件选择
   file_picker: ^8.1.2