├── ios ├── Assets │ └── .gitkeep ├── Classes │ ├── GetuiflutPlugin.h │ └── GetuiflutPlugin.m ├── .gitignore └── getuiflut.podspec ├── res └── values │ └── strings_en.arb ├── .fvmrc ├── android ├── gradle.properties ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── getui │ │ │ └── getuiflut │ │ │ ├── FlutterPushService.java │ │ │ ├── GetuiPluginActivity.java │ │ │ ├── GetuiflutPlugin.java │ │ │ └── FlutterIntentService.java │ │ ├── AndroidManifest.xml │ │ └── res │ │ └── values │ │ └── strings.xml ├── build.gradle ├── gradlew.bat └── gradlew ├── .gitattributes ├── example ├── ohos │ ├── hvigor │ │ └── hvigor-config.json5 │ ├── entry │ │ ├── src │ │ │ └── main │ │ │ │ ├── resources │ │ │ │ ├── base │ │ │ │ │ ├── profile │ │ │ │ │ │ ├── main_pages.json │ │ │ │ │ │ └── buildinfo.json5 │ │ │ │ │ ├── element │ │ │ │ │ │ ├── color.json │ │ │ │ │ │ └── string.json │ │ │ │ │ └── media │ │ │ │ │ │ └── icon.png │ │ │ │ ├── zh_CN │ │ │ │ │ └── element │ │ │ │ │ │ └── string.json │ │ │ │ └── en_US │ │ │ │ │ └── element │ │ │ │ │ └── string.json │ │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ └── Index.ets │ │ │ │ └── entryability │ │ │ │ │ └── EntryAbility.ets │ │ │ │ └── module.json5 │ │ ├── oh-package.json5 │ │ ├── build-profile.json5 │ │ └── hvigorfile.ts │ ├── AppScope │ │ ├── resources │ │ │ └── base │ │ │ │ ├── media │ │ │ │ └── app_icon.png │ │ │ │ └── element │ │ │ │ └── string.json │ │ └── app.json5 │ ├── hvigorconfig.ts │ ├── oh-package.json5 │ ├── hvigorfile.ts │ └── build-profile.json5 ├── ios │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner │ │ ├── AppDelegate.h │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── File.swift │ │ ├── main.m │ │ ├── SceneDelegate.h │ │ ├── Runner.entitlements │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ ├── AppDelegate.m │ │ ├── Info.plist │ │ └── SceneDelegate.m │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── Podfile.lock │ └── Podfile ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── ent │ │ │ │ │ │ └── com │ │ │ │ │ │ └── getui │ │ │ │ │ │ └── getuiflut_example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle.kts │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── build.gradle.kts │ └── settings.gradle.kts ├── README.md ├── test │ └── widget_test.dart ├── .metadata ├── analysis_options.yaml ├── .gitignore ├── pubspec.yaml ├── pubspec.lock └── lib │ └── main.dart ├── ohos ├── libs │ └── GT-HM-1.0.9_u3.har ├── index.ets ├── build-profile.json5 ├── src │ └── main │ │ ├── module.json5 │ │ └── ets │ │ └── components │ │ └── plugin │ │ └── GetuiflutPlugin.ets ├── oh-package.json5 └── hvigorfile.ts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .metadata ├── test └── getuiflut_test.dart ├── .gitignore ├── .pubignore ├── .project ├── LICENSE ├── pubspec.yaml ├── CHANGELOG.md ├── pubspec.lock ├── README.md └── lib └── getuiflut.dart /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /res/values/strings_en.arb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.fvmrc: -------------------------------------------------------------------------------- 1 | { 2 | "flutter": "stable" 3 | } -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'getuiflut' 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.dart linguist-language=Dart 2 | *.java linguist-language=Dart 3 | -------------------------------------------------------------------------------- /example/ohos/hvigor/hvigor-config.json5: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "modelVersion": "5.0.0", 4 | "dependencies": { 5 | } 6 | } -------------------------------------------------------------------------------- /example/ohos/entry/src/main/resources/base/profile/main_pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": [ 3 | "pages/Index" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /ohos/libs/GT-HM-1.0.9_u3.har: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/ohos/libs/GT-HM-1.0.9_u3.har -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ohos/index.ets: -------------------------------------------------------------------------------- 1 | 2 | 3 | import GetuiflutPlugin from './src/main/ets/components/plugin/GetuiflutPlugin'; 4 | export default GetuiflutPlugin; 5 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /example/ohos/AppScope/resources/base/media/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ohos/AppScope/resources/base/media/app_icon.png -------------------------------------------------------------------------------- /example/ohos/entry/src/main/resources/base/profile/buildinfo.json5: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "enable_impeller", 5 | "value": "true" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /example/ohos/hvigorconfig.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { injectNativeModules } from 'flutter-hvigor-plugin'; 3 | 4 | injectNativeModules(__dirname, path.dirname(__dirname)) -------------------------------------------------------------------------------- /example/ohos/entry/src/main/resources/base/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "start_window_background", 5 | "value": "#FFFFFF" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /example/ohos/entry/src/main/resources/base/media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ohos/entry/src/main/resources/base/media/icon.png -------------------------------------------------------------------------------- /ohos/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | }, 5 | "targets": [ 6 | { 7 | "name": "default" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ohos/AppScope/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "app_name", 5 | "value": "flutter_harmony_plugin_example" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | /.idea 10 | .idea/ 11 | build/ 12 | android/.idea/* -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /android/src/main/java/com/getui/getuiflut/FlutterPushService.java: -------------------------------------------------------------------------------- 1 | package com.getui.getuiflut; 2 | 3 | 4 | import com.igexin.sdk.PushService; 5 | 6 | public class FlutterPushService extends PushService { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // Runner 4 | // 5 | // Created by ak on 2023/1/10. 6 | // Copyright © 2023 The Chromium Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GetuiLaboratory/getui-flutter-plugin/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/ent/com/getui/getuiflut_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package ent.com.getui.getuiflut_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity : FlutterActivity() 6 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Classes/GetuiflutPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface GetuiflutPlugin : NSObject 4 | @property FlutterMethodChannel *channel; 5 | + (void)handleSceneWillConnectWithOptions:(UISceneConnectionOptions *)connectionOptions; 6 | @end 7 | -------------------------------------------------------------------------------- /example/ohos/entry/oh-package.json5: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "entry", 4 | "version": "1.0.0", 5 | "description": "Please describe the basic information.", 6 | "main": "", 7 | "author": "", 8 | "license": "", 9 | "dependencies": { 10 | }, 11 | } 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Jun 25 16:45:27 CST 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /ohos/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "getuiflut", 4 | "type": "har", 5 | "deviceTypes": [ 6 | "default", 7 | "tablet" 8 | ], 9 | "requestPermissions": [ 10 | {"name": "ohos.permission.INTERNET"}, // 按需添加权限 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ohos/AppScope/app.json5: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "bundleName": "com.example.flutter_harmony_plugin_example", 4 | "vendor": "example", 5 | "versionCode": 1000000, 6 | "versionName": "1.0.0", 7 | "icon": "$media:app_icon", 8 | "label": "$string:app_name" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ohos/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getuiflut", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "index.ets", 6 | "author": "", 7 | "license": "Apache-2.0", 8 | "dependencies": { 9 | "@getui/push": "file:./libs/GT-HM-1.0.9_u3.har" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/SceneDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.h 3 | // SceneDemo 4 | // 5 | // Created by ak on 2023/10/17. 6 | // 7 | 8 | #import 9 | 10 | @interface SceneDelegate : UIResponder 11 | 12 | @property (strong, nonatomic) UIWindow * window; 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ohos/entry/build-profile.json5: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "apiType": 'stageMode', 4 | "buildOption": { 5 | "arkOptions": { 6 | 7 | } 8 | }, 9 | "targets": [ 10 | { 11 | "name": "default", 12 | "runtimeOS": "HarmonyOS" 13 | }, 14 | { 15 | "name": "ohosTest", 16 | } 17 | ], 18 | 19 | } -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | #distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip 6 | distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.12-all.zip 7 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 8661d8aecd626f7f57ccbcb735553edc05a2e713 8 | channel: beta 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /example/ohos/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "modelVersion": "5.0.0", 3 | "name": "flutter_harmony_plugin_example", 4 | "version": "1.0.0", 5 | "description": "Please describe the basic information.", 6 | "main": "", 7 | "author": "", 8 | "license": "", 9 | "dependencies": {}, 10 | "devDependencies": { 11 | "@ohos/hypium": "1.0.6" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ohos/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | // Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. 2 | import { harTasks } from '@ohos/hvigor-ohos-plugin'; 3 | 4 | export default { 5 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 6 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 7 | } -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Apr 12 17:31:13 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | #distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 7 | distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-6.7.1-bin.zip 8 | -------------------------------------------------------------------------------- /example/ohos/entry/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "模块描述" 6 | }, 7 | { 8 | "name": "EntryAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "EntryAbility_label", 13 | "value": "flutter_harmony_plugin_example" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /example/ohos/entry/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | 2 | // Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. 3 | import { hapTasks } from '@ohos/hvigor-ohos-plugin'; 4 | export default { 5 | system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 6 | plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ 7 | } 8 | -------------------------------------------------------------------------------- /example/ohos/entry/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "module description" 6 | }, 7 | { 8 | "name": "EntryAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "EntryAbility_label", 13 | "value": "flutter_harmony_plugin_example" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ohos/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { appTasks } from '@ohos/hvigor-ohos-plugin'; 3 | import { flutterHvigorPlugin } from 'flutter-hvigor-plugin'; 4 | 5 | export default { 6 | system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 7 | plugins:[flutterHvigorPlugin(path.dirname(__dirname))] /* Custom plugin to extend the functionality of Hvigor. */ 8 | } -------------------------------------------------------------------------------- /test/getuiflut_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:getuiflut/getuiflut.dart'; 3 | 4 | void main() { 5 | // const MethodChannel channel = MethodChannel('getuiflut'); 6 | 7 | setUp(() { 8 | }); 9 | 10 | tearDown(() { 11 | }); 12 | 13 | test('getPlatformVersion', () async { 14 | expect(await Getuiflut.platformVersion, '42'); 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | com.apple.developer.associated-domains 8 | 9 | applinks:link.applk.cn 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | /.idea 7 | .idea/ 8 | *.iml 9 | build/ 10 | /build 11 | .gradle 12 | android/.idea/* 13 | .settings 14 | flutter.iml 15 | getuiflut.iml 16 | .vscode 17 | 18 | Example/ios/Index/* 19 | example/.flutter-plugins-dependencies 20 | example/ios/Flutter/Flutter.podspec 21 | example/ios/Flutter/flutter_export_environment.sh 22 | lib/generated/i18n.dart 23 | 24 | # FVM Version Cache 25 | .fvm/ 26 | 27 | -------------------------------------------------------------------------------- /example/ohos/entry/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "module description" 6 | }, 7 | { 8 | "name": "EntryAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "EntryAbility_label", 13 | "value": "flutter_harmony_plugin_example" 14 | }, 15 | { 16 | "name": "tracking_reason", 17 | "value": "\"广告需要\"" 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /.pubignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | /.idea 7 | .idea/ 8 | *.iml 9 | build/ 10 | /build 11 | .gradle 12 | gradle 13 | android/.idea/* 14 | /android/.idea/* 15 | #.vscode/* 16 | Example/ios/Index/* 17 | example/.flutter-plugins-dependencies 18 | example/ios/Flutter/Flutter.podspec 19 | example/ios/Flutter/flutter_export_environment.sh 20 | lib/generated/i18n.dart 21 | .gradle/ 22 | android/.idea/ 23 | .settings 24 | flutter.iml 25 | getuiflut.iml 26 | .vscode 27 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | flutter 4 | Project flutter created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/src/main/java/com/getui/getuiflut/GetuiPluginActivity.java: -------------------------------------------------------------------------------- 1 | package com.getui.getuiflut; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import com.igexin.sdk.GTServiceManager; 6 | 7 | /** 8 | * Create by wanghb on 2020-02-24 9 | * Athor: monkeydbobo 10 | */ 11 | public class GetuiPluginActivity extends Activity { 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | GTServiceManager.getInstance().onActivityCreate(this); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # getuiflut_example 2 | 3 | Demonstrates how to use the getuiflut plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.io/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/ohos/entry/src/main/ets/pages/Index.ets: -------------------------------------------------------------------------------- 1 | 2 | import { FlutterPage } from '@ohos/flutter_ohos' 3 | import common from '@ohos.app.ability.common'; 4 | let storage = LocalStorage.getShared() 5 | const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' 6 | 7 | @Entry(storage) 8 | @Component 9 | struct Index { 10 | private context = getContext(this) as common.UIAbilityContext 11 | @LocalStorageLink('viewId') viewId: string = ""; 12 | 13 | build() { 14 | Column() { 15 | FlutterPage({ viewId: this.viewId }) 16 | } 17 | } 18 | 19 | onBackPress(): boolean { 20 | this.context.eventHub.emit(EVENT_BACK_PRESS) 21 | return true 22 | } 23 | 24 | aboutToAppear() { 25 | 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /example/android/build.gradle.kts: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | maven { 6 | url = uri("https://mvn.getui.com/nexus/content/repositories/releases/") 7 | } 8 | } 9 | } 10 | 11 | val newBuildDir: Directory = 12 | rootProject.layout.buildDirectory 13 | .dir("../../build") 14 | .get() 15 | rootProject.layout.buildDirectory.value(newBuildDir) 16 | 17 | subprojects { 18 | val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) 19 | project.layout.buildDirectory.value(newSubprojectBuildDir) 20 | } 21 | subprojects { 22 | project.evaluationDependsOn(":app") 23 | } 24 | 25 | tasks.register("clean") { 26 | delete(rootProject.layout.buildDirectory) 27 | } 28 | -------------------------------------------------------------------------------- /ios/getuiflut.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'getuiflut' 6 | s.version = '0.0.1' 7 | s.summary = 'getui plugin flutter' 8 | s.description = <<-DESC 9 | getui plugin flutter 10 | DESC 11 | s.homepage = 'http://example.com' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Your Company' => 'email@example.com' } 14 | s.source = { :path => '.' } 15 | s.source_files = 'Classes/**/*' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.dependency 'Flutter' 18 | s.dependency 'GTSDK' 19 | 20 | s.ios.deployment_target = '8.0' 21 | s.static_framework = true 22 | end 23 | 24 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | void main() { 12 | testWidgets('Verify Platform version', (WidgetTester tester) async { 13 | // Build our app and trigger a frame. 14 | // await tester.pumpWidget(MyApp()); 15 | 16 | // Verify that platform version is retrieved. 17 | expect( 18 | find.byWidgetPredicate( 19 | (Widget widget) => widget is Text && 20 | widget.data.startsWith('Running on:'), 21 | ), 22 | findsOneWidget, 23 | ); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - getuiflut (0.0.1): 4 | - Flutter 5 | - GTSDK 6 | - GTCommonSDK (3.1.10.0): 7 | - ZXSDK 8 | - GTSDK (3.0.10.0): 9 | - GTCommonSDK (> 3.0.9.0) 10 | - ZXSDK (3.3.2) 11 | 12 | DEPENDENCIES: 13 | - Flutter (from `Flutter`) 14 | - getuiflut (from `.symlinks/plugins/getuiflut/ios`) 15 | 16 | SPEC REPOS: 17 | https://github.com/CocoaPods/Specs.git: 18 | - GTCommonSDK 19 | - GTSDK 20 | - ZXSDK 21 | 22 | EXTERNAL SOURCES: 23 | Flutter: 24 | :path: Flutter 25 | getuiflut: 26 | :path: ".symlinks/plugins/getuiflut/ios" 27 | 28 | SPEC CHECKSUMS: 29 | Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 30 | getuiflut: ea9b200062f474810671171f9f36985ff5d431d0 31 | GTCommonSDK: aa0cdaada5e31c2dc173c8170127d50f16a439c7 32 | GTSDK: 1a2e62b50cf265046c2e48cdb88cd3d8e62bd7ea 33 | ZXSDK: 786338c0a18e98e03eda00699c3bfd2700b97117 34 | 35 | PODFILE CHECKSUM: 5b2178d2ba7918cc634057a5ee2c59098ebd663d 36 | 37 | COCOAPODS: 1.16.2 38 | -------------------------------------------------------------------------------- /example/android/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | val flutterSdkPath = 3 | run { 4 | val properties = java.util.Properties() 5 | file("local.properties").inputStream().use { properties.load(it) } 6 | val flutterSdkPath = properties.getProperty("flutter.sdk") 7 | require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } 8 | flutterSdkPath 9 | } 10 | 11 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 12 | 13 | repositories { 14 | google() 15 | mavenCentral() 16 | gradlePluginPortal() 17 | maven { 18 | url = uri("https://mvn.getui.com/nexus/content/repositories/releases/") 19 | } 20 | } 21 | } 22 | 23 | plugins { 24 | id("dev.flutter.flutter-plugin-loader") version "1.0.0" 25 | id("com.android.application") version "8.9.1" apply false 26 | id("org.jetbrains.kotlin.android") version "2.1.0" apply false 27 | } 28 | 29 | include(":app") 30 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.getui.getuiflut' 2 | version '1.0-SNAPSHOT' 3 | buildscript { 4 | repositories { 5 | mavenCentral() 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:4.2.0' 12 | } 13 | } 14 | rootProject.allprojects { 15 | repositories { 16 | mavenCentral() 17 | //Maven URL地址 18 | maven { 19 | url "https://mvn.getui.com/nexus/content/repositories/releases/" 20 | } 21 | jcenter() 22 | google() 23 | } 24 | } 25 | apply plugin: 'com.android.library' 26 | android { 27 | namespace 'com.getui.getuiflut' 28 | compileSdkVersion 34 29 | defaultConfig { 30 | minSdkVersion 17 31 | } 32 | 33 | lintOptions { 34 | disable 'InvalidPackage' 35 | } 36 | } 37 | repositories { 38 | flatDir { 39 | dirs 'libs' 40 | } 41 | } 42 | dependencies { 43 | implementation 'com.google.code.gson:gson:2.10.1' 44 | compileOnly('com.getui:gtsdk:3.3.7.0') 45 | 46 | } -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 15 | 16 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "9f455d2486bcb28cad87b062475f42edc959f636" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 9f455d2486bcb28cad87b062475f42edc959f636 17 | base_revision: 9f455d2486bcb28cad87b062475f42edc959f636 18 | - platform: android 19 | create_revision: 9f455d2486bcb28cad87b062475f42edc959f636 20 | base_revision: 9f455d2486bcb28cad87b062475f42edc959f636 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 个推实验室 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | source 'https://github.com/CocoaPods/Specs.git' 3 | platform :ios, '13.0' 4 | 5 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 6 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 7 | 8 | project 'Runner', { 9 | 'Debug' => :debug, 10 | 'Profile' => :release, 11 | 'Release' => :release, 12 | } 13 | 14 | def flutter_root 15 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 16 | unless File.exist?(generated_xcode_build_settings_path) 17 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 18 | end 19 | 20 | File.foreach(generated_xcode_build_settings_path) do |line| 21 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 22 | return matches[1].strip if matches 23 | end 24 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 25 | end 26 | 27 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 28 | 29 | flutter_ios_podfile_setup 30 | 31 | target 'Runner' do 32 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 33 | end 34 | 35 | post_install do |installer| 36 | installer.pods_project.targets.each do |target| 37 | flutter_additional_ios_build_settings(target) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at https://dart.dev/lints. 17 | # 18 | # Instead of disabling a lint rule for the entire project in the 19 | # section below, it can also be suppressed for a single line of code 20 | # or a specific dart file by using the `// ignore: name_of_lint` and 21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 22 | # producing the lint. 23 | rules: 24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 26 | 27 | # Additional information about this file can be found at 28 | # https://dart.dev/guides/language/analysis-options 29 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ohos/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "signingConfigs": [ 4 | { 5 | "name": "default", 6 | "type": "HarmonyOS", 7 | "material": { 8 | "certpath": "/Users/yangsihao/.ohos/config/default_ohos_PzixlcW-H-xWgV722Mb1Iin8feL8jOLcA0ERA6pzRzI=.cer", 9 | "keyAlias": "debugKey", 10 | "keyPassword": "0000001A8FE2752B61C7F318754A2490D625882175F0B879BE602C3042B2BCD8D930AB19AD9C4CAE2ED4", 11 | "profile": "/Users/yangsihao/.ohos/config/default_ohos_PzixlcW-H-xWgV722Mb1Iin8feL8jOLcA0ERA6pzRzI=.p7b", 12 | "signAlg": "SHA256withECDSA", 13 | "storeFile": "/Users/yangsihao/.ohos/config/default_ohos_PzixlcW-H-xWgV722Mb1Iin8feL8jOLcA0ERA6pzRzI=.p12", 14 | "storePassword": "0000001A52BF65262D1DBD706B25EF6C21E04D92734BF757BBFF2E8241E56084995A394A56279FEF3B97" 15 | } 16 | } 17 | ], 18 | "products": [ 19 | { 20 | "name": "default", 21 | "signingConfig": "default", 22 | "compatibleSdkVersion": "5.0.4(16)", 23 | "runtimeOS": "HarmonyOS", 24 | "buildOption": { 25 | "strictMode": { 26 | "useNormalizedOHMUrl": true 27 | } 28 | } 29 | } 30 | ], 31 | "buildModeSet": [ 32 | { 33 | "name": "debug" 34 | }, 35 | { 36 | "name": "profile" 37 | }, 38 | { 39 | "name": "release" 40 | } 41 | ] 42 | }, 43 | "modules": [ 44 | { 45 | "name": "entry", 46 | "srcPath": "./entry", 47 | "targets": [ 48 | { 49 | "name": "default", 50 | "applyToProducts": [ 51 | "default" 52 | ] 53 | } 54 | ] 55 | } 56 | ] 57 | } -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | //MARK: - 非Scene场景 7 | //- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | // [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // 10 | // return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | //} 12 | // 13 | //- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { 14 | // //warning: 需要重写当前方法,gtsdk的接管系统方法就会生效,否则会影响回执 15 | // //保持空实现 16 | //} 17 | 18 | //MARK: - Scene场景 (需要配置Info.plist Application Scene Manifest) 19 | 20 | - (BOOL)application:(UIApplication *)application 21 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 22 | if (@available(iOS 13, *)) { 23 | // iOS 13+ 由 SceneDelegate 处理 24 | } 25 | else { 26 | // iOS 12 及以下,从 launchOptions 获取通知 27 | // 插件的didFinishLaunchingWithOptions会被触发 来获取launchOptions 28 | } 29 | 30 | return YES; 31 | } 32 | 33 | - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { 34 | // 配置场景连接时的场景配置 35 | return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; 36 | } 37 | 38 | - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { 39 | // 当用户放弃场景会话时调用 40 | // 释放与被丢弃场景相关的资源 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /example/ohos/entry/src/main/ets/entryability/EntryAbility.ets: -------------------------------------------------------------------------------- 1 | 2 | import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos'; 3 | import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant'; 4 | import GetuiflutPlugin from 'getuiflut'; 5 | import { AbilityConstant, Want } from '@kit.AbilityKit'; 6 | import { hilog } from '@kit.PerformanceAnalysisKit'; 7 | 8 | class JsonUtils { 9 | static hasGttask(gtdata: object): boolean { 10 | return gtdata['gttask'] !== undefined; 11 | } 12 | } 13 | 14 | export default class EntryAbility extends FlutterAbility { 15 | configureFlutterEngine(flutterEngine: FlutterEngine) { 16 | super.configureFlutterEngine(flutterEngine) 17 | GeneratedPluginRegistrant.registerWith(flutterEngine) 18 | } 19 | 20 | onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 21 | hilog.info(0x0000, 'EntryAbility', '%{public}s', 'Ability onCreate'); 22 | if (want && want.parameters && want.parameters['gtdata']) { 23 | //注意这里的判断条件,在线点击通知回执和离线报表补全有区别 24 | if (!JsonUtils.hasGttask(want.parameters['gtdata'])) { 25 | 26 | GetuiflutPlugin.setClickWant(want); 27 | hilog.info(0x0000, 'EntryAbility', 'onCreate PushManager.setClickWant'); 28 | } 29 | } 30 | return super.onCreate(want,launchParam) 31 | } 32 | 33 | onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { 34 | hilog.info(0x0000, 'EntryAbility', 'onNewWant info = ' + JSON.stringify(want)); 35 | if (want && want.parameters && want.parameters['gtdata']) { 36 | if (!JsonUtils.hasGttask(want.parameters['gtdata'])) { 37 | GetuiflutPlugin.setClickWant(want); 38 | hilog.info(0x0000, 'EntryAbility', 'onCreate PushManager.setClickWant'); 39 | } 40 | } 41 | return super.onNewWant(want,launchParam) 42 | 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /example/ohos/entry/src/main/module.json5: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "module": { 4 | "name": "entry", 5 | "type": "entry", 6 | "description": "$string:module_desc", 7 | "mainElement": "EntryAbility", 8 | "deviceTypes": [ 9 | "phone" 10 | ], 11 | "deliveryWithInstall": true, 12 | "installationFree": false, 13 | "pages": "$profile:main_pages", 14 | "abilities": [ 15 | { 16 | "name": "EntryAbility", 17 | "srcEntry": "./ets/entryability/EntryAbility.ets", 18 | "description": "$string:EntryAbility_desc", 19 | "icon": "$media:icon", 20 | "label": "$string:EntryAbility_label", 21 | "startWindowIcon": "$media:icon", 22 | "startWindowBackground": "$color:start_window_background", 23 | "exported": true, 24 | "skills": [ 25 | { 26 | "entities": [ 27 | "entity.system.home" 28 | ], 29 | "actions": [ 30 | "action.system.home" 31 | ] 32 | } 33 | ] 34 | } 35 | ], 36 | "requestPermissions": [ 37 | {"name" : "ohos.permission.INTERNET"}, 38 | { 39 | "name": "ohos.permission.GET_NETWORK_INFO" 40 | }, 41 | { 42 | "name": "ohos.permission.KEEP_BACKGROUND_RUNNING" 43 | }, 44 | { 45 | "name": "ohos.permission.APP_TRACKING_CONSENT", 46 | "reason": "$string:tracking_reason", 47 | "usedScene": { 48 | "abilities": [ 49 | "EntryAbility" 50 | ] 51 | } 52 | } 53 | ], 54 | 55 | "metadata": [ 56 | { 57 | "name": "GETUI_APPID", 58 | "value": "djYjSlFVMf6p5YOy2OQUs8"//你的APPID 59 | }, 60 | { 61 | "name": "ZX_CHANNELID_GT", 62 | "value": "C01-GEztJH0JLdBC" 63 | }, 64 | { 65 | "name": "client_id", 66 | // 配置为步骤1中获取的Client ID 67 | "value": "109599703", //你的厂商推送id 68 | }, 69 | { 70 | "name": "GT_PUSH_LOG", 71 | "value": "true" //SDK文件日志开关 72 | } 73 | ] 74 | } 75 | } -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: 'getuiflut_example' 2 | number: 1.0.0 3 | description: Demonstrates how to use the getuiflut plugin. 4 | publish_to: 'none' 5 | 6 | environment: 7 | sdk: ">=2.12.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | # The following adds the Cupertino Icons font to your application. 14 | # Use with the CupertinoIcons class for iOS style icons. 15 | cupertino_icons: ^1.0.6 16 | 17 | dev_dependencies: 18 | flutter_test: 19 | sdk: flutter 20 | 21 | getuiflut: 22 | path: ../ 23 | 24 | # For information on the generic Dart part of this file, see the 25 | # following page: https://www.dartlang.org/tools/pub/pubspec 26 | 27 | # The following section is specific to Flutter. 28 | flutter: 29 | 30 | # The following line ensures that the Material Icons font is 31 | # included with your application, so that you can use the icons in 32 | # the material Icons class. 33 | uses-material-design: true 34 | 35 | # To add assets to your application, add an assets section, like this: 36 | # assets: 37 | # - images/a_dot_burr.jpeg 38 | # - images/a_dot_ham.jpeg 39 | 40 | # An image asset can refer to one or more resolution-specific "variants", see 41 | # https://flutter.io/assets-and-images/#resolution-aware. 42 | 43 | # For details regarding adding assets from package dependencies, see 44 | # https://flutter.io/assets-and-images/#from-packages 45 | 46 | # To add custom fonts to your application, add a fonts section here, 47 | # in this "flutter" section. Each entry in this list should have a 48 | # "family" key with the font family name, and a "fonts" key with a 49 | # list giving the asset and other descriptors for the font. For 50 | # example: 51 | # fonts: 52 | # - family: Schyler 53 | # fonts: 54 | # - asset: fonts/Schyler-Regular.ttf 55 | # - asset: fonts/Schyler-Italic.ttf 56 | # style: italic 57 | # - family: Trajan Pro 58 | # fonts: 59 | # - asset: fonts/TrajanPro.ttf 60 | # - asset: fonts/TrajanPro_Bold.ttf 61 | # weight: 700 62 | # 63 | # For details regarding fonts from package dependencies, 64 | # see https://flutter.io/custom-fonts/#from-packages 65 | -------------------------------------------------------------------------------- /example/android/app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | id("kotlin-android") 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id("dev.flutter.flutter-gradle-plugin") 6 | } 7 | 8 | android { 9 | namespace = "ent.com.getui.getuiflut_example" 10 | compileSdk = flutter.compileSdkVersion 11 | ndkVersion = flutter.ndkVersion 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_11 15 | targetCompatibility = JavaVersion.VERSION_11 16 | } 17 | 18 | kotlinOptions { 19 | jvmTarget = JavaVersion.VERSION_11.toString() 20 | } 21 | 22 | defaultConfig { 23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 24 | applicationId = "ent.com.getui.getuiflut_example" 25 | // You can update the following values to match your application needs. 26 | // For more information, see: https://flutter.dev/to/review-gradle-config. 27 | minSdk = flutter.minSdkVersion 28 | targetSdk = flutter.targetSdkVersion 29 | versionCode = 1 30 | versionName = "1.0" 31 | manifestPlaceholders.putAll(mapOf( 32 | "GETUI_APPID" to "djYjSlFVMf6p5YOy2OQUs8", 33 | "GETUI_APP_ID" to "djYjSlFVMf6p5YOy2OQUs8", 34 | "XIAOMI_APP_ID" to "", 35 | "XIAOMI_APP_KEY" to "", 36 | "MEIZU_APP_ID" to "", 37 | "MEIZU_APP_KEY" to "", 38 | "HUAWEI_APP_ID" to "", 39 | "OPPO_APP_KEY" to "", 40 | "OPPO_APP_SECRET" to "", 41 | "VIVO_APP_ID" to "", 42 | "VIVO_APP_KEY" to "" 43 | )) 44 | 45 | } 46 | 47 | buildTypes { 48 | release { 49 | // TODO: Add your own signing config for the release build. 50 | // Signing with the debug keys for now, so `flutter run --release` works. 51 | signingConfig = signingConfigs.getByName("debug") 52 | } 53 | } 54 | } 55 | 56 | flutter { 57 | source = "../.." 58 | } 59 | dependencies { 60 | implementation("com.getui:gtsdk:3.3.12.0") // 修复:使用 () 和双引号 61 | implementation("com.getui:gtc:3.2.18.0") // 修复:使用 () 和双引号 62 | 63 | } -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: getuiflut 2 | description: getui flutter plugin 3 | version: 0.2.40 4 | homepage: https://www.getui.com 5 | 6 | environment: 7 | sdk: ">=2.12.0 <4.0.0" 8 | flutter: ">=1.12.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | 18 | # For information on the generic Dart part of this file, see the 19 | # following page: https://www.dartlang.org/tools/pub/pubspec 20 | 21 | # The following section is specific to Flutter. 22 | flutter: 23 | # This section identifies this Flutter project as a plugin project. 24 | # The androidPackage and pluginClass identifiers should not ordinarily 25 | # be modified. They are used by the tooling to maintain consistency when 26 | # adding or updating assets for this project. 27 | plugin: 28 | platforms: 29 | android: 30 | package: com.getui.getuiflut 31 | pluginClass: GetuiflutPlugin 32 | ios: 33 | pluginClass: GetuiflutPlugin 34 | ohos: 35 | pluginClass: GetuiflutPlugin 36 | 37 | # To add assets to your plugin package, add an assets section, like this: 38 | # assets: 39 | # - images/a_dot_burr.jpeg 40 | # - images/a_dot_ham.jpeg 41 | # 42 | # For details regarding assets in packages, see 43 | # https://flutter.io/assets-and-images/#from-packages 44 | # 45 | # An image asset can refer to one or more resolution-specific "variants", see 46 | # https://flutter.io/assets-and-images/#resolution-aware. 47 | 48 | # To add custom fonts to your plugin package, add a fonts section here, 49 | # in this "flutter" section. Each entry in this list should have a 50 | # "family" key with the font family name, and a "fonts" key with a 51 | # list giving the asset and other descriptors for the font. For 52 | # example: 53 | # fonts: 54 | # - family: Schyler 55 | # fonts: 56 | # - asset: fonts/Schyler-Regular.ttf 57 | # - asset: fonts/Schyler-Italic.ttf 58 | # style: italic 59 | # - family: Trajan Pro 60 | # fonts: 61 | # - asset: fonts/TrajanPro.ttf 62 | # - asset: fonts/TrajanPro_Bold.ttf 63 | # weight: 700 64 | # 65 | # For details regarding fonts in packages, see 66 | # https://flutter.io/custom-fonts/#from-packages 67 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 17 | 21 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 35 | 36 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | 111Storyboard Name 15 | 16 | UISceneConfigurationName 17 | Default Configuration 18 | UISceneDelegateClassName 19 | SceneDelegate 20 | 21 | 22 | 23 | 24 | CFBundleDevelopmentRegion 25 | en 26 | CFBundleExecutable 27 | $(EXECUTABLE_NAME) 28 | CFBundleIdentifier 29 | $(PRODUCT_BUNDLE_IDENTIFIER) 30 | CFBundleInfoDictionaryVersion 31 | 6.0 32 | CFBundleName 33 | getuiflut_example 34 | CFBundlePackageType 35 | APPL 36 | CFBundleShortVersionString 37 | $(FLUTTER_BUILD_NAME) 38 | CFBundleSignature 39 | ???? 40 | CFBundleVersion 41 | $(FLUTTER_BUILD_NUMBER) 42 | LSRequiresIPhoneOS 43 | 44 | UIBackgroundModes 45 | 46 | fetch 47 | remote-notification 48 | voip 49 | 50 | UILaunchStoryboardName 51 | LaunchScreen 52 | UIMainStoryboardFile 53 | Main 54 | UISupportedInterfaceOrientations 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationLandscapeLeft 58 | UIInterfaceOrientationLandscapeRight 59 | 60 | UISupportedInterfaceOrientations~ipad 61 | 62 | UIInterfaceOrientationPortrait 63 | UIInterfaceOrientationPortraitUpsideDown 64 | UIInterfaceOrientationLandscapeLeft 65 | UIInterfaceOrientationLandscapeRight 66 | 67 | UIViewControllerBasedStatusBarAppearance 68 | 69 | CADisableMinimumFrameDurationOnPhone 70 | 71 | UIApplicationSupportsIndirectInputEvents 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /example/ios/Runner/SceneDelegate.m: -------------------------------------------------------------------------------- 1 | #import "SceneDelegate.h" 2 | #import 3 | #import "GeneratedPluginRegistrant.h" 4 | #import 5 | #import "GetuiflutPlugin.h" 6 | 7 | @interface SceneDelegate () 8 | 9 | @end 10 | 11 | @implementation SceneDelegate 12 | 13 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { 14 | // 配置窗口场景 15 | if (@available(iOS 13.0, *)) { 16 | UIWindowScene *windowScene = (UIWindowScene *)scene; 17 | self.window = [[UIWindow alloc] initWithWindowScene:windowScene]; 18 | } else { 19 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 20 | } 21 | 22 | // 创建并设置 Flutter 视图控制器 23 | FlutterViewController *flutterViewController = [FlutterViewController new]; 24 | self.window.rootViewController = flutterViewController; 25 | 26 | // 注册 Flutter 插件 27 | [GeneratedPluginRegistrant registerWithRegistry:flutterViewController]; 28 | 29 | // 处理连接选项中的通知 30 | UNNotification *note = connectionOptions.notificationResponse.notification; 31 | NSDictionary *userInfo = note.request.content.userInfo; 32 | UNNotificationTrigger *trigger = note.request.trigger; 33 | NSLog(@">>>GTSDK [ TestDemo ] willConnectToSession %@", userInfo); 34 | if (note && userInfo) { 35 | if ([trigger isKindOfClass:[UNPushNotificationTrigger class]]) { 36 | NSLog(@">>>GTSDK [ TestDemo ] 远程通知"); 37 | } else { 38 | NSLog(@">>>GTSDK [ TestDemo ] 本地通知"); 39 | } 40 | } 41 | 42 | //用于获取UIScene模式下的通知数据 43 | [GetuiflutPlugin handleSceneWillConnectWithOptions:connectionOptions]; 44 | 45 | // // 初始化个推SDK 46 | // [GeTuiSdk startSdkWithAppId:@"xXmjbbab3b5F1m7wAYZoG2" appKey:@"2" appSecret:@"3" delegate:self launchingOptions:nil]; 47 | // [GeTuiSdk registerRemoteNotification: (UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)]; 48 | 49 | // 使窗口可见 50 | [self.window makeKeyAndVisible]; 51 | } 52 | 53 | - (void)sceneDidBecomeActive:(UIScene *)scene { 54 | // 应用变为活动状态时调用 55 | NSLog(@"[ TestDemo ] sceneDidBecomeActive %@", scene); 56 | } 57 | 58 | - (void)sceneWillResignActive:(UIScene *)scene { 59 | // 应用即将变为非活动状态时调用 60 | } 61 | 62 | - (void)sceneWillEnterForeground:(UIScene *)scene { 63 | // 应用即将进入前台时调用 64 | NSLog(@"[ TestDemo ] sceneWillEnterForeground %@", scene); 65 | } 66 | 67 | - (void)sceneDidEnterBackground:(UIScene *)scene { 68 | // 应用进入后台时调用 69 | } 70 | 71 | - (void)sceneDidDisconnect:(UIScene *)scene { 72 | // 场景断开连接时调用 73 | } 74 | @end 75 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.9 2 | 3 | 1.新增bindAlias& unbindAlias &setBadge & resetBadge接口 4 | 2.新增setTags接口 5 | 3.完善readme 6 | 4.添加支持静态库 7 | 5.修复已知问题 8 | 9 | ## 0.2.1 10 | 1.新增setLocalBadge接口 11 | 12 | ## 0.2.3 13 | 1.新增getLaunchNotification 14 | 15 | ## 0.2.4 16 | 1. iOS application:continueUserActivity:restorationHandler 避免userActivity被系统清除 17 | * TODO: Describe initial release. 18 | 19 | ## 0.2.5 20 | 1. 升级安卓个推和厂商SDK 21 | 2. 增加turnOnPush接口 22 | 3. stopPush接口修改为turnOffPush 23 | 24 | ## 0.2.6 25 | 1. 升级iOS GTSDK到2.5.4.0 26 | 2. iOS侧不再支持voip 27 | 28 | ## 0.2.7 29 | 1. 修复GTSDK兼容性问题 30 | 31 | ## 0.2.8 32 | 1. iOS GTSDK 增加插件回调事件 33 | 34 | ## 0.2.9 35 | 1. 安卓升级flutter,替换过期方法 36 | 37 | 38 | ## 0.2.10 39 | 1. 支持 null safe 40 | 41 | ## 0.2.11 42 | 1. 去除v4包 43 | 44 | ## 0.2.12 45 | 1. 兼容iOS GTSDK 2.6.4.0 46 | 2. 增加setPushMode API 47 | 48 | ## 0.2.13 49 | 1.修改Android集成方式 50 | 51 | ## 0.2.14 52 | 提供函数给用户传递信息 GetuiflutPlugin.transmitUserMessage(map) 53 | 54 | ## 0.2.15 55 | 1. 兼容iOS GTSDK 2.7.0.0 56 | 2. iOS增加授权状态回调 onGrantAuthorization 57 | 3. continueUserActivity返回YES 58 | 59 | ## 0.2.16 60 | 1. 兼容Android setBadge接口 61 | 62 | ## 0.2.17 63 | 1. iOS 添加startSdkSimple、registerRemoteNotification、sdkVersion插件方法 64 | 2. android 适配Android 13 65 | 66 | ## 0.2.18 67 | 1. iOS 添加registerActivityToken插件方法 68 | 2. 69 | ## 0.2.19 70 | 1.android 不再默认依赖GTSDK 71 | 72 | 73 | ## 0.2.20 74 | 1.android 扩展unbindAlias函数 75 | 76 | ## 0.2.21 77 | 1.android 扩展unbindAlias函数,bindAlias函数 78 | 79 | ## 0.2.22 80 | 1.android 修复setBadge函数 81 | 82 | ## 0.2.23 83 | 1. iOS 修复APNs静默回调问题, 新增runBackgroundEnable 84 | 85 | ## 0.2.24 86 | 1. iOS 升级实时活动(灵动岛)API,2. 修复冷启动点击回执。3. 修改静默回调处理 87 | 88 | ## 0.2.25 89 | 1. 升级dart版本为 ">=2.12.0 <=3.2.3" 90 | 2. 91 | ## 0.2.26 92 | 1. andoird GetuiflutPlugin 实例在初始化的时候设置 93 | 94 | ## 0.2.27 95 | 1. 提高dart版本 96 | 97 | ## 0.2.28 98 | 1. Android 增加SetTag、Alias回调 99 | 100 | 101 | ## 0.2.29 102 | 1. iOS 增加API registerDeviceToken 103 | 104 | ## 0.2.30 105 | 1. 增加onReceiveOnlineState 106 | 2. Android 增加onNotificationMessageClicked 107 | 108 | 109 | ## 0.2.31 110 | 1. 增加onReceiveOnlineState 修复 111 | 112 | 113 | ## 0.2.32 114 | 1. iOS适配灵动岛API,GTSDK 3.0.7.0 115 | 2. 修复已知问题 116 | 117 | ## 0.2.33 118 | 1. iOS增加API getLaunchOptions 119 | 120 | ## 0.2.34 121 | 1. iOS onReceiveOnlineState回调参数bool改为string,避免dart2兼容性问题 122 | 123 | ## 0.2.35 124 | 1.iOS 删除getLaunchOptions,新增getLaunchLocalNotification性问题 125 | 126 | ## 0.2.36 127 | 1.iOS 修改getLaunchLocalNotification返回值 128 | 129 | 130 | ## 0.2.37 131 | 1.android 增加namespace 132 | 133 | ## 0.2.38 134 | 1. 支持ohos 135 | 2. 删除onReceiveMessageData. 使用onReceivePayload替换 136 | 3. initGetuiSdk等类方法,全部改为对象实例方法 137 | 4. 增加queryTag(sn) IOS不支持 138 | 5. 修改setTag(tags)为setTag(tags,sn) 旧版本Android中sn固定为“setTag”,iOS的sn会根据tags自动生成sn 139 | 6. 增加setSilentTime 、 sendFeedbackMessage 140 | 141 | ## 0.2.39 142 | 1. compileSdkVersion 改为34 143 | 2. FlutterIntentService bug修复 144 | 145 | ## 0.2.40 146 | 1. iOS兼容UIScene场景,新增handleSceneWillConnectWithOptions API 147 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /android/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 个推演示 4 | 通知栏/透传测试 5 | 高级功能 6 | 应用信息 7 | 个推Demo 8 | (none) 9 | 已启动 10 | ClientID: 11 | 已停止 12 | 透传测试 13 | 通知测试 14 | 透传内容 15 | 开始时间(beginHour) 16 | 持续时间(durationHour) 17 | 绑定别名 18 | 绑定别名失败,未知异常 19 | 绑定别名成功 20 | 绑定别名失败,请求频次超限 21 | 绑定别名失败,参数错误 22 | 绑定别名失败,请求被过滤 23 | 绑定别名失败,未获取到cid 24 | 绑定别名失败,网络错误 25 | 绑定别名失败,别名无效 26 | 绑定别名失败,sn无效 27 | 解绑别名 28 | 取消绑定别名失败,未知异常 29 | 取消绑定别名成功 30 | 取消绑定别名失败,请求频次超限 31 | 取消绑定别名失败,参数错误 32 | 取消绑定别名失败,请求被过滤 33 | 取消绑定别名失败,未获取到cid 34 | 取消绑定别名失败,网络错误 35 | 取消绑定别名失败,别名无效 36 | 取消绑定别名失败,sn无效 37 | 添加Tag 38 | 设置标签失败,未知异常 39 | 接口调用成功 40 | 接口调用失败, tag数量过大, 最大不能超过200个 41 | 设置标签失败,超出频次限制 42 | 接口调用失败, tag 为空 43 | 接口调用失败, sn 为空 44 | 设置标签失败, 标签重复 45 | 设置标签失败, 服务未初始化成功 46 | 还未登陆成功 47 | 该应用已经在黑名单中,请联系售后支持! 48 | 已存 tag 超过限制 49 | TAG不合法,请检查! 50 | 确定设置 51 | 通知栏测试 52 | 通知栏测试 53 | 您收到一条测试消息,点击访问 54 | 收到一条透传测试消息 55 | 对不起,当前网络不可用! 56 | 40字节以内,支持中,英文(区分大小写)、数字以及下划线,每次设置都会覆盖之前的别名 57 | 输入已绑定过的别名,将已绑定的别名解绑 58 | 0-23(单位小时) 59 | 0-23(单位小时),为0则不静默 60 | 在线 61 | 离线 62 | 日志已清除 63 | CID为空 64 | 复制成功 65 | 发送成功 66 | 确认绑定 67 | 确认解绑 68 | 请输入别名 69 | 绑定请求已发送 70 | 解除绑定请求已发送 71 | 时间格式错误,请检查格式 72 | 静默时间设置 73 | Tag设置 74 | Tag长度不能大于40 75 | Tag为空 76 | 确定设置 77 | 请输入Tag名 78 | 支持中文、英文字母、数字、除英文逗号以外的其他特殊符号 79 | SDK服务: 80 | 在线/离线 81 | CID状态: 82 | 复制 83 | 应用名称 84 | 包名 85 | SDK版本号 86 | 标签是用户的一种属性,设置标签后即可针对用户推送,默认套餐一天仅能设置一次 87 | 对已安装某应用的用户取别名来标识,对该用户消息推送时,可用此别名来推送。 88 | 调用接口设置静默时间,在静默时间期间SDK将不再联网 89 | 90 | 温馨提示 91 | 检测到您的通知权限已关闭,暂无法接收通知消息,请前往开启 92 | 取消 93 | 去设置 94 | 95 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.4.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.2" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.19.1" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.3.3" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_test: 58 | dependency: "direct dev" 59 | description: flutter 60 | source: sdk 61 | version: "0.0.0" 62 | leak_tracker: 63 | dependency: transitive 64 | description: 65 | name: leak_tracker 66 | sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" 67 | url: "https://pub.flutter-io.cn" 68 | source: hosted 69 | version: "11.0.1" 70 | leak_tracker_flutter_testing: 71 | dependency: transitive 72 | description: 73 | name: leak_tracker_flutter_testing 74 | sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" 75 | url: "https://pub.flutter-io.cn" 76 | source: hosted 77 | version: "3.0.10" 78 | leak_tracker_testing: 79 | dependency: transitive 80 | description: 81 | name: leak_tracker_testing 82 | sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" 83 | url: "https://pub.flutter-io.cn" 84 | source: hosted 85 | version: "3.0.2" 86 | matcher: 87 | dependency: transitive 88 | description: 89 | name: matcher 90 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 91 | url: "https://pub.flutter-io.cn" 92 | source: hosted 93 | version: "0.12.17" 94 | material_color_utilities: 95 | dependency: transitive 96 | description: 97 | name: material_color_utilities 98 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 99 | url: "https://pub.flutter-io.cn" 100 | source: hosted 101 | version: "0.11.1" 102 | meta: 103 | dependency: transitive 104 | description: 105 | name: meta 106 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c 107 | url: "https://pub.flutter-io.cn" 108 | source: hosted 109 | version: "1.16.0" 110 | path: 111 | dependency: transitive 112 | description: 113 | name: path 114 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" 115 | url: "https://pub.flutter-io.cn" 116 | source: hosted 117 | version: "1.9.1" 118 | sky_engine: 119 | dependency: transitive 120 | description: flutter 121 | source: sdk 122 | version: "0.0.0" 123 | source_span: 124 | dependency: transitive 125 | description: 126 | name: source_span 127 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "1.10.0" 131 | stack_trace: 132 | dependency: transitive 133 | description: 134 | name: stack_trace 135 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" 136 | url: "https://pub.flutter-io.cn" 137 | source: hosted 138 | version: "1.12.1" 139 | stream_channel: 140 | dependency: transitive 141 | description: 142 | name: stream_channel 143 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" 144 | url: "https://pub.flutter-io.cn" 145 | source: hosted 146 | version: "2.1.4" 147 | string_scanner: 148 | dependency: transitive 149 | description: 150 | name: string_scanner 151 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 152 | url: "https://pub.flutter-io.cn" 153 | source: hosted 154 | version: "1.2.0" 155 | term_glyph: 156 | dependency: transitive 157 | description: 158 | name: term_glyph 159 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 160 | url: "https://pub.flutter-io.cn" 161 | source: hosted 162 | version: "1.2.1" 163 | test_api: 164 | dependency: transitive 165 | description: 166 | name: test_api 167 | sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" 168 | url: "https://pub.flutter-io.cn" 169 | source: hosted 170 | version: "0.7.6" 171 | vector_math: 172 | dependency: transitive 173 | description: 174 | name: vector_math 175 | sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b 176 | url: "https://pub.flutter-io.cn" 177 | source: hosted 178 | version: "2.2.0" 179 | vm_service: 180 | dependency: transitive 181 | description: 182 | name: vm_service 183 | sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" 184 | url: "https://pub.flutter-io.cn" 185 | source: hosted 186 | version: "14.2.1" 187 | sdks: 188 | dart: ">=3.8.0-0 <4.0.0" 189 | flutter: ">=3.18.0-18.0.pre.54" 190 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.4.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.2" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.19.1" 44 | cupertino_icons: 45 | dependency: "direct main" 46 | description: 47 | name: cupertino_icons 48 | sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.0.8" 52 | fake_async: 53 | dependency: transitive 54 | description: 55 | name: fake_async 56 | sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "1.3.3" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_test: 66 | dependency: "direct dev" 67 | description: flutter 68 | source: sdk 69 | version: "0.0.0" 70 | getuiflut: 71 | dependency: "direct dev" 72 | description: 73 | path: ".." 74 | relative: true 75 | source: path 76 | version: "0.2.38" 77 | leak_tracker: 78 | dependency: transitive 79 | description: 80 | name: leak_tracker 81 | sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" 82 | url: "https://pub.flutter-io.cn" 83 | source: hosted 84 | version: "11.0.2" 85 | leak_tracker_flutter_testing: 86 | dependency: transitive 87 | description: 88 | name: leak_tracker_flutter_testing 89 | sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" 90 | url: "https://pub.flutter-io.cn" 91 | source: hosted 92 | version: "3.0.10" 93 | leak_tracker_testing: 94 | dependency: transitive 95 | description: 96 | name: leak_tracker_testing 97 | sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" 98 | url: "https://pub.flutter-io.cn" 99 | source: hosted 100 | version: "3.0.2" 101 | matcher: 102 | dependency: transitive 103 | description: 104 | name: matcher 105 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 106 | url: "https://pub.flutter-io.cn" 107 | source: hosted 108 | version: "0.12.17" 109 | material_color_utilities: 110 | dependency: transitive 111 | description: 112 | name: material_color_utilities 113 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 114 | url: "https://pub.flutter-io.cn" 115 | source: hosted 116 | version: "0.11.1" 117 | meta: 118 | dependency: transitive 119 | description: 120 | name: meta 121 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c 122 | url: "https://pub.flutter-io.cn" 123 | source: hosted 124 | version: "1.16.0" 125 | path: 126 | dependency: transitive 127 | description: 128 | name: path 129 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" 130 | url: "https://pub.flutter-io.cn" 131 | source: hosted 132 | version: "1.9.1" 133 | sky_engine: 134 | dependency: transitive 135 | description: flutter 136 | source: sdk 137 | version: "0.0.0" 138 | source_span: 139 | dependency: transitive 140 | description: 141 | name: source_span 142 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 143 | url: "https://pub.flutter-io.cn" 144 | source: hosted 145 | version: "1.10.0" 146 | stack_trace: 147 | dependency: transitive 148 | description: 149 | name: stack_trace 150 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" 151 | url: "https://pub.flutter-io.cn" 152 | source: hosted 153 | version: "1.12.1" 154 | stream_channel: 155 | dependency: transitive 156 | description: 157 | name: stream_channel 158 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" 159 | url: "https://pub.flutter-io.cn" 160 | source: hosted 161 | version: "2.1.4" 162 | string_scanner: 163 | dependency: transitive 164 | description: 165 | name: string_scanner 166 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 167 | url: "https://pub.flutter-io.cn" 168 | source: hosted 169 | version: "1.2.0" 170 | term_glyph: 171 | dependency: transitive 172 | description: 173 | name: term_glyph 174 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 175 | url: "https://pub.flutter-io.cn" 176 | source: hosted 177 | version: "1.2.1" 178 | test_api: 179 | dependency: transitive 180 | description: 181 | name: test_api 182 | sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" 183 | url: "https://pub.flutter-io.cn" 184 | source: hosted 185 | version: "0.7.6" 186 | vector_math: 187 | dependency: transitive 188 | description: 189 | name: vector_math 190 | sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b 191 | url: "https://pub.flutter-io.cn" 192 | source: hosted 193 | version: "2.2.0" 194 | vm_service: 195 | dependency: transitive 196 | description: 197 | name: vm_service 198 | sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" 199 | url: "https://pub.flutter-io.cn" 200 | source: hosted 201 | version: "14.2.1" 202 | sdks: 203 | dart: ">=3.8.0-0 <4.0.0" 204 | flutter: ">=3.18.0-18.0.pre.54" 205 | -------------------------------------------------------------------------------- /ohos/src/main/ets/components/plugin/GetuiflutPlugin.ets: -------------------------------------------------------------------------------- 1 | import { 2 | FlutterPlugin, 3 | FlutterPluginBinding, 4 | MethodCall, 5 | MethodCallHandler, 6 | MethodChannel, 7 | MethodResult, 8 | FlutterManager 9 | } from '@ohos/flutter_ohos'; 10 | import { BusinessError } from '@ohos.base'; 11 | import notificationManager from '@ohos.notificationManager'; 12 | import hilog from '@ohos.hilog'; 13 | import PushManager, { GTTransmitMessage, GTCmdMessage, Tag, GTNotificationMessage, PushConst } from "@getui/push" 14 | import common from '@ohos.app.ability.common'; 15 | import { ArrayList } from '@kit.ArkTS'; 16 | import Want from '@ohos.app.ability.Want'; 17 | 18 | 19 | let TAG = "ohos_getuiflut" 20 | 21 | /** FlutterHarmonyPlugin **/ 22 | export default class GetuiflutPlugin implements FlutterPlugin, MethodCallHandler { 23 | private channel: MethodChannel | null = null; 24 | private binding: FlutterPluginBinding | null = null; 25 | private context: common.UIAbilityContext | null = null; 26 | 27 | constructor() { 28 | } 29 | 30 | getUniqueClassName(): string { 31 | return "getuiflut" 32 | } 33 | 34 | onAttachedToEngine(binding: FlutterPluginBinding): void { 35 | this.channel = new MethodChannel(binding.getBinaryMessenger(), "getuiflut"); 36 | this.channel.setMethodCallHandler(this) 37 | this.binding = binding 38 | // this.context = binding.getApplicationContext() as common.UIAbilityContext 39 | this.context = FlutterManager.getInstance().getUIAbility()?.context as common.UIAbilityContext 40 | 41 | } 42 | 43 | onDetachedFromEngine(binding: FlutterPluginBinding): void { 44 | if (this.channel != null) { 45 | this.channel.setMethodCallHandler(null) 46 | } 47 | } 48 | 49 | static setClickWant(want: Want) { 50 | PushManager.setClickWant(want) 51 | } 52 | 53 | onMethodCall(call: MethodCall, result: MethodResult): void { 54 | hilog.debug(0x0000, TAG, '%{public}s', "method = " + call.method + " argument = " + JSON.stringify(call.args)); 55 | if (call.method == "getPlatformVersion") { 56 | result.success("OpenHarmony ^ ^ ") 57 | } else if (call.method == "initGetuiPush") { 58 | this.initSDK(); 59 | } else if (call.method == "getClientId") { 60 | result.success(PushManager.getClientId()); 61 | } else if (call.method == "sdkVersion") { 62 | result.success(PushManager.getSDKVersion()); 63 | } else if (call.method == "resume") { 64 | PushManager.turnOnPush() 65 | } else if (call.method == "stopPush") { 66 | PushManager.turnOffPush() 67 | } else if (call.method == "bindAlias") { 68 | hilog.debug(0x0000, TAG, '%{public}s', 69 | "bindAlias:" + call.argument("alias").toString() + call.argument("aSn").toString()); 70 | PushManager.bindAlias(call.argument("alias").toString(), call.argument("aSn").toString()) 71 | } else if (call.method == "unbindAlias") { 72 | hilog.debug(0x0000, TAG, '%{public}s', 73 | "unbindAlias:" + call.argument("alias").toString() + call.argument("aSn").toString() + 74 | call.argument("isSelf").toString()); 75 | PushManager.unBindAlias(call.argument("alias").toString(), call.argument("isSelf").toString() === 'true', 76 | call.argument("aSn").toString()) 77 | } else if (call.method == "setTag") { 78 | let tags = call.argument("tags") as ArrayList 79 | const tagArray: Tag[] = []; 80 | // 将ArrayList中的每个字符串转换为Tag对象 81 | for (let i = 0; i < tags.length; i++) { 82 | const tag = new Tag(); 83 | tag.setName(tags[i].toString()); 84 | tagArray.push(tag); 85 | } 86 | PushManager.setTag(tagArray, call.argument("sn")) 87 | } else if (call.method == "queryTag") { 88 | PushManager.queryTag(TAG) 89 | } else if (call.method == "onActivityCreate") { 90 | result.notImplemented() 91 | } else if (call.method == "setBadge") { 92 | PushManager.setBadgeNum(call.argument("badge")) 93 | } else if (call.method == "runBackgroundEnable") { 94 | //enable 取反 95 | const offline = !call.argument("enable") as boolean 96 | PushManager.setBackgroundOffLine(offline) 97 | } else if (call.method == "setSilentTime") { 98 | PushManager.setSilentTime(call.argument("beginHour"), call.argument("duration")) 99 | } else if (call.method == "sendFeedbackMessage") { 100 | PushManager.sendFeedbackMessage(call.argument("taskId"), call.argument("messageId"), call.argument("actionId")) 101 | } else { 102 | result.notImplemented() 103 | } 104 | } 105 | 106 | initSDK() { 107 | notificationManager.requestEnableNotification().then(() => { 108 | hilog.debug(0x0000, "notify", '%{public}s', 'requestEnableNotification success'); 109 | }).catch((err: BusinessError) => { 110 | hilog.error(0x0000, "notify", '%{public}s', "error = " + err.message); 111 | }) 112 | 113 | PushManager.setPushCallback({ 114 | onReceiveClientId: (clientId: string) => { 115 | hilog.debug(0x0000, TAG, '%{public}s', "clientId = " + clientId); 116 | this.channel?.invokeMethod("onReceiveClientId", clientId); 117 | }, 118 | onReceiveDeviceToken: (token: string) => { 119 | hilog.debug(0x0000, TAG, '%{public}s', "token = " + token); 120 | this.channel?.invokeMethod("onRegisterDeviceToken", token); 121 | }, 122 | onReceiveOnlineState: (onLine: boolean) => { 123 | hilog.debug(0x0000, TAG, '%{public}s', "onLine = " + onLine); 124 | this.channel?.invokeMethod("onReceiveOnlineState", String(onLine)); 125 | }, 126 | onReceiveCommandResult: (result: GTCmdMessage) => { 127 | hilog.debug(0x0000, TAG, '%{public}s', "cmd = " + JSON.stringify(result)); 128 | 129 | if (result.action == PushConst.SET_TAG_RESULT) { 130 | this.channel?.invokeMethod("onSetTagResult", JSON.stringify(result)) 131 | } else if (result.action == PushConst.BIND_ALIAS_RESULT) { 132 | this.channel?.invokeMethod("onAliasResult", JSON.stringify(result)) 133 | } else if (result.action == PushConst.UNBIND_ALIAS_RESULT) { 134 | this.channel?.invokeMethod("onAliasResult", JSON.stringify(result)) 135 | } else if ((result.action == PushConst.THIRDPART_FEEDBACK)) { 136 | this.channel?.invokeMethod("thirdPartFeedback", JSON.stringify(result)) 137 | } else if (result.action == PushConst.QUERY_TAG_RESULT) { 138 | this.channel?.invokeMethod("onQueryTagResult", JSON.stringify(result)) 139 | } 140 | }, 141 | onReceiveMessageData: (message: GTTransmitMessage) => { 142 | hilog.debug(0x0000, TAG, '%{public}s', "message = " + JSON.stringify(message)); 143 | this.channel?.invokeMethod("onReceivePayload", JSON.stringify(message)); 144 | }, 145 | onNotificationMessageArrived: (message: GTNotificationMessage) => { 146 | hilog.debug(0x0000, TAG, '%{public}s', "MessageArrived = " + JSON.stringify(message)); 147 | this.channel?.invokeMethod("onNotificationMessageArrived", JSON.stringify(message)); 148 | }, 149 | onNotificationMessageClicked: (message: GTNotificationMessage) => { 150 | hilog.debug(0x0000, TAG, '%{public}s', "MessageClicked = " + JSON.stringify(message)); 151 | this.channel?.invokeMethod("onNotificationMessageClicked", JSON.stringify(message)); 152 | } 153 | }) 154 | 155 | 156 | if (undefined == this.context) { 157 | this.context = this.binding?.getApplicationContext() as common.UIAbilityContext 158 | } 159 | PushManager.initialize({ 160 | context: this.context, 161 | onSuccess: (cid: string) => { 162 | hilog.debug(0x0000, TAG, '%{public}s', "cid = " + cid); 163 | hilog.info(0x0000, TAG, '%{public}s', "cid = " + cid); 164 | }, 165 | onFailed: (error: string) => { 166 | hilog.debug(0x0000, TAG, '%{public}s', "error = " + error); 167 | } 168 | }) 169 | } 170 | } 171 | 172 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getui Flutter Plugin 集成与使用指南 2 | 3 | ## 1. 引入插件 4 | 5 | 在 `pubspec.yaml` 中添加以下依赖: 6 | 7 | ```markdown 8 | dependencies: 9 | getuiflut: ^0.2.39 10 | ``` 11 | 12 | 13 | 执行以下命令下载依赖并运行项目: 14 | 15 | ```shell 16 | flutter pub get 17 | flutter run 18 | ``` 19 | 20 | 或者直接通过命令行添加: 21 | ```shell 22 | flutter pub add getuiflut 23 | ``` 24 | 25 | ## 2. 配置 26 | 27 | ### 2.1 Android 配置 28 | 参考[个推官网文档](https://docs.getui.com/getui/mobile/android/overview/)进行配置。 29 | 核心PushService、GTIntentService已经内置在flutter插件中 30 | 31 | #### 配置 Maven 库地址 32 | 在项目根目录 `build.gradle` 文件中添加: 33 | ```yaml 34 | allprojects { 35 | repositories { 36 | mavenCentral() 37 | google() 38 | maven { 39 | url "https://mvn.getui.com/nexus/content/repositories/releases/" 40 | } 41 | } 42 | } 43 | ``` 44 | 45 | #### 添加依赖 46 | 在 `android/app/build.gradle` 文件中配置: 47 | ```yaml 48 | android { 49 | defaultConfig { 50 | manifestPlaceholders = [ 51 | GETUI_APPID: "your appid" 52 | ] 53 | } 54 | } 55 | 56 | dependencies { 57 | //在官网查阅最新版本(https://docs.getui.com/getui/mobile/android/overview/) 58 | implementation 'com.getui:gtsdk:3.3.12.0' // 个推 SDK 59 | implementation 'com.getui:gtc:3.2.18.0' // 个推核心组件 60 | } 61 | ``` 62 | 63 | ### 2.2 iOS 配置 64 | 在 `main.dart` 中添加以下代码以启动 SDK: 65 | ```dart 66 | Getuiflut().startSdk( 67 | appId: "8eLAkGIYnGAwA9fVYZU93A", 68 | appKey: "VFX8xYxvVF6w59tsvY6XN", 69 | appSecret: "Kv3TeED8z19QwnMLdzdI35" 70 | ); 71 | ``` 72 | 73 | #### 启用通知 74 | 在 Xcode 中,进入 `Signing & Capabilities`,添加 `Push Notifications`。 75 | 76 | #### Notification Service Extension 77 | 为精确统计消息送达率,可添加 `Notification Service Extension`,并在 Extensions 中调用 `GTExtensionSDK` 的统计接口。具体参考[个推 iOS 集成文档](https://docs.getui.com/getui/mobile/ios/xcode/)。 78 | 79 | ### 2.3 HarmonyOS 配置 80 | * 引入插件, 见上文 81 | * 使用鸿蒙定制版 Flutter,否则报错依赖缺失, 下载地址: [OpenHarmony Flutter](https://gitcode.com/openharmony-tpc/flutter_flutter) 及 [使用教程](https://developer.huawei.com/consumer/cn/blog/topic/03178381351651116)。 82 | * [启动应用教程](https://gitcode.com/openharmony-tpc/flutter_flutter#%E6%9E%84%E5%BB%BA%E6%AD%A5%E9%AA%A4) 83 | 84 | #### 2.3.1 配置 `build-profile.json5` 85 | ohos工程需要兼容字节码包,在项目级build-profile.json5: 86 | ```yaml 87 | "buildOption": { 88 | "strictMode": { 89 | "useNormalizedOHMUrl": true 90 | } 91 | } 92 | ``` 93 | 94 | #### 2.3.2 配置 `module.json5` 95 | 在项目中配置: 96 | ```yaml 97 | "requestPermissions": [ 98 | {"name": "ohos.permission.INTERNET"}, 99 | {"name": "ohos.permission.GET_NETWORK_INFO"}, 100 | {"name": "ohos.permission.KEEP_BACKGROUND_RUNNING"}, 101 | { 102 | "name": "ohos.permission.APP_TRACKING_CONSENT", 103 | "reason": "$string:tracking_reason", 104 | "usedScene": { 105 | "abilities": ["EntryAbility"] 106 | } 107 | } 108 | ], 109 | "metadata": [ 110 | {"name": "GETUI_APPID", "value": "djYjSlFVMf6p5YOy2OQUs8"},//你的appid 111 | {"name": "ZX_CHANNELID_GT", "value": "C01-GEztJH0JLdBC"}, 112 | {"name": "client_id", "value": "109599703"},//厂商appid,开通在官网找技术支持协助 113 | {"name": "GT_PUSH_LOG", "value": "false"} //sdk文件日志开关, 技术支持问题排查时使用 114 | ] 115 | ``` 116 | #### 2.3.3 注册插件 117 | 运行 fvm flutter build hap 后自动生成 GeneratedPluginRegistrant 118 | 119 | 120 | #### 2.3.4 配置在线通知点击事件 121 | * 通过个推在线渠道展示的通知类消息,待通知点击打开目的页面后,由客户必须调用PushManager.setClickWant(want)完善报表和完成后续业务,以免影响消息业务使用(重要) 122 | * 通知点击打开应用页面(目的页面由下发通知时决定) 123 | * 通知点击打开浏览器 124 | * 配置参考demo代码: [EntryAbility.ets](example/ohos/entry/src/main/ets/entryability/EntryAbility.ets) 125 | 126 | 127 | 128 | #### 2.3.5 其他API功能 129 | 参考: [官网文档](https://docs.getui.com/getui/mobile/harmonyos/vendor/vendor_open/) 130 | 131 | 132 | 133 | ## 3. 使用方法 134 | 135 | ### 3.1 公共 API 136 | 导入插件: 137 | ```dart 138 | import 'package:getuiflut/getuiflut.dart'; 139 | ``` 140 | 141 | #### 初始化 SDK (Android/ohos) 142 | ```dart 143 | Getuiflut().initGetuiSdk; 144 | ``` 145 | 146 | #### 设置角标 147 | ```dart 148 | setBadge(badge); 149 | ``` 150 | 151 | #### 绑定/解绑别名 152 | ```dart 153 | bindAlias(alias, sn); 154 | unbindAlias(alias, sn); 155 | ``` 156 | * sn: 绑定序列码,不为nil 157 | 158 | 159 | #### 设置/查询标签 160 | ```dart 161 | setTag(tags,sn); 162 | queryTag(sn) 163 | ``` 164 | * sn: 绑定序列码,不为nil 165 | 166 | #### 开启/关闭推送服务(iOS 不支持) 167 | ```dart 168 | turnOnPush(); 169 | turnOffPush(); 170 | ``` 171 | 172 | #### 获取版本和 CID 173 | ```dart 174 | getClientId(); 175 | ``` 176 | 177 | #### 设置静默时间(IOS不支持) 178 | ```dart 179 | setSilentTime(beginHour,duration) 180 | ``` 181 | * 开始时间,beginHour >= 0 && beginHour < 24,单位 h 182 | * duration:持续时间,duration > 0 && duration <= 23,持续时间为 0 则取消静默,单位 h 183 | 184 | 185 | #### 自定义回执 186 | ```dart 187 | sendFeedbackMessage( taskId, messageId, actionId) 188 | ``` 189 | * actionId:自定义的actionId,取值范围是 90001-90999 190 | 191 | #### 回调方法 192 | 设置事件监听: 193 | ```dart 194 | Getuiflut().addEventHandler( 195 | onReceiveClientId: (String message) async { 196 | print("flutter onReceiveClientId: $message"); 197 | }, onReceiveOnlineState: (String online) async { 198 | print("flutter onReceiveOnlineState: $online"); 199 | },onReceivePayload: (Map message) async { 200 | print("flutter onReceivePayload: $message"); 201 | },onSetTagResult: (Map message) async { 202 | print("flutter onSetTagResult: $message"); 203 | }, onAliasResult: (Map message) async { 204 | print("flutter onAliasResult: $message"); 205 | }, onQueryTagResult: (Map message) async { 206 | print("flutter onQueryTagResult: $message"); 207 | },onRegisterDeviceToken: (String message) async { 208 | print("flutter onRegisterDeviceToken: $message"); 209 | }, 210 | //Android 、ohos 特有 211 | onNotificationMessageArrived: (Map msg) async { 212 | print("flutter onNotificationMessageArrived: $msg"); 213 | }, onNotificationMessageClicked: (Map msg) async { 214 | print("flutter onNotificationMessageClicked: $msg"); 215 | }, 216 | //以下IOS特有 217 | onTransmitUserMessageReceive: (Map msg) async { 218 | print("flutter onTransmitUserMessageReceive:$msg"); 219 | },onReceiveNotificationResponse: (Map message) async { 220 | print("flutter onReceiveNotificationResponse: $message"); 221 | }, onAppLinkPayload: (String message) async { 222 | print("flutter onAppLinkPayload: $message"); 223 | }, onPushModeResult: (Map message) async { 224 | print("flutter onPushModeResult: $message"); 225 | }, onWillPresentNotification: (Map message) async { 226 | print("flutter onWillPresentNotification: $message"); 227 | }, onOpenSettingsForNotification: (Map message) async { 228 | print("flutter onOpenSettingsForNotification: $message"); 229 | }, onGrantAuthorization: (String granted) async { 230 | print("flutter onGrantAuthorization: $granted"); 231 | }, onLiveActivityResult: (Map message) async { 232 | print("flutter onLiveActivityResult: $message"); 233 | }, onRegisterPushToStartTokenResult: (Map message) async { 234 | print("flutter onRegisterPushToStartTokenResult: $message"); 235 | }); 236 | ``` 237 | 238 | ### 3.2 iOS 专用 API 239 | #### 启动 SDK 并请求通知权限 240 | ```dart 241 | startSdk(appId, appKey, appSecret); 242 | ``` 243 | 244 | #### 仅启动 SDK 245 | ```dart 246 | startSdkSimple(appId, appKey, appSecret); 247 | ``` 248 | 249 | #### 注册远程通知 250 | ```dart 251 | registerRemoteNotification(appId, appKey, appSecret); 252 | ``` 253 | 254 | #### 获取启动参数 255 | ```dart 256 | getLaunchOptions(); 257 | getLaunchNotification(); 258 | ``` 259 | 260 | #### 管理角标 261 | ```dart 262 | setBadge(badge); 263 | resetBadge(); 264 | setLocalBadge(badge); 265 | ``` 266 | 267 | #### 后台模式 268 | ```dart 269 | runBackgroundEnable(enable); 270 | ``` 271 | 272 | #### 灵动岛支持(GTSDK ≥ 2.7.3.0) 273 | ```dart 274 | registerActivityToken(aid, token, sn); 275 | registerPushToStartToken(attribute, token, sn); 276 | ``` 277 | 278 | 279 | 280 | #### AppDelegate 配置 281 | 282 | 在 `AppDelegate.m` 中重写以下方法以确保 SDK 正常工作: 283 | ```objc 284 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { 285 | // 保持空实现 286 | } 287 | ``` 288 | 289 | **版本兼容性**: 290 | - GTSDK ≤ 2.4.6.0:使用插件版本 ≤ 0.2.5 291 | - GTSDK > 2.4.6.0:使用最新插件版本 292 | ``` 293 | 294 | **说明**:如需更多细节,可参考[个推官方文档](https://docs.getui.com),联系技术支持。 295 | ``` 296 | 297 | 298 | 299 | 300 | 301 | #### UIScene 配置 302 | 303 | 在 `SceneDelegate.m` 中需要将启动参数传递给flutter插件,[GetuiflutPlugin handleSceneWillConnectWithOptions:connectionOptions]; 304 | 305 | ``` 306 | #import "SceneDelegate.h" 307 | #import 308 | #import "GeneratedPluginRegistrant.h" 309 | #import 310 | #import "GetuiflutPlugin.h" 311 | 312 | @interface SceneDelegate () 313 | 314 | @end 315 | 316 | @implementation SceneDelegate 317 | 318 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { 319 | // 配置窗口场景 320 | if (@available(iOS 13.0, *)) { 321 | UIWindowScene *windowScene = (UIWindowScene *)scene; 322 | self.window = [[UIWindow alloc] initWithWindowScene:windowScene]; 323 | } else { 324 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 325 | } 326 | 327 | // 创建并设置 Flutter 视图控制器 328 | FlutterViewController *flutterViewController = [FlutterViewController new]; 329 | self.window.rootViewController = flutterViewController; 330 | 331 | // 注册 Flutter 插件 332 | [GeneratedPluginRegistrant registerWithRegistry:flutterViewController]; 333 | 334 | 335 | 336 | //TODO:用于获取UIScene模式下的通知数据 337 | [GetuiflutPlugin handleSceneWillConnectWithOptions:connectionOptions]; 338 | 339 | 340 | // 使窗口可见 341 | [self.window makeKeyAndVisible]; 342 | } 343 | ``` 344 | 345 | -------------------------------------------------------------------------------- /android/src/main/java/com/getui/getuiflut/GetuiflutPlugin.java: -------------------------------------------------------------------------------- 1 | package com.getui.getuiflut; 2 | 3 | import android.content.Context; 4 | import android.os.Handler; 5 | import android.os.Looper; 6 | import android.os.Message; 7 | import android.util.Log; 8 | 9 | import com.google.gson.Gson; 10 | import com.igexin.sdk.PushManager; 11 | import com.igexin.sdk.Tag; 12 | 13 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 14 | import io.flutter.plugin.common.MethodCall; 15 | import io.flutter.plugin.common.MethodChannel; 16 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 17 | import io.flutter.plugin.common.MethodChannel.Result; 18 | 19 | import java.lang.reflect.Method; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import java.util.Map; 23 | 24 | /** 25 | * Flutter 插件类,用于与个推推送服务交互 26 | */ 27 | public class GetuiflutPlugin implements FlutterPlugin, MethodCallHandler { 28 | private static final String TAG = "GetuiflutPlugin"; 29 | private static final String CHANNEL_NAME = "getuiflut"; 30 | private static final int FLUTTER_CALL_BACK = 1; 31 | private static final int FLUTTER_CALL_BACK_USER = 2; 32 | 33 | /** 34 | * 状态类型枚举 35 | */ 36 | enum StateType { 37 | Default, 38 | onReceiveClientId, 39 | onReceiveOnlineState, 40 | onReceivePayload, 41 | onNotificationMessageArrived, 42 | onNotificationMessageClicked, 43 | onSetTagResult, 44 | onAliasResult, 45 | onQueryTagResult, 46 | thirdPartFeedback 47 | } 48 | 49 | private MethodChannel channel; 50 | private Context context; 51 | public static GetuiflutPlugin instance; 52 | 53 | public GetuiflutPlugin() { 54 | Log.d(TAG, "Plugin initialized"); 55 | } 56 | 57 | @Override 58 | public void onAttachedToEngine(FlutterPluginBinding binding) { 59 | context = binding.getApplicationContext(); 60 | channel = new MethodChannel(binding.getBinaryMessenger(), CHANNEL_NAME); 61 | channel.setMethodCallHandler(this); 62 | 63 | Log.d(TAG, "Attached to Flutter engine"); 64 | } 65 | 66 | @Override 67 | public void onDetachedFromEngine(FlutterPluginBinding binding) { 68 | channel.setMethodCallHandler(null); 69 | Log.d(TAG, "Detached from Flutter engine"); 70 | } 71 | 72 | /** 73 | * 处理 Flutter 端调用 74 | */ 75 | @Override 76 | public void onMethodCall(MethodCall call, Result result) { 77 | Log.d(TAG, "Method call: " + call.method + ", arguments: " + (call.arguments == null ? "none" : call.arguments)); 78 | switch (call.method) { 79 | case "getPlatformVersion": 80 | result.success("Android " + android.os.Build.VERSION.RELEASE); 81 | break; 82 | case "initGetuiPush": 83 | initGtSdk(); 84 | result.success(null); 85 | break; 86 | case "getClientId": 87 | result.success(getClientId()); 88 | break; 89 | case "resume": 90 | resume(); 91 | result.success(null); 92 | break; 93 | case "stopPush": 94 | stopPush(); 95 | result.success(null); 96 | break; 97 | case "bindAlias": 98 | bindAlias(call.argument("alias"), call.argument("aSn")); 99 | result.success(null); 100 | break; 101 | case "unbindAlias": 102 | unbindAlias(call.argument("alias"), call.argument("aSn"), Boolean.TRUE.equals(call.argument("isSelf"))); 103 | result.success(null); 104 | break; 105 | case "setTag": 106 | setTag(call.argument("tags"), call.argument("sn")); 107 | result.success(null); 108 | break; 109 | case "queryTag": 110 | PushManager.getInstance().queryTag(context, call.argument("sn")); 111 | result.success(null); 112 | break; 113 | case "onActivityCreate": 114 | onActivityCreate(); 115 | result.success(null); 116 | break; 117 | case "setBadge": 118 | setBadge(call.argument("badge")); 119 | result.success(null); 120 | break; 121 | case "registerDeviceToken": 122 | PushManager.getInstance().setDeviceToken(context, call.argument("token")); 123 | result.success(null); 124 | break; 125 | case "setSilentTime": 126 | PushManager.getInstance().setSilentTime(context, call.argument("beginHour"), call.argument("duration")); 127 | result.success(null); 128 | break; 129 | case "sendFeedbackMessage": 130 | PushManager.getInstance().sendFeedbackMessage(context, call.argument("taskId"), call.argument("messageId"), call.argument("actionId")); 131 | result.success(null); 132 | break; 133 | default: 134 | result.notImplemented(); 135 | break; 136 | } 137 | } 138 | 139 | /** 140 | * 初始化个推 SDK 141 | */ 142 | private void initGtSdk() { 143 | instance = this; 144 | try { 145 | Log.d(TAG, "Initializing Getui SDK "+PushManager.getInstance().getVersion(context)); 146 | } catch (Throwable e) { 147 | 148 | } 149 | try { 150 | PushManager.getInstance().initialize(context); 151 | } catch (Throwable e) { 152 | Log.e(TAG, "Initialization failed, setting privacy policy", e); 153 | try { 154 | Method setPrivacyPolicyStrategy = PushManager.class.getDeclaredMethod("setPrivacyPolicyStrategy", Context.class, boolean.class); 155 | setPrivacyPolicyStrategy.invoke(PushManager.getInstance(), context, true); 156 | } catch (Throwable ex) { 157 | throw new RuntimeException("Failed to set privacy policy", ex); 158 | } 159 | PushManager.getInstance().registerPushIntentService(context, FlutterIntentService.class); 160 | PushManager.getInstance().initialize(context, FlutterPushService.class); 161 | } 162 | } 163 | 164 | /** 165 | * 注册推送 Activity 166 | */ 167 | private void onActivityCreate() { 168 | try { 169 | Method method = PushManager.class.getDeclaredMethod("registerPushActivity", Context.class, Class.class); 170 | method.setAccessible(true); 171 | method.invoke(PushManager.getInstance(), context, GetuiPluginActivity.class); 172 | Log.d(TAG, "Push activity registered"); 173 | } catch (Throwable e) { 174 | Log.e(TAG, "Failed to register push activity", e); 175 | } 176 | } 177 | 178 | /** 179 | * 设置应用角标 180 | */ 181 | private void setBadge(int badgeNum) { 182 | try { 183 | Method method = PushManager.class.getDeclaredMethod("setBadgeNum", Context.class, int.class); 184 | method.setAccessible(true); 185 | method.invoke(PushManager.getInstance(), context, badgeNum); 186 | Log.d(TAG, "Badge set to: " + badgeNum); 187 | } catch (Throwable e) { 188 | Log.e(TAG, "Failed to set badge", e); 189 | } 190 | } 191 | 192 | /** 193 | * 获取客户端 ID 194 | */ 195 | private String getClientId() { 196 | String clientId = PushManager.getInstance().getClientid(context); 197 | Log.d(TAG, "Client ID: " + clientId); 198 | return clientId; 199 | } 200 | 201 | /** 202 | * 恢复推送服务 203 | */ 204 | private void resume() { 205 | PushManager.getInstance().turnOnPush(context); 206 | Log.d(TAG, "Push service resumed"); 207 | } 208 | 209 | /** 210 | * 停止推送服务 211 | */ 212 | private void stopPush() { 213 | PushManager.getInstance().turnOffPush(context); 214 | Log.d(TAG, "Push service stopped"); 215 | } 216 | 217 | /** 218 | * 绑定别名 219 | */ 220 | private void bindAlias(String alias, String sn) { 221 | PushManager.getInstance().bindAlias(context, alias,sn); 222 | Log.d(TAG, "Binding alias: " + alias + ", sn: " + sn); 223 | } 224 | 225 | /** 226 | * 解绑别名 227 | */ 228 | private void unbindAlias(String alias, String sn, boolean isSelf) { 229 | PushManager.getInstance().unBindAlias(context, alias, isSelf, sn); 230 | Log.d(TAG, "Unbinding alias: " + alias + ", sn: " + sn + ", isSelf: " + isSelf); 231 | } 232 | 233 | /** 234 | * 设置标签 235 | */ 236 | private void setTag(List tags, String sn) { 237 | if (tags == null || tags.isEmpty()) { 238 | Log.d(TAG, "No tags provided"); 239 | return; 240 | } 241 | 242 | Tag[] tagArray = new Tag[tags.size()]; 243 | for (int i = 0; i < tags.size(); i++) { 244 | Tag tag = new Tag(); 245 | tag.setName(tags.get(i)); 246 | tagArray[i] = tag; 247 | } 248 | PushManager.getInstance().setTag(context, tagArray, sn); 249 | Log.d(TAG, "Tags set: " + tags + ", sn: " + sn); 250 | } 251 | 252 | /** 253 | * 处理消息回调的 Handler 254 | */ 255 | private static final Handler flutterHandler = new Handler(Looper.getMainLooper()) { 256 | @Override 257 | public void handleMessage(Message msg) { 258 | switch (msg.what) { 259 | case FLUTTER_CALL_BACK: 260 | StateType type = StateType.values()[msg.arg1]; 261 | instance.channel.invokeMethod(type.name(), msg.obj); 262 | Log.d(TAG, type.name() + ": " + msg.obj); 263 | break; 264 | case FLUTTER_CALL_BACK_USER: 265 | instance.channel.invokeMethod("onTransmitUserMessageReceive", msg.obj); 266 | Log.d(TAG, "User message: " + msg.obj); 267 | break; 268 | default: 269 | Log.d(TAG, "Unknown message type: " + msg.what); 270 | break; 271 | } 272 | } 273 | }; 274 | 275 | /** 276 | * 传输消息到 Flutter 277 | */ 278 | static void transmitMessageReceive(String message, StateType type) { 279 | if (instance == null) { 280 | Log.d(TAG, "Plugin instance is null"); 281 | return; 282 | } 283 | Message msg = Message.obtain(); 284 | msg.what = FLUTTER_CALL_BACK; 285 | msg.arg1 = type.ordinal(); 286 | msg.obj = message; 287 | flutterHandler.sendMessage(msg); 288 | } 289 | 290 | /** 291 | * 传输用户消息到 Flutter 292 | */ 293 | public static void transmitUserMessage(Map message) { 294 | if (instance == null) { 295 | Log.d(TAG, "Plugin instance is null"); 296 | return; 297 | } 298 | Message msg = Message.obtain(); 299 | msg.what = FLUTTER_CALL_BACK_USER; 300 | msg.obj = new Gson().toJson(message); 301 | flutterHandler.sendMessage(msg); 302 | } 303 | } -------------------------------------------------------------------------------- /lib/getuiflut.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:io'; 3 | import 'package:flutter/services.dart'; 4 | import 'dart:convert'; 5 | 6 | // 事件回调类型定义 7 | typedef Future EventHandler(String res); 8 | typedef Future EventHandlerBool(bool res); 9 | typedef Future EventHandlerMap(Map event); 10 | 11 | class Getuiflut { 12 | static const MethodChannel _channel = const MethodChannel('getuiflut'); 13 | 14 | 15 | /*----------------------------- 16 | * 事件处理器 17 | *----------------------------*/ 18 | late EventHandler _onReceiveClientId; 19 | late EventHandler _onRegisterDeviceToken; 20 | late EventHandler _onAppLinkPayload; 21 | late EventHandler _onGrantAuthorization; 22 | late EventHandler _onReceiveOnlineState; 23 | 24 | late EventHandlerMap _onNotificationMessageArrived; 25 | late EventHandlerMap _onNotificationMessageClicked; 26 | late EventHandlerMap _onTransmitUserMessageReceive; 27 | late EventHandlerMap _onSetTagResult; 28 | late EventHandlerMap _onAliasResult; 29 | late EventHandlerMap _onQueryTagResult; 30 | late EventHandlerMap _onReceivePayload; 31 | late EventHandlerMap _onReceiveNotificationResponse; 32 | late EventHandlerMap _onPushModeResult; 33 | late EventHandlerMap _onWillPresentNotification; 34 | late EventHandlerMap _onOpenSettingsForNotification; 35 | late EventHandlerMap _onLiveActivityResult; 36 | late EventHandlerMap _onRegisterPushToStartTokenResult; 37 | 38 | /*----------------------------- 39 | * SDK基础方法 40 | *----------------------------*/ 41 | 42 | /// 获取平台版本 43 | Future get platformVersion async { 44 | final String version = await _channel.invokeMethod('getPlatformVersion'); 45 | print(version); 46 | return version; 47 | } 48 | 49 | /// 初始化SDK(Android/ohos) 50 | void get initGetuiSdk { 51 | _channel.invokeMethod('initGetuiPush'); 52 | } 53 | 54 | /// 启动SDK(iOS标准模式) 55 | void startSdk({ 56 | required String appId, 57 | required String appKey, 58 | required String appSecret, 59 | }) { 60 | _channel.invokeMethod( 61 | 'startSdk', 62 | {'appId': appId, 'appKey': appKey, 'appSecret': appSecret}, 63 | ); 64 | } 65 | 66 | /// 启动SDK(iOS简单模式) 67 | void startSdkSimple({ 68 | required String appId, 69 | required String appKey, 70 | required String appSecret, 71 | }) { 72 | if (Platform.isIOS) { 73 | _channel.invokeMethod( 74 | 'startSdkSimple', 75 | {'appId': appId, 'appKey': appKey, 'appSecret': appSecret}, 76 | ); 77 | } 78 | } 79 | 80 | /*----------------------------- 81 | * 客户端信息获取 82 | *----------------------------*/ 83 | 84 | /// 获取个推ClientId 85 | Future get getClientId async { 86 | return await _channel.invokeMethod('getClientId'); 87 | } 88 | 89 | /// 获取SDK版本号 90 | Future get sdkVersion async { 91 | return await _channel.invokeMethod('sdkVersion'); 92 | } 93 | Future get getLaunchNotification async { 94 | Map info = await _channel.invokeMethod('getLaunchNotification'); 95 | return info; 96 | } 97 | 98 | Future get getLaunchLocalNotification async { 99 | Map info = await _channel.invokeMethod('getLaunchLocalNotification'); 100 | return info; 101 | } 102 | 103 | 104 | /*----------------------------- 105 | * 推送控制方法 106 | *----------------------------*/ 107 | 108 | /// 开启推送 109 | void turnOnPush() { 110 | if (!Platform.isIOS) { 111 | _channel.invokeMethod('resume'); 112 | } 113 | } 114 | 115 | /// 关闭推送 116 | void turnOffPush() { 117 | if (!Platform.isIOS) { 118 | _channel.invokeMethod('stopPush'); 119 | } 120 | } 121 | 122 | /// Android 注册Activity 123 | void onActivityCreate() { 124 | if (Platform.isAndroid) { 125 | _channel.invokeMethod('onActivityCreate'); 126 | } 127 | } 128 | 129 | /*----------------------------- 130 | * 别名标签管理 131 | *----------------------------*/ 132 | 133 | /// 绑定别名 134 | void bindAlias(String alias, String sn) { 135 | _channel.invokeMethod('bindAlias', {'alias': alias, 'aSn': sn}); 136 | } 137 | 138 | /// 解绑别名 139 | void unbindAlias(String alias, String sn, bool isSelf) { 140 | _channel.invokeMethod( 141 | 'unbindAlias', {'alias': alias, 'aSn': sn, 'isSelf': isSelf}); 142 | } 143 | 144 | /// 设置标签 145 | void setTag(List tags, String sn) { 146 | _channel.invokeMethod('setTag', {'tags': tags,'sn':sn}); 147 | } 148 | 149 | //查询标签 150 | void queryTag(String sn) { 151 | _channel.invokeMethod('queryTag', {'sn':sn}); 152 | } 153 | 154 | ///设置后台运行 155 | void runBackgroundEnable(int enable) { 156 | if (Platform.isAndroid) { 157 | } else { 158 | _channel.invokeMethod( 159 | 'runBackgroundEnable', {'enable': enable}); 160 | } 161 | } 162 | 163 | /// 设置角标 164 | void setBadge(int badge) { 165 | _channel.invokeMethod('setBadge', {'badge': badge}); 166 | } 167 | //设置静默时间 168 | void setSilentTime(int beginHour, int duration) { 169 | _channel.invokeMethod('setSilentTime', {'beginHour': beginHour, "duration": duration}); 170 | } 171 | //自定义action 172 | void sendFeedbackMessage(String taskId, String messageId, int actionId) { 173 | _channel.invokeMethod('sendFeedbackMessage', {'taskId': taskId , "messageId":messageId, "actionId":actionId}); 174 | } 175 | 176 | 177 | /*----------------------------- 178 | * iOS专属功能 179 | *----------------------------*/ 180 | 181 | /// 设置推送模式(iOS) 182 | void setPushMode(int mode) { 183 | if (Platform.isIOS) { 184 | _channel.invokeMethod('setPushMode', {'mode': mode}); 185 | } 186 | } 187 | 188 | /// 重置角标(iOS) 189 | void resetBadge() { 190 | if (Platform.isIOS) { 191 | _channel.invokeMethod('resetBadge'); 192 | } 193 | } 194 | 195 | /// 设置本地角标(iOS) 196 | void setLocalBadge(int badge) { 197 | if (Platform.isIOS) { 198 | _channel.invokeMethod('setLocalBadge', {'badge': badge}); 199 | } 200 | } 201 | 202 | /*----------------------------- 203 | * 设备Token管理 204 | *----------------------------*/ 205 | 206 | /// 注册ActivityToken(iOS灵动岛) 207 | void registerActivityToken(String aid, String token, String sn) { 208 | _channel.invokeMethod( 209 | 'registerActivityToken', {'aid': aid, 'token': token, 'sn': sn}); 210 | } 211 | 212 | /// 注册PushToStartToken(iOS) 213 | void registerPushToStartToken(String attribute, String token, String sn) { 214 | _channel.invokeMethod('registerPushToStartToken', 215 | {'attribute': attribute, 'token': token, 'sn': sn}); 216 | } 217 | 218 | /// 注册DeviceToken(iOS/Android) 219 | void registerDeviceToken(String token) { 220 | _channel.invokeMethod('registerDeviceToken', {'token': token}); 221 | } 222 | 223 | /// 注册远程通知(iOS) 224 | void registerRemoteNotification() { 225 | if (Platform.isIOS) { 226 | _channel.invokeMethod('registerRemoteNotification'); 227 | } 228 | } 229 | 230 | /*----------------------------- 231 | * 事件处理器配置 232 | *----------------------------*/ 233 | void addEventHandler({ 234 | required EventHandler onReceiveClientId, 235 | required EventHandlerMap onNotificationMessageArrived, 236 | required EventHandlerMap onNotificationMessageClicked, 237 | required EventHandlerMap onTransmitUserMessageReceive, 238 | required EventHandler onReceiveOnlineState, 239 | required EventHandler onRegisterDeviceToken, 240 | required EventHandlerMap onReceivePayload, 241 | required EventHandlerMap onReceiveNotificationResponse, 242 | required EventHandler onAppLinkPayload, 243 | required EventHandlerMap onPushModeResult, 244 | required EventHandlerMap onSetTagResult, 245 | required EventHandlerMap onAliasResult, 246 | required EventHandlerMap onQueryTagResult, 247 | required EventHandlerMap onWillPresentNotification, 248 | required EventHandlerMap onOpenSettingsForNotification, 249 | required EventHandler onGrantAuthorization, 250 | required EventHandlerMap onLiveActivityResult, 251 | required EventHandlerMap onRegisterPushToStartTokenResult, 252 | }) { 253 | // 初始化所有事件处理器 254 | _onReceiveClientId = onReceiveClientId; 255 | _onRegisterDeviceToken = onRegisterDeviceToken; 256 | _onNotificationMessageArrived = onNotificationMessageArrived; 257 | _onNotificationMessageClicked = onNotificationMessageClicked; 258 | _onReceivePayload = onReceivePayload; 259 | _onReceiveNotificationResponse = onReceiveNotificationResponse; 260 | _onAppLinkPayload = onAppLinkPayload; 261 | _onPushModeResult = onPushModeResult; 262 | _onSetTagResult = onSetTagResult; 263 | _onAliasResult = onAliasResult; 264 | _onQueryTagResult = onQueryTagResult; 265 | _onWillPresentNotification = onWillPresentNotification; 266 | _onOpenSettingsForNotification = onOpenSettingsForNotification; 267 | _onTransmitUserMessageReceive = onTransmitUserMessageReceive; 268 | _onGrantAuthorization = onGrantAuthorization; 269 | _onLiveActivityResult = onLiveActivityResult; 270 | _onRegisterPushToStartTokenResult = onRegisterPushToStartTokenResult; 271 | _onReceiveOnlineState = onReceiveOnlineState; 272 | 273 | // 设置方法调用处理器 274 | _channel.setMethodCallHandler(_handleMethod); 275 | } 276 | 277 | /*----------------------------- 278 | * 内部处理方法 279 | *----------------------------*/ 280 | Future _handleMethod(MethodCall call) async { 281 | print('_handleMethod method:' + call.method); 282 | print('_handleMethod args :' + call.arguments.toString()); 283 | switch (call.method) { 284 | case "onReceiveClientId": 285 | return _onReceiveClientId(call.arguments); 286 | case "onRegisterDeviceToken": 287 | return _onRegisterDeviceToken(call.arguments); 288 | case "onNotificationMessageArrived": 289 | dynamic result; 290 | if (call.arguments is String) { 291 | result = jsonDecode(call.arguments) as Map; 292 | } else { 293 | result = call.arguments.cast(); 294 | } 295 | return _onNotificationMessageArrived(result); 296 | case "onNotificationMessageClicked": 297 | dynamic result; 298 | if (call.arguments is String) { 299 | result = jsonDecode(call.arguments) as Map; 300 | } else { 301 | result = call.arguments.cast(); 302 | } 303 | return _onNotificationMessageClicked(result); 304 | case "onReceivePayload": 305 | dynamic result; 306 | if (call.arguments is String) { 307 | result = jsonDecode(call.arguments) as Map; 308 | } else { 309 | result = call.arguments.cast(); 310 | } 311 | return _onReceivePayload(result); 312 | case "onSetTagResult": 313 | dynamic result; 314 | if (call.arguments is String) { 315 | result = jsonDecode(call.arguments) as Map; 316 | } else { 317 | result = call.arguments.cast(); 318 | } 319 | return _onSetTagResult(result); 320 | case "onAliasResult": 321 | dynamic result; 322 | if (call.arguments is String) { 323 | result = jsonDecode(call.arguments) as Map; 324 | } else { 325 | result = call.arguments.cast(); 326 | } 327 | return _onAliasResult(result); 328 | case "onQueryTagResult": 329 | dynamic result; 330 | if (call.arguments is String) { 331 | result = jsonDecode(call.arguments) as Map; 332 | } else { 333 | result = call.arguments.cast(); 334 | } 335 | return _onQueryTagResult(result); 336 | case "onReceiveNotificationResponse": 337 | return _onReceiveNotificationResponse( 338 | call.arguments.cast()); 339 | case "onAppLinkPayload": 340 | return _onAppLinkPayload(call.arguments); 341 | case "onPushModeResult": 342 | return _onPushModeResult(call.arguments.cast()); 343 | case "onWillPresentNotification": 344 | return _onWillPresentNotification( 345 | call.arguments.cast()); 346 | case "onOpenSettingsForNotification": 347 | return _onOpenSettingsForNotification( 348 | call.arguments.cast()); 349 | case "onTransmitUserMessageReceive": 350 | return _onTransmitUserMessageReceive( 351 | call.arguments.cast()); 352 | case "onGrantAuthorization": 353 | return _onGrantAuthorization(call.arguments); 354 | case "onLiveActivityResult": 355 | return _onLiveActivityResult(call.arguments.cast()); 356 | case "onRegisterPushToStartTokenResult": 357 | return _onRegisterPushToStartTokenResult( 358 | call.arguments.cast()); 359 | case "onReceiveOnlineState": 360 | return _onReceiveOnlineState(call.arguments); 361 | default: 362 | throw new UnsupportedError("Unrecongnized Event"); 363 | } 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /android/src/main/java/com/getui/getuiflut/FlutterIntentService.java: -------------------------------------------------------------------------------- 1 | package com.getui.getuiflut; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.google.gson.Gson; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonParser; 9 | import com.igexin.sdk.GTIntentService; 10 | import com.igexin.sdk.PushConsts; 11 | import com.igexin.sdk.Tag; 12 | import com.igexin.sdk.message.BindAliasCmdMessage; 13 | import com.igexin.sdk.message.FeedbackCmdMessage; 14 | import com.igexin.sdk.message.GTCmdMessage; 15 | import com.igexin.sdk.message.GTNotificationMessage; 16 | import com.igexin.sdk.message.GTTransmitMessage; 17 | import com.igexin.sdk.message.QueryTagCmdMessage; 18 | import com.igexin.sdk.message.SetTagCmdMessage; 19 | import com.igexin.sdk.message.UnBindAliasCmdMessage; 20 | 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | /** 25 | * 推送服务处理类,继承自 GTIntentService,处理推送相关事件 26 | */ 27 | public class FlutterIntentService extends GTIntentService { 28 | private static final String TAG = "FlutterIntentService"; 29 | private static final Gson GSON = new Gson(); 30 | 31 | @Override 32 | public void onCreate() { 33 | super.onCreate(); 34 | log("Service created"); 35 | } 36 | 37 | @Override 38 | public void onReceiveServicePid(Context context, int pid) { 39 | log("Received service PID: " + pid); 40 | } 41 | 42 | @Override 43 | public void onReceiveClientId(Context context, String clientId) { 44 | log("Received client ID: " + clientId); 45 | GetuiflutPlugin.transmitMessageReceive(clientId, GetuiflutPlugin.StateType.onReceiveClientId); 46 | } 47 | 48 | @Override 49 | public void onReceiveMessageData(Context context, GTTransmitMessage msg) { 50 | log("Received message data"); 51 | Map payload = new HashMap<>(); 52 | payload.put("messageId", msg.getMessageId()); 53 | payload.put("payload", new String(msg.getPayload())); 54 | payload.put("payloadId", msg.getPayloadId()); 55 | payload.put("taskId", msg.getTaskId()); 56 | GetuiflutPlugin.transmitMessageReceive(GSON.toJson(payload), GetuiflutPlugin.StateType.onReceivePayload); 57 | } 58 | 59 | @Override 60 | public void onReceiveOnlineState(Context context, boolean online) { 61 | log("Received online state: " + online); 62 | GetuiflutPlugin.transmitMessageReceive(String.valueOf(online), GetuiflutPlugin.StateType.onReceiveOnlineState); 63 | } 64 | 65 | @Override 66 | public void onReceiveCommandResult(Context context, GTCmdMessage gtCmdMessage) { 67 | int action = gtCmdMessage.getAction(); 68 | if (action == PushConsts.SET_TAG_RESULT) { 69 | GetuiflutPlugin.transmitMessageReceive(getTagResult((SetTagCmdMessage) gtCmdMessage), GetuiflutPlugin.StateType.onSetTagResult); 70 | } else if (action == PushConsts.BIND_ALIAS_RESULT) { 71 | GetuiflutPlugin.transmitMessageReceive(bindAliasResult((BindAliasCmdMessage) gtCmdMessage),GetuiflutPlugin.StateType.onAliasResult); 72 | } else if (action == PushConsts.UNBIND_ALIAS_RESULT) { 73 | GetuiflutPlugin.transmitMessageReceive(unBindAliasResult((UnBindAliasCmdMessage) gtCmdMessage),GetuiflutPlugin.StateType.onAliasResult); 74 | } else if ((action == PushConsts.THIRDPART_FEEDBACK)) { 75 | GetuiflutPlugin.transmitMessageReceive(feedbackResult((FeedbackCmdMessage) gtCmdMessage),GetuiflutPlugin.StateType.thirdPartFeedback); 76 | }else if(action == PushConsts.QUERY_TAG_RESULT){ 77 | GetuiflutPlugin.transmitMessageReceive(onQueryTagResult((QueryTagCmdMessage) gtCmdMessage), GetuiflutPlugin.StateType.onQueryTagResult); 78 | } 79 | 80 | 81 | } 82 | 83 | private String onQueryTagResult(QueryTagCmdMessage gtCmdMessage) { 84 | String code = gtCmdMessage.getCode(); 85 | String sn = gtCmdMessage.getSn(); 86 | Tag[] tags = gtCmdMessage.getTags(); 87 | HashMap map = new HashMap<>(); 88 | map.put("sn",sn); 89 | map.put("result",Integer.parseInt(code)==0); 90 | map.put("code",Integer.parseInt(code)); 91 | map.put("tags",tags); 92 | return GSON.toJson(map); 93 | } 94 | 95 | private String feedbackResult(FeedbackCmdMessage feedbackCmdMsg) { 96 | String appid = feedbackCmdMsg.getAppid(); 97 | String taskid = feedbackCmdMsg.getTaskId(); 98 | String actionid = feedbackCmdMsg.getActionId(); 99 | String result = feedbackCmdMsg.getResult(); 100 | long timestamp = feedbackCmdMsg.getTimeStamp(); 101 | String cid = feedbackCmdMsg.getClientId(); 102 | 103 | HashMap map = new HashMap<>(); 104 | map.put("appid",appid); 105 | map.put("taskid",taskid); 106 | map.put("actionid",actionid); 107 | map.put("result",result); 108 | map.put("timestamp",timestamp); 109 | map.put("cid",cid); 110 | return GSON.toJson(map); 111 | } 112 | 113 | private String unBindAliasResult(UnBindAliasCmdMessage gtCmdMessage) { 114 | String sn = gtCmdMessage.getSn(); 115 | String code = gtCmdMessage.getCode(); 116 | 117 | int text = R.string.unbind_alias_unknown_exception; 118 | switch (Integer.parseInt(code)) { 119 | case PushConsts.UNBIND_ALIAS_SUCCESS: 120 | text = R.string.unbind_alias_success; 121 | break; 122 | case PushConsts.ALIAS_ERROR_FREQUENCY: 123 | text = R.string.unbind_alias_error_frequency; 124 | break; 125 | case PushConsts.ALIAS_OPERATE_PARAM_ERROR: 126 | text = R.string.unbind_alias_error_param_error; 127 | break; 128 | case PushConsts.ALIAS_REQUEST_FILTER: 129 | text = R.string.unbind_alias_error_request_filter; 130 | break; 131 | case PushConsts.ALIAS_OPERATE_ALIAS_FAILED: 132 | text = R.string.unbind_alias_unknown_exception; 133 | break; 134 | case PushConsts.ALIAS_CID_LOST: 135 | text = R.string.unbind_alias_error_cid_lost; 136 | break; 137 | case PushConsts.ALIAS_CONNECT_LOST: 138 | text = R.string.unbind_alias_error_connect_lost; 139 | break; 140 | case PushConsts.ALIAS_INVALID: 141 | text = R.string.unbind_alias_error_alias_invalid; 142 | break; 143 | case PushConsts.ALIAS_SN_INVALID: 144 | text = R.string.unbind_alias_error_sn_invalid; 145 | break; 146 | default: 147 | break; 148 | 149 | } 150 | HashMap map = new HashMap<>(); 151 | map.put("sn",sn); 152 | map.put("result",Integer.parseInt(code)==0); 153 | map.put("code",Integer.parseInt(code)); 154 | map.put("message",getResources().getString(text)); 155 | return GSON.toJson(map); 156 | } 157 | 158 | private String bindAliasResult(BindAliasCmdMessage gtCmdMessage) { 159 | String sn = gtCmdMessage.getSn(); 160 | String code = gtCmdMessage.getCode(); 161 | 162 | int text = R.string.bind_alias_unknown_exception; 163 | switch (Integer.parseInt(code)) { 164 | case PushConsts.BIND_ALIAS_SUCCESS: 165 | text = R.string.bind_alias_success; 166 | break; 167 | case PushConsts.ALIAS_ERROR_FREQUENCY: 168 | text = R.string.bind_alias_error_frequency; 169 | break; 170 | case PushConsts.ALIAS_OPERATE_PARAM_ERROR: 171 | text = R.string.bind_alias_error_param_error; 172 | break; 173 | case PushConsts.ALIAS_REQUEST_FILTER: 174 | text = R.string.bind_alias_error_request_filter; 175 | break; 176 | case PushConsts.ALIAS_OPERATE_ALIAS_FAILED: 177 | text = R.string.bind_alias_unknown_exception; 178 | break; 179 | case PushConsts.ALIAS_CID_LOST: 180 | text = R.string.bind_alias_error_cid_lost; 181 | break; 182 | case PushConsts.ALIAS_CONNECT_LOST: 183 | text = R.string.bind_alias_error_connect_lost; 184 | break; 185 | case PushConsts.ALIAS_INVALID: 186 | text = R.string.bind_alias_error_alias_invalid; 187 | break; 188 | case PushConsts.ALIAS_SN_INVALID: 189 | text = R.string.bind_alias_error_sn_invalid; 190 | break; 191 | default: 192 | break; 193 | 194 | } 195 | HashMap map = new HashMap<>(); 196 | map.put("sn",sn); 197 | map.put("result",Integer.parseInt(code)==0); 198 | map.put("code",Integer.parseInt(code)); 199 | map.put("message",getResources().getString(text)); 200 | return GSON.toJson(map); 201 | } 202 | 203 | private String getTagResult(SetTagCmdMessage gtCmdMessage) { 204 | String sn = gtCmdMessage.getSn(); 205 | String code = gtCmdMessage.getCode(); 206 | int text = R.string.add_tag_unknown_exception; 207 | switch (Integer.parseInt(code)) { 208 | case PushConsts.SETTAG_SUCCESS: 209 | text = R.string.add_tag_success; 210 | break; 211 | case PushConsts.SETTAG_ERROR_COUNT: 212 | text = R.string.add_tag_error_count; 213 | break; 214 | case PushConsts.SETTAG_ERROR_FREQUENCY: 215 | text = R.string.add_tag_error_frequency; 216 | break; 217 | case PushConsts.SETTAG_ERROR_REPEAT: 218 | text = R.string.add_tag_error_repeat; 219 | break; 220 | case PushConsts.SETTAG_ERROR_UNBIND: 221 | text = R.string.add_tag_error_unbind; 222 | break; 223 | case PushConsts.SETTAG_ERROR_EXCEPTION: 224 | text = R.string.add_tag_unknown_exception; 225 | break; 226 | case PushConsts.SETTAG_ERROR_NULL: 227 | text = R.string.add_tag_error_null; 228 | break; 229 | case PushConsts.SETTAG_NOTONLINE: 230 | text = R.string.add_tag_error_not_online; 231 | break; 232 | case PushConsts.SETTAG_IN_BLACKLIST: 233 | text = R.string.add_tag_error_black_list; 234 | break; 235 | case PushConsts.SETTAG_NUM_EXCEED: 236 | text = R.string.add_tag_error_exceed; 237 | break; 238 | case PushConsts.SETTAG_TAG_ILLEGAL: 239 | text = R.string.add_tag_error_tagIllegal; 240 | break; 241 | default: 242 | break; 243 | } 244 | 245 | HashMap map = new HashMap<>(); 246 | map.put("sn",sn); 247 | map.put("result",Integer.parseInt(code)==0); 248 | map.put("code",Integer.parseInt(code)); 249 | map.put("message",getResources().getString(text)); 250 | return GSON.toJson(map); 251 | } 252 | 253 | @Override 254 | public void onNotificationMessageArrived(Context context, GTNotificationMessage message) { 255 | log("Notification arrived"); 256 | Map notification = new HashMap(); 257 | notification.put("messageId",message.getMessageId()); 258 | notification.put("taskId",message.getTaskId()); 259 | notification.put("title",message.getTitle()); 260 | notification.put("content",message.getContent()); 261 | GetuiflutPlugin.transmitMessageReceive(GSON.toJson(notification), GetuiflutPlugin.StateType.onNotificationMessageArrived); 262 | } 263 | 264 | @Override 265 | public void onNotificationMessageClicked(Context context, GTNotificationMessage message) { 266 | log("Notification clicked"); 267 | Map notification = new HashMap(); 268 | notification.put("messageId",message.getMessageId()); 269 | notification.put("taskId",message.getTaskId()); 270 | notification.put("title",message.getTitle()); 271 | notification.put("content",message.getContent()); 272 | GetuiflutPlugin.transmitMessageReceive(GSON.toJson(notification), GetuiflutPlugin.StateType.onNotificationMessageClicked); 273 | } 274 | 275 | // 统一日志记录方法 276 | private void log(String message) { 277 | Log.d(TAG, message); 278 | } 279 | 280 | // 获取设置标签的提示信息资源 ID 281 | private int getMessageResIdForTag(String code) { 282 | switch (Integer.parseInt(code)) { 283 | case PushConsts.SETTAG_SUCCESS: return R.string.add_tag_success; 284 | case PushConsts.SETTAG_ERROR_COUNT: return R.string.add_tag_error_count; 285 | case PushConsts.SETTAG_ERROR_FREQUENCY: return R.string.add_tag_error_frequency; 286 | case PushConsts.SETTAG_ERROR_REPEAT: return R.string.add_tag_error_repeat; 287 | case PushConsts.SETTAG_ERROR_UNBIND: return R.string.add_tag_error_unbind; 288 | case PushConsts.SETTAG_ERROR_EXCEPTION: return R.string.add_tag_unknown_exception; 289 | case PushConsts.SETTAG_ERROR_NULL: return R.string.add_tag_error_null; 290 | case PushConsts.SETTAG_NOTONLINE: return R.string.add_tag_error_not_online; 291 | case PushConsts.SETTAG_IN_BLACKLIST: return R.string.add_tag_error_black_list; 292 | case PushConsts.SETTAG_NUM_EXCEED: return R.string.add_tag_error_exceed; 293 | case PushConsts.SETTAG_TAG_ILLEGAL: return R.string.add_tag_error_tagIllegal; 294 | default: return R.string.add_tag_unknown_exception; 295 | } 296 | } 297 | 298 | // 获取别名操作的提示信息资源 ID 299 | private int getMessageResIdForAlias(String code, boolean isBind) { 300 | int baseResId = isBind ? R.string.bind_alias_unknown_exception : R.string.unbind_alias_unknown_exception; 301 | switch (Integer.parseInt(code)) { 302 | case PushConsts.BIND_ALIAS_SUCCESS: return isBind ? R.string.bind_alias_success : R.string.unbind_alias_success; 303 | case PushConsts.ALIAS_ERROR_FREQUENCY: return isBind ? R.string.bind_alias_error_frequency : R.string.unbind_alias_error_frequency; 304 | case PushConsts.ALIAS_OPERATE_PARAM_ERROR: return isBind ? R.string.bind_alias_error_param_error : R.string.unbind_alias_error_param_error; 305 | case PushConsts.ALIAS_REQUEST_FILTER: return isBind ? R.string.bind_alias_error_request_filter : R.string.unbind_alias_error_request_filter; 306 | case PushConsts.ALIAS_OPERATE_ALIAS_FAILED: return baseResId; 307 | case PushConsts.ALIAS_CID_LOST: return isBind ? R.string.bind_alias_error_cid_lost : R.string.unbind_alias_error_cid_lost; 308 | case PushConsts.ALIAS_CONNECT_LOST: return isBind ? R.string.bind_alias_error_connect_lost : R.string.unbind_alias_error_connect_lost; 309 | case PushConsts.ALIAS_INVALID: return isBind ? R.string.bind_alias_error_alias_invalid : R.string.unbind_alias_error_alias_invalid; 310 | case PushConsts.ALIAS_SN_INVALID: return isBind ? R.string.bind_alias_error_sn_invalid : R.string.unbind_alias_error_sn_invalid; 311 | default: return baseResId; 312 | } 313 | } 314 | } -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/material.dart'; 3 | import 'dart:async'; 4 | import 'dart:io'; 5 | import 'package:flutter/services.dart'; 6 | import 'package:getuiflut/getuiflut.dart'; 7 | 8 | void main() => runApp(MyApp()); 9 | 10 | class MyApp extends StatefulWidget { 11 | @override 12 | _MyAppState createState() => _MyAppState(); 13 | } 14 | 15 | class _MyAppState extends State { 16 | String _platformVersion = 'Unknown'; 17 | String _userMsg = ''; 18 | String _notificationState = ''; 19 | String _getClientId = ''; 20 | String _getDeviceToken = ''; 21 | String _onReceivePayload = ''; 22 | String _onReceiveNotificationResponse = ''; 23 | String _onAppLinkPayLoad = ''; 24 | final Getuiflut _getui = Getuiflut(); 25 | 26 | @override 27 | void initState() { 28 | super.initState(); 29 | initPlatformState(); 30 | } 31 | 32 | // 初始化平台状态 33 | Future initPlatformState() async { 34 | String platformVersion; 35 | String payloadInfo = 'default'; 36 | String notificationState = 'default'; 37 | 38 | try { 39 | // 获取平台版本 40 | platformVersion = await _getui.platformVersion; 41 | print('平台版本: $platformVersion'); 42 | 43 | // iOS 初始化 SDK 44 | if (Platform.isIOS) { 45 | _getui.startSdk( 46 | appId: 'xXmjbbab3b5F1m7wAYZoG2', 47 | appKey: 'BZF4dANEYr8dwLhj6lRfx2', 48 | appSecret: 'yXRS5zRxDt8WhMW8DD8W05', 49 | ); 50 | await getSdkVersion(); 51 | } else { 52 | // Android/HarmonyOS 初始化 SDK 53 | _getui.initGetuiSdk; 54 | } 55 | } on PlatformException catch (e) { 56 | platformVersion = '获取平台版本失败: ${e.message}'; 57 | } 58 | 59 | if (!mounted) return; 60 | 61 | setState(() { 62 | _platformVersion = platformVersion; 63 | _notificationState = notificationState; 64 | }); 65 | 66 | // 设置事件监听 67 | _getui.addEventHandler( 68 | onReceiveClientId: (String message) async { 69 | print('收到客户端 ID: $message'); 70 | setState(() { 71 | _getClientId = message; 72 | }); 73 | }, 74 | onReceiveOnlineState: (String online) async { 75 | print('在线状态: $online'); 76 | }, 77 | onReceivePayload: (Map message) async { 78 | print('收到 Payload: $message'); 79 | setState(() { 80 | _onReceivePayload = message.toString(); 81 | }); 82 | }, 83 | onSetTagResult: (Map message) async { 84 | print('设置标签结果: $message'); 85 | }, 86 | onAliasResult: (Map message) async { 87 | print('别名操作结果: $message'); 88 | }, 89 | onQueryTagResult: (Map message) async { 90 | print('查询标签结果: $message'); 91 | }, 92 | onRegisterDeviceToken: (String message) async { 93 | print('注册设备令牌: $message'); 94 | setState(() { 95 | _getDeviceToken = message; 96 | }); 97 | }, 98 | // Android 和 HarmonyOS 专用 99 | onNotificationMessageArrived: (Map msg) async { 100 | print('通知到达: $msg'); 101 | setState(() { 102 | _notificationState = '已到达'; 103 | }); 104 | }, 105 | onNotificationMessageClicked: (Map msg) async { 106 | print('通知被点击: $msg'); 107 | setState(() { 108 | _notificationState = '已点击'; 109 | }); 110 | }, 111 | // iOS 专用 112 | onTransmitUserMessageReceive: (Map msg) async { 113 | print('收到用户消息: $msg'); 114 | setState(() { 115 | _userMsg = msg['msg']?.toString() ?? ''; 116 | }); 117 | }, 118 | onReceiveNotificationResponse: (Map message) async { 119 | print('收到通知响应: $message'); 120 | setState(() { 121 | _onReceiveNotificationResponse = message.toString(); 122 | }); 123 | }, 124 | onAppLinkPayload: (String message) async { 125 | print('收到 AppLink Payload: $message'); 126 | setState(() { 127 | _onAppLinkPayLoad = message; 128 | }); 129 | }, 130 | onPushModeResult: (Map message) async { 131 | print('推送模式结果: $message'); 132 | }, 133 | onWillPresentNotification: (Map message) async { 134 | print('即将显示通知: $message'); 135 | }, 136 | onOpenSettingsForNotification: (Map message) async { 137 | print('打开通知设置: $message'); 138 | }, 139 | onGrantAuthorization: (String granted) async { 140 | print('授权状态: $granted'); 141 | }, 142 | onLiveActivityResult: (Map message) async { 143 | print('灵动岛结果: $message'); 144 | }, 145 | onRegisterPushToStartTokenResult: (Map message) async { 146 | print('注册推送启动令牌结果: $message'); 147 | }, 148 | ); 149 | } 150 | 151 | // 获取 SDK 版本 152 | Future getSdkVersion() async { 153 | try { 154 | final ver = await _getui.sdkVersion; 155 | print('SDK 版本: $ver'); 156 | } catch (e) { 157 | print('获取 SDK 版本失败: $e'); 158 | } 159 | } 160 | 161 | // 获取启动通知 162 | Future getLaunchNotification() async { 163 | try { 164 | final info = await _getui.getLaunchNotification; 165 | print('启动通知: $info'); 166 | } catch (e) { 167 | print('获取启动通知失败: $e'); 168 | } 169 | } 170 | 171 | // 获取本地启动通知 172 | Future getLaunchLocalNotification() async { 173 | try { 174 | final info = await _getui.getLaunchLocalNotification; 175 | print('本地启动通知: $info'); 176 | } catch (e) { 177 | print('获取本地启动通知失败: $e'); 178 | } 179 | } 180 | 181 | @override 182 | Widget build(BuildContext context) { 183 | return MaterialApp( 184 | debugShowCheckedModeBanner: false, 185 | home: Scaffold( 186 | appBar: AppBar( 187 | title: const Text('个推插件示例应用'), 188 | ), 189 | body: ListView( 190 | children: [ 191 | Container( 192 | alignment: Alignment.center, 193 | padding: const EdgeInsets.all(16.0), 194 | child: Column( 195 | children: [ 196 | Text('平台版本: $_platformVersion\n'), 197 | Text('客户端 ID: $_getClientId\n'), 198 | Text( 199 | '公共功能', 200 | style: TextStyle( 201 | color: Colors.lightBlue, 202 | fontSize: 20.0, 203 | ), 204 | ), 205 | Text('用户消息: $_userMsg\n'), 206 | Text('Payload: $_onReceivePayload'), 207 | Text('通知状态: $_notificationState\n'), 208 | Row( 209 | mainAxisAlignment: MainAxisAlignment.spaceAround, 210 | children: [ 211 | ElevatedButton( 212 | onPressed: () { 213 | if (Platform.isIOS) { 214 | _getui.startSdk( 215 | appId: 'xXmjbbab3b5F1m7wAYZoG2', 216 | appKey: 'BZF4dANEYr8dwLhj6lRfx2', 217 | appSecret: 'yXRS5zRxDt8WhMW8DD8W05', 218 | ); 219 | } else { 220 | _getui.initGetuiSdk; 221 | } 222 | }, 223 | child: const Text('初始化 SDK'), 224 | ), 225 | ElevatedButton( 226 | onPressed: Platform.isAndroid 227 | ? () { 228 | _getui.onActivityCreate(); 229 | } 230 | : null, 231 | child: const Text('onActivityCreate'), 232 | ), 233 | ] 234 | ), 235 | 236 | Row( 237 | mainAxisAlignment: MainAxisAlignment.spaceAround, 238 | children: [ 239 | ElevatedButton( 240 | onPressed: () { 241 | _getui.getClientId.then((value) { 242 | print('客户端 ID: $value'); 243 | setState(() { 244 | _getClientId = value; 245 | }); 246 | }); 247 | }, 248 | child: const Text('获取客户端 ID'), 249 | ), 250 | ElevatedButton( 251 | onPressed: () { 252 | _getui.turnOffPush(); 253 | }, 254 | child: const Text('关闭推送'), 255 | ), 256 | ElevatedButton( 257 | onPressed: () { 258 | _getui.turnOnPush(); 259 | }, 260 | child: const Text('开启推送'), 261 | ), 262 | ], 263 | ), 264 | Row( 265 | mainAxisAlignment: MainAxisAlignment.spaceAround, 266 | children: [ 267 | ElevatedButton( 268 | onPressed: () { 269 | _getui.bindAlias('test', 'test'); 270 | }, 271 | child: const Text('绑定别名'), 272 | ), 273 | ElevatedButton( 274 | onPressed: () { 275 | _getui.unbindAlias('test', 'test', true); 276 | }, 277 | child: const Text('解绑别名'), 278 | ), 279 | 280 | ], 281 | ), 282 | Row( 283 | mainAxisAlignment: MainAxisAlignment.spaceAround, 284 | children: [ 285 | ElevatedButton( 286 | onPressed: () { 287 | _getui.setBadge(5); 288 | }, 289 | child: const Text('设置角标'), 290 | ), 291 | ElevatedButton( 292 | onPressed: () { 293 | List tags = ['abc']; 294 | _getui.setTag(tags, "唯一标识"); 295 | }, 296 | child: const Text('设置标签'), 297 | ), 298 | ElevatedButton( 299 | onPressed: () { 300 | _getui.queryTag("唯一标识"); 301 | }, 302 | child: const Text('查询标签'), 303 | ), 304 | ], 305 | ), 306 | Row( 307 | mainAxisAlignment: MainAxisAlignment.spaceAround, 308 | children: [ 309 | ElevatedButton( 310 | onPressed: () { 311 | _getui.setSilentTime(13,0); 312 | }, 313 | child: const Text('设置静默时间(非IOS)'), 314 | ), 315 | ElevatedButton( 316 | onPressed: () { 317 | _getui.sendFeedbackMessage("taskId","messageId", 90002 ); 318 | }, 319 | child: const Text('自定义数据回执'), 320 | ) 321 | ] 322 | ), 323 | 324 | Text( 325 | 'iOS 专用功能', 326 | style: TextStyle( 327 | color: Colors.redAccent, 328 | fontSize: 20.0, 329 | ), 330 | ), 331 | Text('设备令牌: $_getDeviceToken'), 332 | Text('AppLink Payload: $_onAppLinkPayLoad'), 333 | Text('APNs 通知: $_onReceiveNotificationResponse'), 334 | Row( 335 | mainAxisAlignment: MainAxisAlignment.spaceAround, 336 | children: [ 337 | ElevatedButton( 338 | onPressed: getLaunchNotification, 339 | child: const Text('获取启动通知'), 340 | ), 341 | ElevatedButton( 342 | onPressed: getLaunchLocalNotification, 343 | child: const Text('获取本地启动通知'), 344 | ), 345 | ], 346 | ), 347 | Row( 348 | mainAxisAlignment: MainAxisAlignment.spaceAround, 349 | children: [ 350 | ElevatedButton( 351 | onPressed: Platform.isIOS?() { 352 | _getui.setBadge(5); 353 | }:null, 354 | child: const Text('设置角标'), 355 | ), 356 | ElevatedButton( 357 | onPressed: Platform.isIOS 358 | ? () { 359 | _getui.setLocalBadge(5); 360 | } 361 | : null, 362 | child: const Text('设置本地角标(5)'), 363 | ), 364 | ], 365 | ), 366 | Row( 367 | mainAxisAlignment: MainAxisAlignment.spaceAround, 368 | children: [ 369 | ElevatedButton( 370 | onPressed: Platform.isIOS 371 | ? () { 372 | _getui.resetBadge(); 373 | } 374 | : null, 375 | child: const Text('重置角标'), 376 | ), 377 | ElevatedButton( 378 | onPressed: Platform.isIOS 379 | ? () { 380 | _getui.setPushMode(0); 381 | } 382 | : null, 383 | child: const Text('设置推送模式(0)'), 384 | ), 385 | ], 386 | ), 387 | Row( 388 | mainAxisAlignment: MainAxisAlignment.spaceAround, 389 | children: [ 390 | ElevatedButton( 391 | onPressed: Platform.isIOS 392 | ? () { 393 | _getui.startSdkSimple( 394 | appId: 'xXmjbbab3b5F1m7wAYZoG2', 395 | appKey: 'BZF4dANEYr8dwLhj6lRfx2', 396 | appSecret: 'yXRS5zRxDt8WhMW8DD8W05', 397 | ); 398 | } 399 | : null, 400 | child: const Text('仅启动 SDK'), 401 | ), 402 | ElevatedButton( 403 | onPressed: Platform.isIOS 404 | ? () { 405 | _getui.registerRemoteNotification(); 406 | } 407 | : null, 408 | child: const Text('注册通知权限'), 409 | ), 410 | ], 411 | ), 412 | Row( 413 | mainAxisAlignment: MainAxisAlignment.spaceAround, 414 | children: [ 415 | ElevatedButton( 416 | onPressed: Platform.isIOS 417 | ? () { 418 | _getui.registerDeviceToken(_getDeviceToken); 419 | } 420 | : null, 421 | child: const Text('注册设备令牌'), 422 | ), 423 | ElevatedButton( 424 | onPressed: !Platform.isAndroid 425 | ? () { 426 | _getui.runBackgroundEnable(1); 427 | } 428 | : null, 429 | child: const Text('启用后台模式'), 430 | ), 431 | ], 432 | ), 433 | Row( 434 | mainAxisAlignment: MainAxisAlignment.spaceAround, 435 | children: [ 436 | ElevatedButton( 437 | onPressed: Platform.isIOS 438 | ? () { 439 | _getui.registerActivityToken( 440 | 'aid_01', _getDeviceToken, 'sn_01'); 441 | } 442 | : null, 443 | child: const Text('注册灵动岛令牌'), 444 | ), 445 | ElevatedButton( 446 | onPressed: Platform.isIOS 447 | ? () { 448 | _getui.registerPushToStartToken( 449 | 'attribute1', 'faketoken', 'attribute1_sn'); 450 | } 451 | : null, 452 | child: const Text('注册推送启动令牌'), 453 | ), 454 | ], 455 | ), 456 | ], 457 | ), 458 | ), 459 | ], 460 | ), 461 | ), 462 | ); 463 | } 464 | } 465 | -------------------------------------------------------------------------------- /ios/Classes/GetuiflutPlugin.m: -------------------------------------------------------------------------------- 1 | #import "GetuiflutPlugin.h" 2 | #import 3 | #import 4 | #import 5 | 6 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 7 | #import 8 | #endif 9 | @interface GeTuiSdk(GetuiflutPlugin) 10 | //3.0.3.0废弃的API 11 | + (BOOL)registerActivityToken:(NSString *)activityToken; 12 | @end 13 | 14 | @interface GtSdkManager : NSObject 15 | + (GtSdkManager *)sharedInstance; 16 | //用于上报回执&回调 17 | - (void)Getui_didReceiveRemoteNotificationInner:(NSDictionary*)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; 18 | @end 19 | 20 | 21 | NSDictionary *_launchNotification; 22 | NSDictionary *_launchLocalNotification; 23 | @interface GetuiflutPlugin() { 24 | BOOL _started; 25 | NSDictionary *_launchOptions; 26 | NSDictionary *_apnsSlienceUserInfo; 27 | } 28 | @end 29 | 30 | @implementation GetuiflutPlugin 31 | 32 | + (void)registerWithRegistrar:(NSObject*)registrar { 33 | FlutterMethodChannel* channel = [FlutterMethodChannel 34 | methodChannelWithName:@"getuiflut" 35 | binaryMessenger:[registrar messenger]]; 36 | GetuiflutPlugin *instance = [[GetuiflutPlugin alloc] init]; 37 | instance.channel = channel; 38 | [registrar addApplicationDelegate:instance]; 39 | [registrar addMethodCallDelegate:instance channel:channel]; 40 | // [instance registerRemoteNotification]; 41 | 42 | // [instance registerObservers]; 43 | } 44 | 45 | //- (void)registerObservers { 46 | // NSLog(@">>>GTSDK registerObservers"); 47 | // [[NSNotificationCenter defaultCenter] addObserver:self 48 | // selector:@selector(onSceneConnected:) 49 | // name:UISceneWillConnectNotification 50 | // object:nil]; 51 | //} 52 | // 53 | //// 尝试处理Scene模式启动参数 54 | //- (void)onSceneConnected:(NSNotification *)notification { 55 | // //但这个通知的userInfo 不包含 connectionOptions。它只提供notification.object是一个scene对象,无法直接提取APNS数据 56 | // 57 | // NSLog(@">>>GTSDK onSceneConnected %@ userinfo:%@",notification, notification.userInfo); 58 | // // 获取UIScene对象 59 | // UIScene *scene = notification.object; 60 | // NSLog(@">>>GTSDK Scene connection established"); 61 | //} 62 | 63 | - (id)init { 64 | self = [super init]; 65 | _launchOptions = @{}; 66 | _launchNotification = nil; 67 | _launchLocalNotification = nil; 68 | _apnsSlienceUserInfo = @{}; 69 | return self; 70 | } 71 | 72 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 73 | if ([@"getPlatformVersion" isEqualToString:call.method]) { 74 | result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); 75 | } else if([@"startSdk" isEqualToString:call.method]) { 76 | [self startSdk:call result:result]; 77 | } else if([@"startSdkSimple" isEqualToString:call.method]) { 78 | [self onlyStartSdk:call result:result]; 79 | } else if([@"registerRemoteNotification" isEqualToString:call.method]) { 80 | [self registerRemoteNotification:call result:result]; 81 | } else if([@"bindAlias" isEqualToString:call.method]) { 82 | [self bindAlias:call result:result]; 83 | } else if([@"unbindAlias" isEqualToString:call.method]) { 84 | [self unbindAlias:call result:result]; 85 | } else if([@"setTag" isEqualToString:call.method]) { 86 | [self setTag:call result:result]; 87 | }else if([@"queryTag" isEqualToString:call.method]) { 88 | result(FlutterMethodNotImplemented); 89 | } else if([@"getClientId" isEqualToString:call.method]) { 90 | result([GeTuiSdk clientId]); 91 | } else if([@"setBadge" isEqualToString:call.method]) { 92 | [self setBadge:call result:result]; 93 | } else if([@"resetBadge" isEqualToString:call.method]) { 94 | [GeTuiSdk resetBadge]; 95 | } else if([@"setLocalBadge" isEqualToString:call.method]) { 96 | [self setLocalBadge:call result:result]; 97 | } else if([@"setPushMode" isEqualToString:call.method]) { 98 | [self setPushMode:call result:result]; 99 | } else if([@"resume" isEqualToString:call.method]) { 100 | // [GeTuiSdk resume]; 101 | } else if([@"getLaunchNotification" isEqualToString:call.method]) { 102 | NSLog(@">>>GTSDK getLaunchNotification %@", _launchNotification); 103 | result(_launchNotification ?: @{}); 104 | } else if([@"getLaunchLocalNotification" isEqualToString:call.method]) { 105 | NSLog(@">>>GTSDK getLaunchLocalNotification %@", _launchLocalNotification); 106 | result(_launchLocalNotification ?: @{}); 107 | } else if([@"sdkVersion" isEqualToString:call.method]) { 108 | result([GeTuiSdk version]); 109 | } else if([@"registerDeviceToken" isEqualToString:call.method]) { 110 | [self registerDeviceToken:call result:result]; 111 | } else if([@"runBackgroundEnable" isEqualToString:call.method]) { 112 | [self runBackgroundEnable:call result:result]; 113 | } else if([@"registerActivityToken" isEqualToString:call.method]) { 114 | [self registerActivityToken:call result:result]; 115 | } else if([@"registerPushToStartToken" isEqualToString:call.method]) { 116 | [self registerPushToStartToken:call result:result]; 117 | } else if([@"sendFeedbackMessage" isEqualToString:call.method]) { 118 | NSDictionary *ConfigurationInfo = call.arguments; 119 | [GeTuiSdk sendFeedbackMessage:ConfigurationInfo[@"actionId"] andTaskId:ConfigurationInfo[@"taskId"] andMsgId:ConfigurationInfo[@"messageId"]]; 120 | } else { 121 | result(FlutterMethodNotImplemented); 122 | } 123 | } 124 | 125 | - (void)startSdk:(FlutterMethodCall*)call result:(FlutterResult)result { 126 | NSLog(@"\n>>>GTSDK startSdk launchNotification:%@", _launchNotification); 127 | _started = YES; 128 | NSDictionary *ConfigurationInfo = call.arguments; 129 | [GeTuiSdk startSdkWithAppId:ConfigurationInfo[@"appId"] appKey:ConfigurationInfo[@"appKey"] appSecret:ConfigurationInfo[@"appSecret"] delegate:self launchingOptions:_launchOptions ?: @{}]; 130 | 131 | // 注册远程通知 132 | [GeTuiSdk registerRemoteNotification: (UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)]; 133 | } 134 | 135 | - (void)onlyStartSdk:(FlutterMethodCall*)call result:(FlutterResult)result { 136 | NSLog(@"\n>>>GTSDK onlyStartSdk"); 137 | _started = YES; 138 | NSDictionary *ConfigurationInfo = call.arguments; 139 | [GeTuiSdk startSdkWithAppId:ConfigurationInfo[@"appId"] appKey:ConfigurationInfo[@"appKey"] appSecret:ConfigurationInfo[@"appSecret"] delegate:self launchingOptions:_launchOptions ?: @{}]; 140 | } 141 | 142 | - (void)registerRemoteNotification:(FlutterMethodCall*)call result:(FlutterResult)result { 143 | [GeTuiSdk registerRemoteNotification: (UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)]; 144 | } 145 | 146 | /// MARK: - AppDelegate 147 | 148 | 149 | //兼容非Scene的启动方式 150 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 151 | if (launchOptions != nil) { 152 | _launchOptions = launchOptions; 153 | 154 | _launchNotification = @{};//避免后续错误赋值 155 | _launchLocalNotification = @{};//避免后续错误赋值 156 | 157 | _launchNotification = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]; 158 | if(launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { 159 | 160 | // 获取本地通知对象(类型为 UILocalNotification) 161 | UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; 162 | if (localNotification && 163 | localNotification.userInfo && 164 | [localNotification.userInfo isKindOfClass:[NSDictionary class]]) { 165 | NSDictionary *userInfo = localNotification.userInfo; 166 | _launchLocalNotification = userInfo; 167 | } 168 | } 169 | 170 | NSLog(@"\n>>>GTSDK didFinishLaunchingWithOptions launchOptions:%@ noti:%@ local_noti:%@", launchOptions,_launchNotification, _launchLocalNotification); 171 | } 172 | return YES; 173 | } 174 | 175 | // 兼容非Scene的启动方式(iOS>=13) 176 | // 公共类方法,让主App的SceneDelegate调用(处理冷启动APNS数据) 177 | + (void)handleSceneWillConnectWithOptions:(UISceneConnectionOptions *)connectionOptions { 178 | if (!connectionOptions) { 179 | NSLog(@">>>GTSDK handleSceneWillConnectWithOptions: No options provided"); 180 | return; 181 | } 182 | NSLog(@">>>GTSDK handleSceneWillConnectWithOptions: %@",connectionOptions); 183 | 184 | //统计回执 185 | [GeTuiSdk handleSceneWillConnectWithOptions:connectionOptions]; 186 | 187 | 188 | //给开发者返回参数 189 | UNNotification *note = connectionOptions.notificationResponse.notification; 190 | [self checkLocalAndLaunchNotification:note]; 191 | // NSDictionary *userInfo = note.request.content.userInfo; 192 | // UNNotificationTrigger *trigger = note.request.trigger; 193 | // if (note && userInfo) { 194 | // if ([trigger isKindOfClass:[UNPushNotificationTrigger class]]) { 195 | // NSLog(@">>>GTSDK handleSceneWillConnectWithOptions 远程通知 %@", userInfo); 196 | // _launchNotification = userInfo; 197 | // } else { 198 | // NSLog(@">>>GTSDK handleSceneWillConnectWithOptions 本地通知 %@", userInfo); 199 | // _launchLocalNotification = userInfo; 200 | // } 201 | // } 202 | } 203 | 204 | // 处理收到的通知信息,设置_launchNotification变量 205 | - (void)checkLaunchNotification:(NSDictionary *)userInfo { 206 | if (!_launchNotification && userInfo) { 207 | //_launchNotification=nil表示当前启动不是通过点击通知栏进来的,没有启动参数, 208 | //_launchNotification=@{}表示,是在willpresent逻辑中重置了,避免这里错误赋值 209 | _launchNotification = userInfo; 210 | NSLog(@">>>GTSDK _launchNotification = %@", _launchNotification); 211 | } 212 | } 213 | 214 | + (void)checkLocalAndLaunchNotification:(UNNotification *)note { 215 | //给开发者返回参数 216 | //UNNotification *note = connectionOptions.notificationResponse.notification; 217 | NSDictionary *userInfo = note.request.content.userInfo; 218 | UNNotificationTrigger *trigger = note.request.trigger; 219 | NSLog(@">>>GTSDK checkLocalAndLaunchNotification note=%@ userInfo=%@ trigger=%@", note, userInfo,trigger); 220 | if (note && userInfo) { 221 | if ([trigger isKindOfClass:[UNPushNotificationTrigger class]]) { 222 | if (!_launchNotification) {// _launchNotification = nil才会赋值哦 223 | NSLog(@">>>GTSDK handleSceneWillConnectWithOptions 远程通知 %@", userInfo); 224 | _launchNotification = userInfo; 225 | } 226 | } else { 227 | if (!_launchLocalNotification) {// _launchLocalNotification = nil才会赋值哦 228 | NSLog(@">>>GTSDK handleSceneWillConnectWithOptions 本地通知 %@", userInfo); 229 | _launchLocalNotification = userInfo; 230 | } 231 | } 232 | } 233 | } 234 | 235 | /// MARK: - 远程通知(推送)回调 236 | 237 | /** 远程通知注册成功委托 */ 238 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 239 | // [3]:向个推服务器注册deviceToken 为了方便开发者,建议使用新方法 240 | // [GeTuiSdk registerDeviceTokenData:deviceToken]; 241 | NSString *token = [self getHexStringForData:deviceToken]; 242 | NSLog(@"\n>>>GTSDK [DeviceToken(NSString)]: %@\n\n", token); 243 | [_channel invokeMethod:@"onRegisterDeviceToken" arguments:token]; 244 | } 245 | 246 | /** 远程通知注册失败委托 */ 247 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { 248 | NSLog(@"\n>>>GTSDK didFailToRegisterForRemoteNotificationsWithError"); 249 | } 250 | 251 | - (BOOL)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { 252 | NSLog(@">>>GTSDK didReceiveRemoteNotification %@ _started:%@", userInfo, @(_started)); 253 | 254 | //UIScene启动方式下, 静默通知可能会通过这里补发启动参数哦 255 | [self checkLaunchNotification:userInfo]; 256 | 257 | if (_started) { 258 | /* 259 | 注释下面代码,因为开发者在appdelegate.m中重写application:didReceiveRemoteNotification:fetchCompletionHandler后,个推hook就正常了。 260 | 否则,此处需要再转发给个推处理回执 261 | */ 262 | //sdk已启动,收到APNs静默, 回执&回调 263 | //[[GtSdkManager sharedInstance] Getui_didReceiveRemoteNotificationInner:userInfo fetchCompletionHandler:completionHandler]; 264 | } else { 265 | //sdk未启动,收到APNs静默后启动sdk。记录到内存,等cid在线后,回执&回调 266 | _apnsSlienceUserInfo = userInfo; 267 | //completionHandler(UIBackgroundFetchResultNewData); //注释,因为会导致flutter日志打印多份。 268 | } 269 | return YES; 270 | } 271 | 272 | /// MARK: - APP运行中接收到通知(推送)处理 - iOS 10以下版本收到推送 273 | 274 | /// MARK: - GeTuiSdkDelegate 275 | - (void)GetuiSdkGrantAuthorization:(BOOL)granted error:(NSError *)error { 276 | NSLog(@"\n>>>GTSDK GetuiSdkGrantAuthorization: granted:%@ error:%@", @(granted), error); 277 | 278 | [_channel invokeMethod:@"onGrantAuthorization" arguments:[NSString stringWithFormat:@"%@",@(granted)]]; 279 | } 280 | /** SDK启动成功返回cid */ 281 | - (void)GeTuiSdkDidRegisterClient:(NSString *)clientId { 282 | // [ GTSdk ]:个推SDK已注册,返回clientId 283 | NSLog(@"\n>>>GTSDK RegisterClient:%@", clientId); 284 | if ([clientId isEqualToString:@""]) { 285 | return; 286 | } 287 | 288 | [_channel invokeMethod:@"onReceiveClientId" arguments:clientId]; 289 | 290 | if (_apnsSlienceUserInfo) { 291 | [[GtSdkManager sharedInstance] Getui_didReceiveRemoteNotificationInner:_apnsSlienceUserInfo fetchCompletionHandler:nil]; 292 | _apnsSlienceUserInfo = nil; 293 | } 294 | } 295 | 296 | /// 通知展示(iOS10及以上版本) 297 | /// @param center center 298 | /// @param notification notification 299 | /// @param completionHandler completionHandler 300 | - (void)GeTuiSdkNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification completionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { 301 | NSLog(@"\n>>>GTSDK willPresentNotification :%@", notification.request.content.userInfo); 302 | 303 | // 启动参数如果没有, 则设置为@{}, 避免后续被错误赋值 304 | if (!_launchNotification) { 305 | _launchNotification = @{}; 306 | } 307 | if (!_launchLocalNotification) { 308 | _launchLocalNotification = @{}; 309 | } 310 | 311 | 312 | // 根据APP需要,判断是否要提示用户Badge、Sound、Alert 313 | completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert); 314 | [_channel invokeMethod:@"onWillPresentNotification" arguments:notification.request.content.userInfo]; 315 | } 316 | 317 | - (void)GeTuiSdkDidReceiveNotification:(NSDictionary *)userInfo notificationCenter:(UNUserNotificationCenter *)center response:(UNNotificationResponse *)response fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { 318 | NSDate *time = response.notification.date; 319 | // NSDictionary *userInfo = response.notification.request.content.userInfo; 320 | NSLog(@"\n>>>GTSDK %@\nTime:%@\n%@", NSStringFromSelector(_cmd), time, userInfo); 321 | 322 | //注意: UIScene启动方式下, 反复多次点击通知冷启动App后杀死app,发现willConnectToSession不是每次冷启动都会调用的,可能因为复用机制而不走willConnectToSession方法。 323 | //此时系统会将apns参数通过GeTuiSdkDidReceiveNotification回调app, 让app也能拿到apns数据 324 | [GetuiflutPlugin checkLocalAndLaunchNotification:response.notification]; 325 | 326 | [_channel invokeMethod:@"onReceiveNotificationResponse" arguments:userInfo]; 327 | if (completionHandler) { 328 | completionHandler(UIBackgroundFetchResultNoData); 329 | } 330 | } 331 | 332 | - (void)GeTuiSdkNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(UNNotification *)notification { 333 | NSLog(@"\n>>>GTSDK openSettingsForNotification :%@", notification.request.content.userInfo); 334 | [_channel invokeMethod:@"onOpenSettingsForNotification" arguments:notification.request.content.userInfo]; 335 | } 336 | 337 | - (void)GeTuiSdkDidReceiveSlience:(NSDictionary *)userInfo fromGetui:(BOOL)fromGetui offLine:(BOOL)offLine appId:(NSString *)appId taskId:(NSString *)taskId msgId:(NSString *)msgId fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { 338 | NSString *payloadMsg = userInfo[@"payload"]; 339 | NSDictionary *payloadMsgDic = @{ @"taskId": taskId ?: @"", @"messageId": msgId ?: @"", @"payloadMsg" : payloadMsg, @"offLine" : @(offLine), @"fromGetui": @(fromGetui)}; 340 | NSLog(@"\n>>>GTSDK GeTuiSdkDidReceiveSlience:%@", payloadMsgDic); 341 | 342 | // 处理静默通知内容 343 | //[self updateLaunchNotification:userInfo]; 344 | 345 | [_channel invokeMethod:@"onReceivePayload" arguments:payloadMsgDic]; 346 | 347 | } 348 | 349 | /// MARK: - AppLink 350 | 351 | - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nonnull))restorationHandler { 352 | //系统用 NSUserActivityTypeBrowsingWeb 表示对应的 universal HTTP links 触发 353 | if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { 354 | NSURL* webUrl = userActivity.webpageURL; 355 | 356 | //处理个推APPLink回执统计 357 | //APPLink url 示例:https://link.applk.cn/getui?n=payload&p=mid, 其中 n=payload 字段存储下发的透传信息,可以根据透传内容进行业务操作。 358 | NSString *payload = [GeTuiSdk handleApplinkFeedback:webUrl]; 359 | if (payload) { 360 | NSLog(@"\n>>>GTSDK 个推APPLink中携带的透传payload信息: %@,URL : %@", payload, webUrl); 361 | //TODO:用户可根据具体 payload 进行业务处理 362 | [_channel invokeMethod:@"onAppLinkPayload" arguments:payload]; 363 | return YES; 364 | } 365 | } 366 | return NO; 367 | } 368 | 369 | 370 | /// MARK: - GTSDKfunction 371 | 372 | - (void)bindAlias:(FlutterMethodCall*)call result:(FlutterResult)result { 373 | NSDictionary *ConfigurationInfo = call.arguments; 374 | [GeTuiSdk bindAlias:ConfigurationInfo[@"alias"] andSequenceNum:ConfigurationInfo[@"aSn"]]; 375 | } 376 | 377 | - (void)unbindAlias:(FlutterMethodCall*)call result:(FlutterResult)result { 378 | NSDictionary *ConfigurationInfo = call.arguments; 379 | [GeTuiSdk unbindAlias:ConfigurationInfo[@"alias"] andSequenceNum:ConfigurationInfo[@"aSn"] andIsSelf:ConfigurationInfo[@"isSelf"]]; 380 | } 381 | 382 | - (void)setTag:(FlutterMethodCall*)call result:(FlutterResult)result { 383 | NSDictionary *ConfigurationInfo = call.arguments; 384 | [GeTuiSdk setTags:ConfigurationInfo[@"tags"] andSequenceNum:ConfigurationInfo[@"sn"]]; 385 | } 386 | 387 | - (void)setBadge:(FlutterMethodCall*)call result:(FlutterResult)result { 388 | NSDictionary *ConfigurationInfo = call.arguments; 389 | NSUInteger value = [ConfigurationInfo[@"badge"] integerValue]; 390 | [GeTuiSdk setBadge:value]; 391 | } 392 | 393 | - (void)setLocalBadge:(FlutterMethodCall*)call result:(FlutterResult)result { 394 | NSDictionary *ConfigurationInfo = call.arguments; 395 | NSUInteger value = [ConfigurationInfo[@"badge"] integerValue]; 396 | [UIApplication sharedApplication].applicationIconBadgeNumber = value; 397 | } 398 | 399 | - (void)setPushMode:(FlutterMethodCall*)call result:(FlutterResult)result { 400 | NSDictionary *ConfigurationInfo = call.arguments; 401 | BOOL value = [ConfigurationInfo[@"mode"] boolValue]; 402 | [GeTuiSdk setPushModeForOff:value]; 403 | } 404 | 405 | - (void)registerActivityToken:(FlutterMethodCall*)call result:(FlutterResult)result { 406 | NSDictionary *ConfigurationInfo = call.arguments; 407 | if ([GeTuiSdk respondsToSelector:@selector(registerActivityToken:)]) { 408 | //sdk<=3020 409 | [GeTuiSdk registerActivityToken:ConfigurationInfo[@"token"]]; 410 | return; 411 | } 412 | if ([GeTuiSdk respondsToSelector:@selector(registerLiveActivity:activityToken:sequenceNum:)]) { 413 | [GeTuiSdk registerLiveActivity:ConfigurationInfo[@"aid"] activityToken:ConfigurationInfo[@"token"] sequenceNum:ConfigurationInfo[@"sn"]]; 414 | } 415 | } 416 | 417 | - (void)registerPushToStartToken:(FlutterMethodCall*)call result:(FlutterResult)result { 418 | NSDictionary *ConfigurationInfo = call.arguments; 419 | if ([GeTuiSdk respondsToSelector:@selector(registerLiveActivity:pushToStartToken:sequenceNum:)]) { 420 | [GeTuiSdk registerLiveActivity:ConfigurationInfo[@"attribute"] pushToStartToken:ConfigurationInfo[@"token"] sequenceNum:ConfigurationInfo[@"sn"]]; 421 | } 422 | } 423 | 424 | - (void)registerDeviceToken:(FlutterMethodCall*)call result:(FlutterResult)result { 425 | NSDictionary *ConfigurationInfo = call.arguments; 426 | if ([GeTuiSdk respondsToSelector:@selector(registerDeviceToken:)]) { 427 | //sdk<=3020 428 | BOOL isSuccess = [GeTuiSdk registerDeviceToken:ConfigurationInfo[@"token"]]; 429 | NSLog(@"registerDeviceToken isSuccess %@ %@ " , @(isSuccess) , ConfigurationInfo[@"token"]); 430 | } 431 | } 432 | 433 | - (void)runBackgroundEnable:(FlutterMethodCall*)call result:(FlutterResult)result { 434 | NSDictionary *ConfigurationInfo = call.arguments; 435 | BOOL value = [ConfigurationInfo[@"enable"] boolValue]; 436 | NSLog(@"runBackgroundEnable %@",@(value)); 437 | [GeTuiSdk runBackgroundEnable:value]; 438 | } 439 | 440 | /** SDK设置推送模式回调 */ 441 | - (void)GeTuiSdkDidSetPushMode:(BOOL)isModeOff error:(NSError *)error { 442 | NSLog(@"\n>>>GTSDK GeTuiSdkDidSetPushMode isModeOff:%@ error:%@", @(isModeOff), error); 443 | NSDictionary *dic = @{@"result": @(isModeOff), @"error": error ? [error localizedDescription] : @""}; 444 | [_channel invokeMethod:@"onPushModeResult" arguments:dic]; 445 | } 446 | 447 | - (void)GeTuiSdkDidSetTagsAction:(NSString *)sequenceNum result:(BOOL)isSuccess error:(NSError *)aError { 448 | NSLog(@"\n>>>GTSDK GeTuiSdkDidSetTagsAction sn:%@ result:%@ error:%@", sequenceNum, @(isSuccess), aError); 449 | NSDictionary *dic = @{@"sn": sequenceNum?:@"", @"result": @(isSuccess), @"error": aError ? [aError localizedDescription] : @""}; 450 | [_channel invokeMethod:@"onSetTagResult" arguments:dic]; 451 | } 452 | 453 | - (void)GeTuiSdkDidAliasAction:(NSString *)action result:(BOOL)isSuccess sequenceNum:(NSString *)aSn error:(NSError *)aError { 454 | NSLog(@"\n>>>GTSDK GeTuiSdkDidAliasAction action: %@ sn:%@ result:%@ error:%@",[kGtResponseBindType isEqualToString:action] ? @"绑定" : @"解绑", aSn, @(isSuccess), aError); 455 | NSDictionary *dic = @{@"action": action, @"sn": aSn?:@"", @"result": @(isSuccess), @"error": aError ? [aError localizedDescription] : @""}; 456 | [_channel invokeMethod:@"onAliasResult" arguments:dic]; 457 | } 458 | 459 | - (void)GetuiSdkDidQueryTag:(NSArray *)tags sequenceNum:(NSString *)sn error:(NSError *)error { 460 | NSLog(@"\n>>>GTSDK GetuiSdkDidQueryTag : %@, SN : %@, error :%@", tags, sn, error); 461 | NSDictionary *dic = @{@"tags": tags, @"sn": sn?:@"", @"error": error ? [error localizedDescription] : @""}; 462 | [_channel invokeMethod:@"onQueryTagResult" arguments:dic]; 463 | } 464 | 465 | - (void)GeTuiSdkDidRegisterLiveActivity:(NSString *)sn result:(BOOL)isSuccess error:(NSError *)error { 466 | NSLog(@"\n>>>GTSDK GeTuiSdkDidRegisterLiveActivity SN : %@, success: %@, error :%@", sn, @(isSuccess), error); 467 | NSDictionary *dic = @{@"success" : @(isSuccess), @"sn": sn?:@"", @"error": error ? [error localizedDescription] : @""}; 468 | [_channel invokeMethod:@"onLiveActivityResult" arguments:dic]; 469 | } 470 | 471 | -(void)GeTuiSdkDidRegisterPushToStartToken:(NSString *)sn result:(BOOL)isSuccess error:(NSError *)error { 472 | NSLog(@"\n>>>GTSDK GeTuiSdkDidRegisterPushToStartToken SN : %@, success: %@, error :%@", sn, @(isSuccess), error); 473 | NSDictionary *dic = @{@"success" : @(isSuccess), @"sn": sn?:@"", @"error": error ? [error localizedDescription] : @""}; 474 | [_channel invokeMethod:@"onRegisterPushToStartTokenResult" arguments:dic]; 475 | } 476 | 477 | - (void)GeTuiSDkDidNotifySdkState:(SdkStatus)status { 478 | NSLog(@"[GetuiSdk Status]:%u", status); 479 | BOOL isOnLine = status == SdkStatusStarted; 480 | [_channel invokeMethod:@"onReceiveOnlineState" arguments:[NSString stringWithFormat:@"%@",@(isOnLine)]]; 481 | } 482 | 483 | 484 | 485 | //- (void)GeTuiSdkPopupDidShow:(NSDictionary *)info { 486 | // 487 | //} 488 | // 489 | //- (void)GeTuiSdkPopupDidClick:(NSDictionary *)info { 490 | // 491 | //} 492 | 493 | 494 | /// MARK: - Private 495 | 496 | - (NSString *)getHexStringForData:(NSData *)data { 497 | NSUInteger len = [data length]; 498 | char *chars = (char *) [data bytes]; 499 | NSMutableString *hexString = [[NSMutableString alloc] init]; 500 | for (NSUInteger i = 0; i < len; i++) { 501 | [hexString appendString:[NSString stringWithFormat:@"%0.2hhx", chars[i]]]; 502 | } 503 | return hexString; 504 | } 505 | 506 | 507 | 508 | 509 | 510 | ///// MARK: - VOIP接入 511 | 512 | /** 注册VOIP服务 */ 513 | //- (void)voipRegistration { 514 | // dispatch_queue_t mainQueue = dispatch_get_main_queue(); 515 | // PKPushRegistry *voipRegistry = [[PKPushRegistry alloc] initWithQueue:mainQueue]; 516 | // voipRegistry.delegate = self; 517 | // // Set the push type to VoIP 518 | // voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP]; 519 | //} 520 | // 521 | //// 实现 PKPushRegistryDelegate 协议方法 522 | // 523 | ///** 系统返回VOIPToken,并提交个推服务器 */ 524 | //- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type { 525 | // //向个推服务器注册 VoipToken 为了方便开发者,建议使用新方法 526 | // [GeTuiSdk registerVoipTokenCredentials:credentials.token]; 527 | // 528 | // NSString *token = [self getHexStringForData:credentials.token]; 529 | // NSLog(@"\n>>>GTSDK [VoipToken(NSString)]: %@", token); 530 | // [_channel invokeMethod:@"onRegisterVoipToken" arguments:token]; 531 | //} 532 | // 533 | ///** 接收VOIP推送中的payload进行业务逻辑处理(一般在这里调起本地通知实现连续响铃、接收视频呼叫请求等操作),并执行个推VOIP回执统计 */ 534 | //- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type { 535 | // // 个推VOIP回执统计 536 | // [GeTuiSdk handleVoipNotification:payload.dictionaryPayload]; 537 | // 538 | // // TODO:接受VOIP推送中的payload内容进行具体业务逻辑处理 539 | // NSLog(@"\n>>>GTSDK [Voip Payload]:%@,%@", payload, payload.dictionaryPayload); 540 | // [_channel invokeMethod:@"onReceiveVoipPayLoad" arguments:payload.dictionaryPayload]; 541 | //} 542 | 543 | 544 | - (void)pushLocalNotification:(NSString *)title { 545 | // 创建通知内容 546 | UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; 547 | content.title = @"测试通知"; 548 | content.body = @"长按以查看扩展"; 549 | content.userInfo = @{@"aa":@"b",@"c":@1}; 550 | content.categoryIdentifier = @"cate1"; 551 | content.sound = [UNNotificationSound defaultSound]; 552 | 553 | // 设置触发条件(5秒后触发) 554 | UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger 555 | triggerWithTimeInterval:5 556 | repeats:NO]; 557 | 558 | // 创建通知请求(使用 UUID 作为唯一标识符) 559 | NSUUID *uuid = [NSUUID UUID]; 560 | UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:[uuid UUIDString] 561 | content:content 562 | trigger:trigger]; 563 | 564 | // 添加通知请求到通知中心 565 | [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request 566 | withCompletionHandler:^(NSError * _Nullable error) { 567 | if (error) { 568 | NSLog(@"通知调度失败: %@", error); 569 | } else { 570 | NSLog(@"通知已调度"); 571 | } 572 | }]; 573 | } 574 | 575 | @end 576 | --------------------------------------------------------------------------------