├── .github └── workflows │ ├── flutter.yml │ └── release.yml ├── .gitignore ├── .pubignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android ├── .gitignore ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── zero │ │ └── flutter_gromore_ads │ │ ├── FlutterGromoreAdsPlugin.java │ │ ├── PluginDelegate.java │ │ ├── event │ │ ├── AdErrorEvent.java │ │ ├── AdEvent.java │ │ ├── AdEventAction.java │ │ ├── AdEventHandler.java │ │ └── AdRewardEvent.java │ │ ├── page │ │ ├── AdBannerView.java │ │ ├── AdSplashActivity.java │ │ ├── BaseAdPage.java │ │ ├── InterstitialPage.java │ │ └── NativeViewFactory.java │ │ └── utils │ │ ├── DataUtils.java │ │ ├── FileUtils.java │ │ ├── StatusBarUtils.java │ │ └── UIUtils.java │ └── res │ ├── layout │ └── activity_ad_splash.xml │ ├── mipmap-xxhdpi │ └── flutterads_logo.png │ ├── values │ └── themes.xml │ └── xml │ ├── bd_file_paths.xml │ ├── gdt_file_path.xml │ ├── mb_provider_paths.xml │ ├── network_config.xml │ ├── pangle_file_paths.xml │ ├── sigmob_provider_paths.xml │ └── tt_file_paths.xml ├── example ├── .gitignore ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ │ └── android_config_5216573.json │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── zero │ │ │ │ │ └── flutter_gromore_ads_example │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── flutterads_logo.png │ │ │ │ ├── flutterads_logo2.png │ │ │ │ └── ic_launcher.png │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── assets │ └── images │ │ └── img_pro.png ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── icon-1024.png │ │ │ ├── icon-20-ipad.png │ │ │ ├── icon-20@2x-ipad.png │ │ │ ├── icon-20@2x.png │ │ │ ├── icon-20@3x.png │ │ │ ├── icon-29-ipad.png │ │ │ ├── icon-29.png │ │ │ ├── icon-29@2x-ipad.png │ │ │ ├── icon-29@2x.png │ │ │ ├── icon-29@3x.png │ │ │ ├── icon-40.png │ │ │ ├── icon-40@2x.png │ │ │ ├── icon-40@3x.png │ │ │ ├── icon-60@2x.png │ │ │ ├── icon-60@3x.png │ │ │ ├── icon-76.png │ │ │ ├── icon-76@2x.png │ │ │ └── icon-83.5@2x.png │ │ ├── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage@1x.png │ │ │ ├── LaunchImage@2x.png │ │ │ └── LaunchImage@3x.png │ │ └── LaunchImage2.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage2@1x.png │ │ │ ├── LaunchImage2@2x.png │ │ │ └── LaunchImage2@3x.png │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── configs │ │ └── ios_config_5209496.json │ │ └── main.m ├── lib │ ├── main.dart │ └── pro_page.dart └── pubspec.yaml ├── go.mod ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── Event │ │ ├── FGMAdErrorEvent.h │ │ ├── FGMAdErrorEvent.m │ │ ├── FGMAdEvent.h │ │ └── FGMAdEvent.m │ ├── FGMGroMore.h │ ├── FlutterGromoreAdsPlugin.h │ ├── FlutterGromoreAdsPlugin.m │ └── Page │ │ ├── FGMAdBannerView.h │ │ ├── FGMAdBannerView.m │ │ ├── FGMBasePage.h │ │ ├── FGMBasePage.m │ │ ├── FGMInterstitialPage.h │ │ ├── FGMInterstitialPage.m │ │ ├── FGMNativeViewFactory.h │ │ ├── FGMNativeViewFactory.m │ │ ├── FGMSplashPage.h │ │ └── FGMSplashPage.m └── flutter_gromore_ads.podspec ├── lib ├── event │ ├── ad_error_event.dart │ ├── ad_event.dart │ ├── ad_event_action.dart │ ├── ad_event_handler.dart │ └── ad_reward_event.dart ├── flutter_gromore_ads.dart ├── flutter_gromore_ads_method_channel.dart ├── flutter_gromore_ads_platform_interface.dart └── view │ └── ad_banner_widget.dart ├── pubspec.yaml └── test └── flutter_gromore_ads_test.dart /.github/workflows/flutter.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | # This workflow is triggered on pushes to the repository. 4 | 5 | on: 6 | push: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | build: 12 | # This job will run on macos virtual machine 13 | runs-on: macos-13 14 | steps: 15 | 16 | # Setup Java environment in order to build the Android app. 17 | - uses: actions/checkout@v3 18 | - uses: actions/setup-java@v3 19 | with: 20 | distribution: 'temurin' 21 | java-version: '17' 22 | cache: 'gradle' 23 | # Setup the flutter environment. 24 | - uses: subosito/flutter-action@v2 25 | with: 26 | channel: 'stable' # 'dev', 'alpha', default to: 'stable' 27 | # flutter-version: '1.22.x' # you can also specify exact version of flutter 28 | 29 | # Get flutter dependencies. 30 | - run: flutter pub get 31 | 32 | # Check for any formatting issues in the code. 33 | - run: dart format --set-exit-if-changed . 34 | 35 | # Statically analyze the Dart code for any errors. 36 | - run: dart analyze . 37 | 38 | ##### 39 | # Build app 40 | ##### 41 | # Build apk. 42 | - run: cd example && flutter build apk 43 | # Build ios 44 | - run: cd example && flutter build ios --no-codesign 45 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*.*.*' 7 | 8 | jobs: 9 | create_release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v4 14 | 15 | - name: Extract version from tag 16 | id: extract_version 17 | run: | 18 | VERSION=${GITHUB_REF#refs/tags/v} 19 | echo "VERSION=$VERSION" >> $GITHUB_ENV 20 | 21 | - name: Read release notes 22 | id: release_notes 23 | run: | 24 | VERSION=${{ env.VERSION }} 25 | CHANGELOG=$(sed -n "/## $VERSION/,/^## /p" CHANGELOG.md | sed '$d' | tail -n +2) 26 | if [ -z "$CHANGELOG" ]; then 27 | echo "Release notes not found for version $VERSION" 28 | exit 1 29 | fi 30 | echo "RELEASE_NOTES<> $GITHUB_ENV 31 | echo "$CHANGELOG" >> $GITHUB_ENV 32 | echo "EOF" >> $GITHUB_ENV 33 | 34 | - name: Create GitHub release 35 | uses: softprops/action-gh-release@v2 36 | with: 37 | body: ${{ env.RELEASE_NOTES }} 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | shell/ 9 | .idea/ 10 | .vscode/ 11 | -------------------------------------------------------------------------------- /.pubignore: -------------------------------------------------------------------------------- 1 | example/images 2 | example/android 3 | example/ios 4 | shell/ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 3.2.0 2 | * 🚀🚀🚀 借助 [Gromore Pro版](https://flutterads.top/) 可以帮你大幅提升广告收益,发挥出最大的用户价值 🏆 3 | * 适配新版本 Flutter,兼容 Android namespace 4 | * 升级 iOS SDK 到 `v5.9.1.5` 5 | * 升级 Android SDK 到 `v5.9.2.8` 6 | * 插件迁移 `plugin_platform_interface` 方便更多平台的后续适配,比如鸿蒙 7 | * [🏆 Pro版](https://flutterads.top/) 支持【信息流、激励视频、测试助手、实时收益、预加载】 8 | 9 | ## 3.1.0 10 | * 🚀🚀🚀 借助 [Gromore Pro版](https://flutterads.top/) 可以帮你大幅提升广告收益,发挥出最大的用户价值 🏆 11 | * 升级 iOS SDK 到 `v5.9.1.2` 12 | * 升级 Android SDK 到 `v5.9.0.8` 13 | * 优化 iOS 开屏加载错误时的回调问题 14 | * 优化 Android 广告加载回调问题 15 | * 增加 CI/CD 流程,提高代码质量 16 | * [🏆 Pro版](https://flutterads.top/) 支持【信息流、激励视频、测试助手、实时收益、预加载】 17 | 18 | ## 3.0.0 19 | * 🚀🚀🚀 借助 [Gromore Pro版](https://flutterads.top/) 可以帮你大幅提升广告收益,发挥出最大的用户价值 🏆 20 | * [🏆 Pro版](https://flutterads.top/) 额外支持【信息流、激励视频、测试助手、实时收益、】 21 | * 适配 Flutter 新版本 22 | * 升级 Android&iOS SDK 版本 23 | 24 | ## 2.1.0 25 | * 升级 iOS SDK 到 `v5.6.0.9` 26 | * 升级 Android SDK 到 `v5.6.1.6` 27 | 28 | ## 2.0.0 29 | * 增加新广告支持 30 | ## 1.3.2 31 | * 增加 Banner 广告支持 32 | ## 1.3.1 33 | * 修复 iOS 11 以下系统奔溃问题 34 | ## 1.3.0 35 | * 开屏支持配置文件,优化配置获取率 36 | * SDK 版本升级到 `3.7.0.0` 37 | * 优化 Android 全面屏适配 38 | * 开屏去掉 `ButtonType` 支持 39 | 40 | 41 | ## 1.2.0 42 | * 优化 iOS 静态库编译问题 43 | * 升级 Android `pangle-adapter` 44 | * iOS 根据环境切换是否判断显示 Log 45 | 46 | ## 1.1.0 47 | * 升级 Gromore SDK 到 v'3.5.0.0' 48 | 49 | ## 1.0.0 50 | 51 | * 发布第一个版本 52 | * 支持开屏广告 53 | * 支持插屏广告 54 | * 支持全屏视频广告 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 FlutterAds 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

📱 Flutter GroMore Ads

2 |

【♻️ 持续更新】一款优质的 Flutter Gromore 聚合广告插件

3 |

4 | 5 |

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |

20 | 21 |

🏆 FlutterAds ~ 致力于构建优质的 Flutter 变现插件

22 |
23 | 24 | ## 🚀 核心功能 25 | 26 | - ✅ 开屏广告 27 | - ✅ 插屏广告 28 | - ✅ 横幅广告 29 | - 🏆 信息流(与产品信息流完没结合)[🚀 Pro 版](https://flutterads.top/) 30 | - 🏆 激励视频 (最高收益的广告形式)[🚀 Pro 版](https://flutterads.top/) 31 | - 🏆 二次激励(可有效提升收益)[🚀 Pro 版](https://flutterads.top/) 32 | - 💰 实时价格 eCPM(收益统计、实时分佣)[🚀 Pro 版](https://flutterads.top/) 33 | - 🦥 预缓存(预加载,极速展示,高填充率) [🚀 Pro 版](https://flutterads.top/) 34 | - 🧪 测试助手(精准测试,稳定上线)[🚀 Pro 版](https://flutterads.top/) 35 | - ♻️ 适配最新(紧跟官方最新 SDK)[🚀 Pro 版](https://flutterads.top/) 36 | 37 | ## 📱 下载体验 38 | 39 | 40 | > 回复 `Pro` 进行体验 41 | 42 | 43 | ## 📃 接入文档 44 | 45 | - [ 🎯 极速接入、快速体验、持续更新](https://flutterads.top/) 46 | 47 | - [ 💰 变现套件 = 【GroMore】+【AdSpark】+【AdContent】](https://flutterads.top/) 48 | 49 | 50 | ## 📌 FlutterAds 广告系列插件 — 打造 Flutter 应用的变现新机会 51 | 52 | 致力于构建优质的 Flutter 变现插件,选择我们提供的高效广告插件,专为 Flutter 开发者量身定制!我们不仅涵盖国内各大广告平台,还支持国际市场,助你快速打开全球创收之门。 53 | 54 | |插件|描述| 55 | |-|-| 56 | |[🏆 FlutterAds](https://flutterads.top/)| 🎉 提供全方位的广告解决方案,轻松集成,变现效益翻倍 🚀,助力你的 Flutter 应用赢得更多收益!| 57 | |[🌐 flutter_gromore_ads](https://github.com/FlutterAds/flutter_gromore_ads)|字节跳动、穿山甲、GroMore 广告平台一站式聚合,助力你在 Flutter 中轻松集成多种广告源!| 58 | |[🌐 flutter_pangle_ads](https://github.com/FlutterAds/flutter_pangle_ads)|专为 Flutter 打造的字节跳动、穿山甲广告插件,让你畅享流量和收益!| 59 | |[🚢 flutter_pangle_global_ads](https://github.com/FlutterAds/flutter_pangle_global_ads)|面向全球用户的字节跳动、穿山甲国际版广告插件,全面支持海外市场的广告变现!| 60 | |[🌐 flutter_qq_ads](https://github.com/FlutterAds/flutter_qq_ads)| 集成腾讯广告、广点通、优量汇,快速为 Flutter 应用打开更多广告渠道!| 61 | |[Ⓜ flutter_ohos_ads](https://github.com/FlutterAds/flutter_ohos_ads)|专为 HarmonyOS(鸿蒙系统)优化的广告变现插件,提供专属 Flutter 广告支持!| 62 | |[📡 flutter_adspark](https://github.com/FlutterAds/flutter_adspark)|强大的广告监测、增长分析与事件管理功能,助力你提升广告投放效果,精准归因!| 63 | |[🎬 flutter_adcontent_pro](https://github.com/FlutterAds/flutter_adcontent)|支持短剧、小视频内容的穿山甲内容输出插件,助力你轻松打造短剧类应用!| 64 | |[📚 flutter_novel_story_pro](https://github.com/FlutterAds/flutter_novel_story)|支持短故事、小说等内容输出,带有内置阅读器和聚合首页,助力你轻松打造小说类应用!| 65 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.zero.flutter_gromore_ads' 2 | version '1.0' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | mavenCentral() 8 | //GroMore SDK依赖 9 | maven { 10 | url "https://artifact.bytedance.com/repository/pangle" 11 | } 12 | //mintegral sdk依赖 13 | maven { 14 | url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_support/" 15 | } 16 | } 17 | 18 | dependencies { 19 | classpath 'com.android.tools.build:gradle:4.1.0' 20 | } 21 | } 22 | 23 | rootProject.allprojects { 24 | repositories { 25 | google() 26 | mavenCentral() 27 | //GroMore SDK依赖 28 | maven { 29 | url "https://artifact.bytedance.com/repository/pangle" 30 | } 31 | //mintegral sdk依赖 32 | maven { 33 | url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_support/" 34 | } 35 | } 36 | } 37 | 38 | apply plugin: 'com.android.library' 39 | 40 | android { 41 | if (project.android.hasProperty("namespace")) { 42 | namespace = "com.zero.flutter_gromore_ads" 43 | } 44 | compileSdk 31 45 | compileOptions { 46 | sourceCompatibility JavaVersion.VERSION_1_8 47 | targetCompatibility JavaVersion.VERSION_1_8 48 | } 49 | 50 | defaultConfig { 51 | minSdkVersion 19 52 | } 53 | } 54 | 55 | dependencies { 56 | implementation 'androidx.appcompat:appcompat:1.3.1' 57 | implementation 'com.google.android.material:material:1.3.0' 58 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' 59 | //GroMore_sdk 60 | implementation "com.pangle.cn:mediation-sdk:5.9.2.8" //融合SDK 61 | } 62 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /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-6.7-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_gromore_ads' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 22 | 23 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/FlutterGromoreAdsPlugin.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 6 | import io.flutter.embedding.engine.plugins.activity.ActivityAware; 7 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; 8 | import io.flutter.plugin.common.EventChannel; 9 | import io.flutter.plugin.common.MethodCall; 10 | import io.flutter.plugin.common.MethodChannel; 11 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 12 | import io.flutter.plugin.common.MethodChannel.Result; 13 | 14 | /** FlutterGromoreAdsPlugin */ 15 | public class FlutterGromoreAdsPlugin implements FlutterPlugin, ActivityAware { 16 | // 方法通道 17 | private MethodChannel methodChannel; 18 | // 事件通道 19 | private EventChannel eventChannel; 20 | // 插件代理 21 | private PluginDelegate delegate; 22 | // 插件连接器 23 | private FlutterPluginBinding bind; 24 | 25 | @Override 26 | public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { 27 | bind = flutterPluginBinding; 28 | // 初始化方法通道和事件通道 29 | methodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_gromore_ads"); 30 | eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_gromore_ads_event"); 31 | } 32 | 33 | 34 | 35 | @Override 36 | public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { 37 | // 解除方法通道和事件通道 38 | methodChannel.setMethodCallHandler(null); 39 | eventChannel.setStreamHandler(null); 40 | } 41 | 42 | 43 | @Override 44 | public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { 45 | this.delegate = new PluginDelegate(binding.getActivity(), bind); 46 | methodChannel.setMethodCallHandler(delegate); 47 | eventChannel.setStreamHandler(delegate); 48 | this.delegate.registerBannerView(); 49 | } 50 | 51 | @Override 52 | public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { 53 | onAttachedToActivity(binding); 54 | } 55 | 56 | 57 | @Override 58 | public void onDetachedFromActivityForConfigChanges() { 59 | onDetachedFromActivity(); 60 | } 61 | 62 | 63 | @Override 64 | public void onDetachedFromActivity() { 65 | this.delegate = null; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/PluginDelegate.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.text.TextUtils; 6 | import android.util.Log; 7 | 8 | import androidx.annotation.NonNull; 9 | 10 | import com.bytedance.sdk.openadsdk.TTAdConfig; 11 | import com.bytedance.sdk.openadsdk.TTAdSdk; 12 | import com.bytedance.sdk.openadsdk.TTCustomController; 13 | import com.bytedance.sdk.openadsdk.mediation.init.MediationConfig; 14 | import com.bytedance.sdk.openadsdk.mediation.init.MediationPrivacyConfig; 15 | import com.zero.flutter_gromore_ads.page.AdSplashActivity; 16 | import com.zero.flutter_gromore_ads.page.InterstitialPage; 17 | import com.zero.flutter_gromore_ads.page.NativeViewFactory; 18 | import com.zero.flutter_gromore_ads.utils.FileUtils; 19 | 20 | import org.json.JSONException; 21 | import org.json.JSONObject; 22 | 23 | import io.flutter.BuildConfig; 24 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 25 | import io.flutter.plugin.common.EventChannel; 26 | import io.flutter.plugin.common.MethodCall; 27 | import io.flutter.plugin.common.MethodChannel; 28 | 29 | /// 插件代理 30 | public class PluginDelegate implements MethodChannel.MethodCallHandler, EventChannel.StreamHandler { 31 | private final String TAG = PluginDelegate.class.getSimpleName(); 32 | // Flutter 插件绑定对象 33 | public FlutterPlugin.FlutterPluginBinding bind; 34 | // 当前 Activity 35 | public Activity activity; 36 | // 返回通道 37 | private MethodChannel.Result result; 38 | // 事件通道 39 | private EventChannel.EventSink eventSink; 40 | // 插件代理对象 41 | private static PluginDelegate _instance; 42 | 43 | public static PluginDelegate getInstance() { 44 | return _instance; 45 | } 46 | 47 | // Banner View 48 | public static final String KEY_BANNER_VIEW = "flutter_gromore_ads_banner"; 49 | // 广告参数 50 | public static final String KEY_POSID = "posId"; 51 | // logo 参数 52 | public static final String KEY_LOGO = "logo"; 53 | // timeout 参数 54 | public static final String KEY_TIMEOUT = "timeout"; 55 | 56 | /** 57 | * 插件代理构造函数构造函数 58 | * 59 | * @param activity Activity 60 | * @param pluginBinding FlutterPluginBinding 61 | */ 62 | public PluginDelegate(Activity activity, FlutterPlugin.FlutterPluginBinding pluginBinding) { 63 | this.activity = activity; 64 | this.bind = pluginBinding; 65 | _instance = this; 66 | } 67 | 68 | /** 69 | * 方法通道调用 70 | * 71 | * @param call 方法调用对象 72 | * @param result 回调结果对象 73 | */ 74 | @Override 75 | public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { 76 | String method = call.method; 77 | Log.d(TAG, "MethodChannel onMethodCall method:" + method + " arguments:" + call.arguments); 78 | if ("requestPermissionIfNecessary".equals(method)) { 79 | requestPermissionIfNecessary(call, result); 80 | } else if ("initAd".equals(method)) { 81 | initAd(call, result); 82 | } else if ("showSplashAd".equals(method)) { 83 | showSplashAd(call, result); 84 | } else if ("showInterstitialAd".equals(method)) { 85 | showInterstitialAd(call, result); 86 | } else { 87 | result.notImplemented(); 88 | } 89 | } 90 | 91 | /** 92 | * 建立事件通道监听 93 | * 94 | * @param arguments 参数 95 | * @param events 事件回调对象 96 | */ 97 | @Override 98 | public void onListen(Object arguments, EventChannel.EventSink events) { 99 | Log.d(TAG, "EventChannel onListen arguments:" + arguments); 100 | eventSink = events; 101 | } 102 | 103 | /** 104 | * 取消事件通道监听 105 | * 106 | * @param arguments 参数 107 | */ 108 | @Override 109 | public void onCancel(Object arguments) { 110 | Log.d(TAG, "EventChannel onCancel"); 111 | eventSink = null; 112 | } 113 | 114 | /** 115 | * 添加事件 116 | * 117 | * @param event 事件 118 | */ 119 | public void addEvent(Object event) { 120 | if (eventSink != null) { 121 | Log.d(TAG, "EventChannel addEvent event:" + event.toString()); 122 | eventSink.success(event); 123 | } 124 | } 125 | 126 | /** 127 | * 展示 Banner 广告 128 | */ 129 | public void registerBannerView() { 130 | bind.getPlatformViewRegistry() 131 | .registerViewFactory(KEY_BANNER_VIEW, new NativeViewFactory(KEY_BANNER_VIEW, this)); 132 | } 133 | 134 | /** 135 | * 请求权限 136 | * 137 | * @param call MethodCall 138 | * @param result Result 139 | */ 140 | public void requestPermissionIfNecessary(MethodCall call, MethodChannel.Result result) { 141 | TTAdSdk.getMediationManager().requestPermissionIfNecessary(activity); 142 | result.success(true); 143 | } 144 | 145 | /** 146 | * 初始化广告 147 | * 148 | * @param call MethodCall 149 | * @param result Result 150 | */ 151 | public void initAd(MethodCall call, final MethodChannel.Result result) { 152 | String appId = call.argument("appId"); 153 | int limitPersonalAds = call.argument("limitPersonalAds"); 154 | 155 | // 构建基础配置 156 | TTAdConfig.Builder configBuilder = new TTAdConfig.Builder() 157 | .appId(appId) 158 | .useMediation(true) 159 | .debug(BuildConfig.DEBUG) 160 | .supportMultiProcess(false); 161 | // 构建配置 162 | TTAdConfig gmPangleOption = configBuilder 163 | .customController(getTTCustomController(limitPersonalAds == 0)) 164 | .build(); 165 | // 初始化 SDK 166 | TTAdSdk.init(activity.getApplicationContext(),gmPangleOption); 167 | TTAdSdk.start(new TTAdSdk.Callback() { 168 | @Override 169 | public void success() { 170 | result.success(TTAdSdk.isInitSuccess()); 171 | } 172 | 173 | @Override 174 | public void fail(int i, String s) { 175 | result.success(false); 176 | Log.e(TAG, "TTAdSdk init start Error code:"+i+" msg:"+s); 177 | } 178 | }); 179 | } 180 | 181 | 182 | private TTCustomController getTTCustomController(boolean limitPersonalAds) { 183 | return new TTCustomController() { 184 | 185 | @Override 186 | public boolean isCanUseWifiState() { 187 | return super.isCanUseWifiState(); 188 | } 189 | 190 | @Override 191 | public String getMacAddress() { 192 | return super.getMacAddress(); 193 | } 194 | 195 | @Override 196 | public boolean isCanUseWriteExternal() { 197 | return super.isCanUseWriteExternal(); 198 | } 199 | 200 | @Override 201 | public String getDevOaid() { 202 | return super.getDevOaid(); 203 | } 204 | 205 | @Override 206 | public boolean isCanUseAndroidId() { 207 | return super.isCanUseAndroidId(); 208 | } 209 | 210 | @Override 211 | public String getAndroidId() { 212 | return super.getAndroidId(); 213 | } 214 | 215 | @Override 216 | public MediationPrivacyConfig getMediationPrivacyConfig() { 217 | return new MediationPrivacyConfig() { 218 | 219 | @Override 220 | public boolean isLimitPersonalAds() { 221 | return limitPersonalAds; 222 | } 223 | 224 | @Override 225 | public boolean isProgrammaticRecommend() { 226 | return limitPersonalAds; 227 | } 228 | }; 229 | } 230 | 231 | @Override 232 | public boolean isCanUsePermissionRecordAudio() { 233 | return super.isCanUsePermissionRecordAudio(); 234 | } 235 | }; 236 | } 237 | 238 | /** 239 | * 显示开屏广告 240 | * 241 | * @param call MethodCall 242 | * @param result Result 243 | */ 244 | public void showSplashAd(MethodCall call, MethodChannel.Result result) { 245 | String posId = call.argument(KEY_POSID); 246 | String logo = call.argument(KEY_LOGO); 247 | double timeout = call.argument(KEY_TIMEOUT); 248 | Intent intent = new Intent(activity, AdSplashActivity.class); 249 | intent.putExtra(KEY_POSID, posId); 250 | intent.putExtra(KEY_LOGO, logo); 251 | intent.putExtra(KEY_TIMEOUT, timeout); 252 | activity.startActivity(intent); 253 | // 设置进入动画 254 | activity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 255 | result.success(true); 256 | } 257 | 258 | /** 259 | * 显示插屏广告 260 | * 261 | * @param call MethodCall 262 | * @param result Result 263 | */ 264 | public void showInterstitialAd(MethodCall call, MethodChannel.Result result) { 265 | InterstitialPage adPage = new InterstitialPage(); 266 | adPage.showAd(activity, call); 267 | result.success(true); 268 | } 269 | 270 | } 271 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/event/AdErrorEvent.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.event; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 广告错误事件 7 | */ 8 | public class AdErrorEvent extends AdEvent { 9 | // 错误码 10 | private final int errCode; 11 | // 错误信息 12 | private final String errMsg; 13 | 14 | // 错误事件实体 15 | public AdErrorEvent(String adId, int errCode, String errMsg) { 16 | super(adId, AdEventAction.onAdError); 17 | this.errCode = errCode; 18 | this.errMsg = errMsg; 19 | } 20 | 21 | /** 22 | * 重写 toMap 方法 23 | * 24 | * @return 返回错误事件的map 25 | */ 26 | @Override 27 | public HashMap toMap() { 28 | HashMap newMap = super.toMap(); 29 | newMap.put("errCode", errCode); 30 | newMap.put("errMsg", errMsg); 31 | return newMap; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/event/AdEvent.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.event; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 广告事件 7 | */ 8 | public class AdEvent { 9 | // 广告 id 10 | private final String adId; 11 | // 操作 12 | private final String action; 13 | 14 | public AdEvent(String adId, String action) { 15 | this.adId = adId; 16 | this.action = action; 17 | } 18 | 19 | /** 20 | * 转换为 Map 方面传输 21 | * 22 | * @return 转换后的 Map 对象 23 | */ 24 | public HashMap toMap() { 25 | HashMap map = new HashMap(); 26 | map.put("adId", adId); 27 | map.put("action", action); 28 | return map; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/event/AdEventAction.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.event; 2 | 3 | /** 4 | * 广告事件操作 5 | */ 6 | public class AdEventAction { 7 | // 广告错误 8 | public static final String onAdError = "onAdError"; 9 | // 广告加载成功 10 | public static final String onAdLoaded = "onAdLoaded"; 11 | // 广告填充 12 | public static final String onAdPresent = "onAdPresent"; 13 | // 广告曝光 14 | public static final String onAdExposure = "onAdExposure"; 15 | // 广告关闭(计时结束或者用户点击关闭) 16 | public static final String onAdClosed = "onAdClosed"; 17 | // 广告点击 18 | public static final String onAdClicked = "onAdClicked"; 19 | // 广告跳过 20 | public static final String onAdSkip = "onAdSkip"; 21 | // 广告播放或计时完毕 22 | public static final String onAdComplete = "onAdComplete"; 23 | // 获得广告激励 24 | public static final String onAdReward = "onAdReward"; 25 | } 26 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/event/AdEventHandler.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.event; 2 | 3 | import com.zero.flutter_gromore_ads.PluginDelegate; 4 | 5 | /** 6 | * 广告事件处理类 7 | */ 8 | public class AdEventHandler { 9 | // 广告事件处理对象 10 | private static volatile AdEventHandler _instance; 11 | 12 | /** 13 | * 获取广告事件处理类 14 | * 15 | * @return 广告事件处理对象 16 | */ 17 | public static AdEventHandler getInstance() { 18 | if (_instance == null) { 19 | synchronized (AdEventHandler.class) { 20 | _instance = new AdEventHandler(); 21 | } 22 | } 23 | return _instance; 24 | } 25 | 26 | /** 27 | * 添加广告事件 28 | * 29 | * @param event 广告事件 30 | */ 31 | public void sendEvent(AdEvent event) { 32 | if (event != null) { 33 | PluginDelegate.getInstance().addEvent(event.toMap()); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/event/AdRewardEvent.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.event; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 广告激励事件 7 | */ 8 | public class AdRewardEvent extends AdEvent { 9 | // 奖励是否有效 10 | private final boolean rewardVerify; 11 | // 奖励数量 12 | private final int rewardAmount; 13 | // 奖励名称 14 | private final String rewardName; 15 | // 错误码 16 | private final int errCode; 17 | // 错误信息 18 | private final String errMsg; 19 | // 自定义信息 20 | private final String customData; 21 | // 用户信息 22 | private final String userId; 23 | 24 | public AdRewardEvent(String adId, boolean rewardVerify, int rewardAmount, String rewardName, int errCode, String errMsg, String customData, String userId) { 25 | super(adId, AdEventAction.onAdReward); 26 | this.rewardVerify = rewardVerify; 27 | this.rewardAmount = rewardAmount; 28 | this.rewardName = rewardName; 29 | this.errCode = errCode; 30 | this.errMsg = errMsg; 31 | this.customData = customData; 32 | this.userId = userId; 33 | } 34 | 35 | @Override 36 | public HashMap toMap() { 37 | HashMap newMap = super.toMap(); 38 | newMap.put("rewardVerify", rewardVerify); 39 | newMap.put("rewardAmount", rewardAmount); 40 | newMap.put("rewardName", rewardName); 41 | newMap.put("errCode", errCode); 42 | newMap.put("errMsg", errMsg); 43 | newMap.put("customData", customData); 44 | newMap.put("userId", userId); 45 | return newMap; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/page/AdBannerView.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.page; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | import android.view.View; 6 | import android.widget.FrameLayout; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.annotation.Nullable; 10 | 11 | 12 | import com.bytedance.sdk.openadsdk.AdSlot; 13 | import com.bytedance.sdk.openadsdk.TTAdDislike; 14 | import com.bytedance.sdk.openadsdk.TTAdNative; 15 | import com.bytedance.sdk.openadsdk.TTNativeExpressAd; 16 | import com.zero.flutter_gromore_ads.PluginDelegate; 17 | import com.zero.flutter_gromore_ads.event.AdEventAction; 18 | import com.zero.flutter_gromore_ads.utils.UIUtils; 19 | 20 | import java.util.List; 21 | import java.util.Map; 22 | 23 | import io.flutter.plugin.common.MethodCall; 24 | import io.flutter.plugin.platform.PlatformView; 25 | 26 | /** 27 | * Banner 广告 View 28 | */ 29 | class AdBannerView extends BaseAdPage implements PlatformView, TTAdNative.NativeExpressAdListener, TTNativeExpressAd.ExpressAdInteractionListener, TTAdDislike.DislikeInteractionCallback { 30 | private final String TAG = AdBannerView.class.getSimpleName(); 31 | @NonNull 32 | private final FrameLayout frameLayout; 33 | private final PluginDelegate pluginDelegate; 34 | private final int id; 35 | private TTNativeExpressAd bad; 36 | 37 | 38 | AdBannerView(@NonNull Context context, int id, @Nullable Map creationParams, PluginDelegate pluginDelegate) { 39 | this.id = id; 40 | this.pluginDelegate = pluginDelegate; 41 | frameLayout = new FrameLayout(context); 42 | MethodCall call = new MethodCall("AdBannerView", creationParams); 43 | showAd(this.pluginDelegate.activity, call); 44 | } 45 | 46 | @NonNull 47 | @Override 48 | public View getView() { 49 | return frameLayout; 50 | } 51 | 52 | @Override 53 | public void dispose() { 54 | disposeAd(); 55 | } 56 | 57 | @Override 58 | public void loadAd(@NonNull MethodCall call) { 59 | // 获取请求模板广告素材的尺寸 60 | int expressViewWidth = call.argument("width"); 61 | int expressViewHeight = call.argument("height"); 62 | this.adslot = new AdSlot.Builder() 63 | .setCodeId(posId) 64 | .setImageAcceptedSize(UIUtils.dp2px(activity,expressViewWidth), UIUtils.dp2px(activity,expressViewHeight)) 65 | .build(); 66 | // 加载广告 67 | adNativeLoader.loadBannerExpressAd(adslot, this); 68 | } 69 | 70 | /** 71 | * 销毁广告 72 | */ 73 | private void disposeAd() { 74 | frameLayout.removeAllViews(); 75 | if (bad != null) { 76 | bad.setExpressInteractionListener(null); 77 | bad.destroy(); 78 | } 79 | } 80 | 81 | @Override 82 | public void onError(int i, String s) { 83 | Log.e(TAG, "onError code:" + i + " msg:" + s); 84 | sendErrorEvent(i, s); 85 | disposeAd(); 86 | } 87 | 88 | @Override 89 | public void onNativeExpressAdLoad(List list) { 90 | if (list == null || list.size() == 0) { 91 | Log.e(TAG, "onNativeExpressAdLoad list is null or size is 0"); 92 | return; 93 | } 94 | bad = list.get(0); 95 | bad.setExpressInteractionListener(this); 96 | bad.setDislikeCallback(activity, this); 97 | bad.render(); 98 | } 99 | 100 | @Override 101 | public void onAdClicked(View view, int i) { 102 | Log.i(TAG, "onAdClicked"); 103 | // 添加广告事件 104 | sendEvent(AdEventAction.onAdClicked); 105 | } 106 | 107 | @Override 108 | public void onAdShow(View view, int i) { 109 | Log.i(TAG, "onAdShow"); 110 | // 添加广告事件 111 | sendEvent(AdEventAction.onAdExposure); 112 | } 113 | 114 | @Override 115 | public void onRenderFail(View view, String s, int i) { 116 | Log.e(TAG, "onRenderFail code:" + i + " msg:" + s); 117 | sendErrorEvent(i, s); 118 | disposeAd(); 119 | } 120 | 121 | @Override 122 | public void onRenderSuccess(View view, float v, float v1) { 123 | Log.i(TAG, "onRenderSuccess"); 124 | if (bad != null) { 125 | frameLayout.removeAllViews(); 126 | frameLayout.addView(bad.getExpressAdView()); 127 | // 添加广告事件 128 | sendEvent(AdEventAction.onAdPresent); 129 | }else{ 130 | disposeAd(); 131 | } 132 | } 133 | 134 | @Override 135 | public void onShow() { 136 | Log.i(TAG, "Dislike onShow"); 137 | } 138 | 139 | @Override 140 | public void onSelected(int i, String s, boolean b) { 141 | Log.i(TAG, "Dislike onSelected"); 142 | // 添加广告事件 143 | disposeAd(); 144 | sendEvent(AdEventAction.onAdClosed); 145 | } 146 | 147 | @Override 148 | public void onCancel() { 149 | Log.i(TAG, "Dislike onCancel"); 150 | } 151 | } -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/page/AdSplashActivity.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.page; 2 | 3 | import android.os.Bundle; 4 | import android.text.TextUtils; 5 | import android.util.Log; 6 | import android.view.KeyEvent; 7 | import android.view.View; 8 | import android.widget.FrameLayout; 9 | 10 | import androidx.annotation.NonNull; 11 | import androidx.appcompat.app.AppCompatActivity; 12 | import androidx.appcompat.widget.AppCompatImageView; 13 | 14 | import com.bytedance.sdk.openadsdk.AdSlot; 15 | import com.bytedance.sdk.openadsdk.CSJAdError; 16 | import com.bytedance.sdk.openadsdk.CSJSplashAd; 17 | import com.bytedance.sdk.openadsdk.TTAdNative; 18 | import com.bytedance.sdk.openadsdk.TTAdSdk; 19 | import com.zero.flutter_gromore_ads.PluginDelegate; 20 | import com.zero.flutter_gromore_ads.R; 21 | import com.zero.flutter_gromore_ads.event.AdErrorEvent; 22 | import com.zero.flutter_gromore_ads.event.AdEvent; 23 | import com.zero.flutter_gromore_ads.event.AdEventAction; 24 | import com.zero.flutter_gromore_ads.event.AdEventHandler; 25 | import com.zero.flutter_gromore_ads.utils.StatusBarUtils; 26 | import com.zero.flutter_gromore_ads.utils.UIUtils; 27 | 28 | /** 29 | * 开屏广告 30 | */ 31 | public class AdSplashActivity extends AppCompatActivity implements TTAdNative.CSJSplashAdListener,CSJSplashAd.SplashAdListener { 32 | private final String TAG = AdSplashActivity.class.getSimpleName(); 33 | // 广告容器 34 | private FrameLayout ad_container; 35 | // 自定义品牌 logo 36 | private AppCompatImageView ad_logo; 37 | // 广告位 id 38 | private String posId; 39 | // 开屏广告 40 | private CSJSplashAd gmSplashAd; 41 | 42 | 43 | @Override 44 | protected void onCreate(Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | UIUtils.hideBottomUIMenu(this); 47 | StatusBarUtils.setTranslucent(this); 48 | setContentView(R.layout.activity_ad_splash); 49 | initView(); 50 | initData(); 51 | } 52 | 53 | /** 54 | * 初始化View 55 | */ 56 | private void initView() { 57 | ad_container = findViewById(R.id.splash_ad_container); 58 | ad_logo = findViewById(R.id.splash_ad_logo); 59 | } 60 | 61 | /** 62 | * 初始化数据 63 | */ 64 | private void initData() { 65 | 66 | // 获取参数 67 | posId = getIntent().getStringExtra(PluginDelegate.KEY_POSID); 68 | String logo = getIntent().getStringExtra(PluginDelegate.KEY_LOGO); 69 | double timeout = getIntent().getDoubleExtra(PluginDelegate.KEY_TIMEOUT, 3.5); 70 | int absTimeout = (int) (timeout * 1000); 71 | // 判断是否有 Logo 72 | boolean hasLogo = !TextUtils.isEmpty(logo); 73 | if (hasLogo) { 74 | // 加载 logo 75 | int resId = getMipmapId(logo); 76 | hasLogo = resId > 0; 77 | if (hasLogo) { 78 | ad_logo.setVisibility(View.VISIBLE); 79 | ad_logo.setImageResource(resId); 80 | } else { 81 | Log.e(TAG, "Logo 名称不匹配或不在 mipmap 文件夹下,展示全屏"); 82 | } 83 | } 84 | int width = (int) UIUtils.getScreenWidthInPx(this); 85 | int height = UIUtils.getRealHeight(this); 86 | // 判断最终的 Logo 是否显示 87 | if (!hasLogo) { 88 | ad_logo.setVisibility(View.GONE); 89 | } else { 90 | // 显示 Logo 高度去掉 Logo 的高度 91 | height = height - ad_logo.getLayoutParams().height; 92 | } 93 | // 创建开屏广告 94 | AdSlot adSlot = new AdSlot.Builder() 95 | .setCodeId(posId) 96 | .setImageAcceptedSize(width, height) // 单位是px 97 | .build(); 98 | // 加载广告 99 | TTAdSdk.getAdManager().createAdNative(this).loadSplashAd(adSlot,this,absTimeout); 100 | } 101 | 102 | /** 103 | * 完成广告,退出开屏页面 104 | */ 105 | private void finishPage() { 106 | finish(); 107 | // 设置退出动画 108 | overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 109 | // 销毁 110 | if (gmSplashAd != null&&gmSplashAd.getMediationManager()!=null) { 111 | gmSplashAd.setSplashAdListener(null); 112 | gmSplashAd.getMediationManager().destroy(); 113 | gmSplashAd = null; 114 | } 115 | } 116 | 117 | /** 118 | * 开屏页一定要禁止用户对返回按钮的控制,否则将可能导致用户手动退出了App而广告无法正常曝光和计费 119 | */ 120 | @Override 121 | public boolean onKeyDown(int keyCode, KeyEvent event) { 122 | if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME) { 123 | return true; 124 | } 125 | return super.onKeyDown(keyCode, event); 126 | } 127 | 128 | /** 129 | * 获取图片资源的id 130 | * 131 | * @param resName 资源名称,不带后缀 132 | * @return 返回资源id 133 | */ 134 | private int getMipmapId(String resName) { 135 | return getResources().getIdentifier(resName, "mipmap", getPackageName()); 136 | } 137 | 138 | 139 | @Override 140 | public void onSplashLoadSuccess(CSJSplashAd csjSplashAd) { 141 | Log.d(TAG, "onSplashLoadSuccess"); 142 | AdEventHandler.getInstance().sendEvent(new AdEvent(this.posId, AdEventAction.onAdLoaded)); 143 | } 144 | 145 | @Override 146 | public void onSplashLoadFail(CSJAdError adError) { 147 | Log.e(TAG, "onSplashLoadFail code:" + adError.getCode() + " msg:" + adError.getMsg()); 148 | AdEventHandler.getInstance().sendEvent(new AdErrorEvent(this.posId, adError.getCode(), adError.getMsg())); 149 | finishPage(); 150 | } 151 | 152 | @Override 153 | public void onSplashRenderSuccess(CSJSplashAd csjSplashAd) { 154 | //获取SplashView 155 | if (this.isFinishing()) { 156 | finishPage(); 157 | return; 158 | } 159 | gmSplashAd=csjSplashAd; 160 | csjSplashAd.setSplashAdListener(this); 161 | View splashView = csjSplashAd.getSplashView(); 162 | if (splashView == null) { 163 | finishPage(); 164 | return; 165 | } 166 | UIUtils.removeFromParent(splashView); 167 | ad_container.removeAllViews(); 168 | ad_container.addView(splashView); 169 | // 加载事件 170 | AdEventHandler.getInstance().sendEvent(new AdEvent(this.posId, AdEventAction.onAdPresent)); 171 | } 172 | 173 | @Override 174 | public void onSplashRenderFail(CSJSplashAd csjSplashAd, CSJAdError adError) { 175 | Log.e(TAG, "onSplashRenderFail code:" + adError.getCode() + " msg:" + adError.getMsg()); 176 | AdEventHandler.getInstance().sendEvent(new AdErrorEvent(this.posId, adError.getCode(), adError.getMsg())); 177 | } 178 | 179 | @Override 180 | public void onSplashAdShow(CSJSplashAd csjSplashAd) { 181 | Log.d(TAG, "onAdShow"); 182 | AdEventHandler.getInstance().sendEvent(new AdEvent(this.posId, AdEventAction.onAdExposure)); 183 | } 184 | 185 | @Override 186 | public void onSplashAdClick(CSJSplashAd csjSplashAd) { 187 | Log.d(TAG, "onAdClicked"); 188 | AdEventHandler.getInstance().sendEvent(new AdEvent(this.posId, AdEventAction.onAdClicked)); 189 | finishPage(); 190 | } 191 | 192 | @Override 193 | public void onSplashAdClose(CSJSplashAd csjSplashAd, int i) { 194 | Log.d(TAG, "onSplashAdClose"); 195 | AdEventHandler.getInstance().sendEvent(new AdEvent(this.posId, AdEventAction.onAdClosed)); 196 | finishPage(); 197 | } 198 | } -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/page/BaseAdPage.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.page; 2 | 3 | import static com.zero.flutter_gromore_ads.PluginDelegate.KEY_POSID; 4 | 5 | import android.app.Activity; 6 | 7 | import com.bytedance.sdk.openadsdk.AdSlot; 8 | import com.bytedance.sdk.openadsdk.TTAdNative; 9 | import com.bytedance.sdk.openadsdk.TTAdSdk; 10 | import com.zero.flutter_gromore_ads.event.AdErrorEvent; 11 | import com.zero.flutter_gromore_ads.event.AdEvent; 12 | import com.zero.flutter_gromore_ads.event.AdEventHandler; 13 | 14 | import io.flutter.plugin.common.MethodCall; 15 | 16 | /** 17 | * 基础广告页面 18 | */ 19 | public abstract class BaseAdPage { 20 | // 上下文 21 | protected Activity activity; 22 | // 广告位 id 23 | protected String posId; 24 | // 广告配置 25 | protected AdSlot adslot; 26 | // 广告加载器 27 | protected TTAdNative adNativeLoader; 28 | 29 | /** 30 | * 显示广告 31 | * 32 | * @param activity 上下文 33 | * @param call 方法调用 34 | */ 35 | public void showAd(Activity activity, MethodCall call) { 36 | this.activity = activity; 37 | this.posId = call.argument(KEY_POSID); 38 | this.adNativeLoader= TTAdSdk.getAdManager().createAdNative(activity); 39 | loadAd(call); 40 | } 41 | 42 | /** 43 | * 加载广告 44 | * 45 | * @param call 方法调用 46 | */ 47 | public abstract void loadAd(MethodCall call); 48 | 49 | /** 50 | * 发送广告事件 51 | * 52 | * @param event 广告事件 53 | */ 54 | protected void sendEvent(AdEvent event) { 55 | AdEventHandler.getInstance().sendEvent(event); 56 | } 57 | 58 | /** 59 | * 发送广告事件 60 | * 61 | * @param action 操作 62 | */ 63 | protected void sendEvent(String action) { 64 | sendEvent(new AdEvent(posId, action)); 65 | } 66 | 67 | /** 68 | * 发送错误事件 69 | * 70 | * @param errCode 错误码 71 | * @param errMsg 错误事件 72 | */ 73 | protected void sendErrorEvent(int errCode, String errMsg) { 74 | sendEvent(new AdErrorEvent(posId, errCode, errMsg)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/page/InterstitialPage.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.page; 2 | 3 | import android.util.Log; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.bytedance.sdk.openadsdk.AdSlot; 8 | import com.bytedance.sdk.openadsdk.TTAdConstant; 9 | import com.bytedance.sdk.openadsdk.TTAdNative; 10 | import com.bytedance.sdk.openadsdk.TTFullScreenVideoAd; 11 | import com.zero.flutter_gromore_ads.event.AdEventAction; 12 | 13 | import io.flutter.plugin.common.MethodCall; 14 | 15 | /** 16 | * 插屏广告 17 | */ 18 | public class InterstitialPage extends BaseAdPage implements TTAdNative.FullScreenVideoAdListener, TTFullScreenVideoAd.FullScreenVideoAdInteractionListener { 19 | private final String TAG = InterstitialPage.class.getSimpleName(); 20 | private TTFullScreenVideoAd ad; 21 | 22 | @Override 23 | public void loadAd(@NonNull MethodCall call) { 24 | adslot = new AdSlot.Builder() 25 | .setCodeId(this.posId) 26 | .build(); 27 | adNativeLoader.loadFullScreenVideoAd(adslot, this); 28 | } 29 | 30 | @Override 31 | public void onError(int i, String s) { 32 | Log.e(TAG, "onInterstitialLoadFail code:" + i + " msg:" + s); 33 | sendErrorEvent(i, s); 34 | } 35 | 36 | @Override 37 | public void onFullScreenVideoAdLoad(TTFullScreenVideoAd ttFullScreenVideoAd) { 38 | Log.i(TAG, "onFullScreenVideoAdLoad"); 39 | ad=ttFullScreenVideoAd; 40 | ad.setFullScreenVideoAdInteractionListener(this); 41 | ad.showFullScreenVideoAd(activity); 42 | // 添加广告事件 43 | sendEvent(AdEventAction.onAdLoaded); 44 | } 45 | 46 | @Override 47 | public void onFullScreenVideoCached() { 48 | 49 | } 50 | 51 | @Override 52 | public void onFullScreenVideoCached(TTFullScreenVideoAd ttFullScreenVideoAd) { 53 | 54 | } 55 | 56 | @Override 57 | public void onAdShow() { 58 | Log.i(TAG, "onAdShow"); 59 | // 添加广告事件 60 | sendEvent(AdEventAction.onAdExposure); 61 | } 62 | 63 | @Override 64 | public void onAdVideoBarClick() { 65 | Log.i(TAG, "onAdVideoBarClick"); 66 | // 添加广告事件 67 | sendEvent(AdEventAction.onAdClicked); 68 | } 69 | 70 | @Override 71 | public void onAdClose() { 72 | Log.i(TAG, "onAdClose"); 73 | if (ad != null && ad.getMediationManager() != null) { 74 | ad.setFullScreenVideoAdInteractionListener(null); 75 | ad.getMediationManager().destroy(); 76 | } 77 | // 添加广告事件 78 | sendEvent(AdEventAction.onAdClosed); 79 | } 80 | 81 | @Override 82 | public void onVideoComplete() { 83 | Log.i(TAG, "onVideoComplete"); 84 | // 添加广告事件 85 | sendEvent(AdEventAction.onAdComplete); 86 | } 87 | 88 | @Override 89 | public void onSkippedVideo() { 90 | Log.i(TAG, "onSkippedVideo"); 91 | // 添加广告事件 92 | sendEvent(AdEventAction.onAdSkip); 93 | } 94 | } -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/page/NativeViewFactory.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.page; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | 8 | import com.zero.flutter_gromore_ads.PluginDelegate; 9 | 10 | import java.util.Map; 11 | 12 | import io.flutter.plugin.common.StandardMessageCodec; 13 | import io.flutter.plugin.platform.PlatformView; 14 | import io.flutter.plugin.platform.PlatformViewFactory; 15 | 16 | /** 17 | * 原生平台 View 工厂 18 | */ 19 | public class NativeViewFactory extends PlatformViewFactory { 20 | @NonNull 21 | private final String viewName;// View 名字 22 | private final PluginDelegate pluginDelegate; // 插件代理类 23 | 24 | public NativeViewFactory(String viewName, @NonNull PluginDelegate pluginDelegate) { 25 | super(StandardMessageCodec.INSTANCE); 26 | this.viewName = viewName; 27 | this.pluginDelegate = pluginDelegate; 28 | } 29 | 30 | @NonNull 31 | @Override 32 | public PlatformView create(@NonNull Context context, int id, @Nullable Object args) { 33 | final Map creationParams = (Map) args; 34 | if (this.viewName.equals(PluginDelegate.KEY_BANNER_VIEW)) { 35 | return new AdBannerView(context, id, creationParams, pluginDelegate); 36 | } 37 | return null; 38 | } 39 | } -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/utils/DataUtils.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | 6 | /** 7 | * 数据工具类 8 | */ 9 | public class DataUtils { 10 | /** 11 | * 转换为 int [] 12 | * 13 | * @param integers List 14 | * @return int [] 15 | */ 16 | public static int[] convertIntegers(ArrayList integers) { 17 | if (integers == null) { 18 | return new int[]{}; 19 | } 20 | int[] ret = new int[integers.size()]; 21 | Iterator iterator = integers.iterator(); 22 | for (int i = 0; i < ret.length; i++) { 23 | ret[i] = iterator.next().intValue(); 24 | } 25 | return ret; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.utils; 2 | 3 | import android.content.Context; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | 10 | /** 11 | * 文件工具类 12 | */ 13 | public class FileUtils { 14 | /** 15 | * 获取 Json 16 | * @param fileName 文件名称 17 | * @param context 上下文 18 | * @return json 内容 19 | */ 20 | public static String getJson(String fileName, Context context) { 21 | StringBuilder stringBuilder = new StringBuilder(); 22 | try { 23 | InputStream is = context.getAssets().open(fileName); 24 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is)); 25 | String line; 26 | while ((line = bufferedReader.readLine()) != null) { 27 | stringBuilder.append(line); 28 | } 29 | } catch (IOException e) { 30 | e.printStackTrace(); 31 | } 32 | return stringBuilder.toString(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/utils/StatusBarUtils.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.utils; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.os.Build; 6 | import android.view.View; 7 | import android.view.Window; 8 | import android.view.WindowManager; 9 | 10 | /** 11 | * 状态栏工具类 12 | */ 13 | public class StatusBarUtils { 14 | /** 15 | * 设置透明状态栏 16 | * 17 | * @param activity Activity 18 | */ 19 | public static void setTranslucent(Activity activity) { 20 | Window window = activity.getWindow(); 21 | /// 设置透明状态栏 22 | if (window != null) { 23 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 24 | window.setStatusBarColor(Color.TRANSPARENT); 25 | } else { 26 | window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 27 | } 28 | } 29 | } 30 | 31 | /** 32 | * Android 6.0使用原始的主题适配 33 | * 34 | * @param activity Activity 35 | * @param darkMode 是否是黑色模式 36 | */ 37 | public static void setBarDarkMode(Activity activity, boolean darkMode) { 38 | Window window = activity.getWindow(); 39 | if (window == null) { 40 | return; 41 | } 42 | //设置StatusBar模式 43 | if (darkMode) {//黑色模式 44 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 45 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//设置statusBar和navigationBar为黑色 46 | window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 47 | } else {//设置statusBar为黑色 48 | window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 49 | } 50 | } 51 | } else {//白色模式 52 | int statusBarFlag = View.SYSTEM_UI_FLAG_VISIBLE; 53 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 54 | statusBarFlag = window.getDecorView().getSystemUiVisibility() 55 | & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 56 | } 57 | window.getDecorView().setSystemUiVisibility(statusBarFlag); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /android/src/main/java/com/zero/flutter_gromore_ads/utils/UIUtils.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Build; 6 | import android.text.TextUtils; 7 | import android.util.DisplayMetrics; 8 | import android.view.Display; 9 | import android.view.DisplayCutout; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.view.ViewParent; 13 | import android.view.WindowInsets; 14 | import android.view.WindowManager; 15 | import android.widget.FrameLayout; 16 | import android.widget.LinearLayout; 17 | import android.widget.RelativeLayout; 18 | 19 | import java.lang.reflect.InvocationTargetException; 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * Created by bytedance on 2019/9/5. 24 | */ 25 | 26 | public class UIUtils { 27 | 28 | public static float getScreenWidthDp(Context context) { 29 | final float scale = context.getResources().getDisplayMetrics().density; 30 | float width = context.getResources().getDisplayMetrics().widthPixels; 31 | return width / (scale <= 0 ? 1 : scale) + 0.5f; 32 | } 33 | 34 | //全面屏、刘海屏适配 35 | public static float getHeight(Activity activity) { 36 | hideBottomUIMenu(activity); 37 | float height; 38 | int realHeight = getRealHeight(activity); 39 | if (UIUtils.hasNotchScreen(activity)) { 40 | height = px2dip(activity, realHeight - getStatusBarHeight(activity)); 41 | } else { 42 | height = px2dip(activity, realHeight); 43 | } 44 | return height; 45 | } 46 | 47 | public static void hideBottomUIMenu(Activity activity) { 48 | if (activity == null) { 49 | return; 50 | } 51 | try { 52 | //隐藏虚拟按键,并且全屏 53 | if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api 54 | View v = activity.getWindow().getDecorView(); 55 | v.setSystemUiVisibility(View.GONE); 56 | } else if (Build.VERSION.SDK_INT >= 19) { 57 | //for new api versions. 58 | View decorView = activity.getWindow().getDecorView(); 59 | int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE 60 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 61 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 62 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar 63 | // | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar 64 | | View.SYSTEM_UI_FLAG_IMMERSIVE; 65 | decorView.setSystemUiVisibility(uiOptions); 66 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); 67 | } 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | 73 | //获取屏幕真实高度,不包含下方虚拟导航栏 74 | public static int getRealHeight(Context context) { 75 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 76 | Display display = windowManager.getDefaultDisplay(); 77 | DisplayMetrics dm = new DisplayMetrics(); 78 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 79 | display.getRealMetrics(dm); 80 | } else { 81 | display.getMetrics(dm); 82 | } 83 | int realHeight = dm.heightPixels; 84 | return realHeight; 85 | } 86 | 87 | //获取状态栏高度 88 | public static float getStatusBarHeight(Context context) { 89 | float height = 0; 90 | int resourceId = context.getApplicationContext().getResources().getIdentifier("status_bar_height", "dimen", "android"); 91 | if (resourceId > 0) { 92 | height = context.getApplicationContext().getResources().getDimensionPixelSize(resourceId); 93 | } 94 | return height; 95 | } 96 | 97 | public static int px2dip(Context context, float pxValue) { 98 | final float scale = context.getResources().getDisplayMetrics().density; 99 | return (int) (pxValue / (scale <= 0 ? 1 : scale) + 0.5f); 100 | } 101 | 102 | public static int dp2px(Context context, float dp) { 103 | final float scale = context.getResources().getDisplayMetrics().density; 104 | return (int) (dp * scale + 0.5f); 105 | } 106 | 107 | /** 108 | * 判断是否是刘海屏 109 | * 110 | * @return 111 | */ 112 | public static boolean hasNotchScreen(Activity activity) { 113 | return isAndroidPHasNotch(activity) 114 | || getInt("ro.miui.notch", activity) == 1 115 | || hasNotchAtHuawei(activity) 116 | || hasNotchAtOPPO(activity) 117 | || hasNotchAtVivo(activity); 118 | } 119 | 120 | /** 121 | * Android P 刘海屏判断 122 | * 123 | * @param activity 124 | * @return 125 | */ 126 | public static boolean isAndroidPHasNotch(Activity activity) { 127 | boolean result = false; 128 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { 129 | DisplayCutout displayCutout = null; 130 | try { 131 | WindowInsets windowInsets = activity.getWindow().getDecorView().getRootWindowInsets(); 132 | if (windowInsets != null) { 133 | displayCutout = windowInsets.getDisplayCutout(); 134 | } 135 | if (displayCutout != null) { 136 | result = true; 137 | } 138 | } catch (Exception e) { 139 | e.printStackTrace(); 140 | } 141 | } 142 | return result; 143 | } 144 | 145 | /** 146 | * 小米刘海屏判断. 147 | * 148 | * @return 0 if it is not notch ; return 1 means notch 149 | * @throws IllegalArgumentException if the key exceeds 32 characters 150 | */ 151 | public static int getInt(String key, Activity activity) { 152 | int result = 0; 153 | if (isMiui()) { 154 | try { 155 | ClassLoader classLoader = activity.getClassLoader(); 156 | @SuppressWarnings("rawtypes") 157 | Class SystemProperties = classLoader.loadClass("android.os.SystemProperties"); 158 | //参数类型 159 | @SuppressWarnings("rawtypes") 160 | Class[] paramTypes = new Class[2]; 161 | paramTypes[0] = String.class; 162 | paramTypes[1] = int.class; 163 | Method getInt = SystemProperties.getMethod("getInt", paramTypes); 164 | //参数 165 | Object[] params = new Object[2]; 166 | params[0] = new String(key); 167 | params[1] = new Integer(0); 168 | result = (Integer) getInt.invoke(SystemProperties, params); 169 | 170 | } catch (ClassNotFoundException e) { 171 | e.printStackTrace(); 172 | } catch (NoSuchMethodException e) { 173 | e.printStackTrace(); 174 | } catch (IllegalAccessException e) { 175 | e.printStackTrace(); 176 | } catch (IllegalArgumentException e) { 177 | e.printStackTrace(); 178 | } catch (InvocationTargetException e) { 179 | e.printStackTrace(); 180 | } 181 | } 182 | return result; 183 | } 184 | 185 | /** 186 | * 华为刘海屏判断 187 | * 188 | * @return 189 | */ 190 | public static boolean hasNotchAtHuawei(Context context) { 191 | boolean ret = false; 192 | try { 193 | ClassLoader classLoader = context.getClassLoader(); 194 | Class HwNotchSizeUtil = classLoader.loadClass("com.huawei.android.util.HwNotchSizeUtil"); 195 | Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen"); 196 | ret = (boolean) get.invoke(HwNotchSizeUtil); 197 | } catch (ClassNotFoundException e) { 198 | } catch (NoSuchMethodException e) { 199 | } catch (Exception e) { 200 | } finally { 201 | return ret; 202 | } 203 | } 204 | 205 | public static final int VIVO_NOTCH = 0x00000020;//是否有刘海 206 | public static final int VIVO_FILLET = 0x00000008;//是否有圆角 207 | 208 | /** 209 | * VIVO刘海屏判断 210 | * 211 | * @return 212 | */ 213 | public static boolean hasNotchAtVivo(Context context) { 214 | boolean ret = false; 215 | try { 216 | ClassLoader classLoader = context.getClassLoader(); 217 | Class FtFeature = classLoader.loadClass("android.util.FtFeature"); 218 | Method method = FtFeature.getMethod("isFeatureSupport", int.class); 219 | ret = (boolean) method.invoke(FtFeature, VIVO_NOTCH); 220 | } catch (ClassNotFoundException e) { 221 | } catch (NoSuchMethodException e) { 222 | } catch (Exception e) { 223 | } finally { 224 | return ret; 225 | } 226 | } 227 | 228 | /** 229 | * O-P-P-O刘海屏判断 230 | * 231 | * @return 232 | */ 233 | public static boolean hasNotchAtOPPO(Context context) { 234 | String temp = "com.kllk.feature.screen.heteromorphism"; 235 | String name = getKllkDecryptString(temp); 236 | return context.getPackageManager().hasSystemFeature(name); 237 | } 238 | 239 | public static boolean isMiui() { 240 | boolean sIsMiui = false; 241 | try { 242 | Class clz = Class.forName("miui.os.Build"); 243 | if (clz != null) { 244 | sIsMiui = true; 245 | //noinspection ConstantConditions 246 | return sIsMiui; 247 | } 248 | } catch (Exception e) { 249 | // ignore 250 | } 251 | return sIsMiui; 252 | } 253 | 254 | /** 255 | * 用于o-p-p-o 版本隐私协议 256 | */ 257 | public static String getKllkDecryptString(String encryptionString) { 258 | 259 | if (TextUtils.isEmpty(encryptionString)) { 260 | return ""; 261 | } 262 | String decryptTag = ""; 263 | String decryptCapitalized = "O" + "P" + "P" + "O"; 264 | String decrypt = "o" + "p" + "p" + "o"; 265 | if (encryptionString.contains("KLLK")) { 266 | decryptTag = encryptionString.replace("KLLK", decryptCapitalized); 267 | } else if (encryptionString.contains("kllk")) { 268 | decryptTag = encryptionString.replace("kllk", decrypt); 269 | } 270 | return decryptTag; 271 | 272 | } 273 | 274 | public static void setViewSize(View view, int width, int height) { 275 | if (view.getParent() instanceof FrameLayout) { 276 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) view.getLayoutParams(); 277 | lp.width = width; 278 | lp.height = height; 279 | view.setLayoutParams(lp); 280 | view.requestLayout(); 281 | } else if (view.getParent() instanceof RelativeLayout) { 282 | RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams(); 283 | lp.width = width; 284 | lp.height = height; 285 | view.setLayoutParams(lp); 286 | view.requestLayout(); 287 | } else if (view.getParent() instanceof LinearLayout) { 288 | LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) view.getLayoutParams(); 289 | lp.width = width; 290 | lp.height = height; 291 | view.setLayoutParams(lp); 292 | view.requestLayout(); 293 | } 294 | } 295 | 296 | public static int getScreenWidthInPx(Context context) { 297 | DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics(); 298 | return dm.widthPixels; 299 | } 300 | 301 | public static int getScreenHeightInPx(Context context) { 302 | DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics(); 303 | return dm.heightPixels; 304 | } 305 | 306 | public static void removeFromParent(View view) { 307 | if (view != null) { 308 | ViewParent vp = view.getParent(); 309 | if (vp instanceof ViewGroup) { 310 | ((ViewGroup) vp).removeView(view); 311 | } 312 | } 313 | } 314 | 315 | /** 316 | * 获取全面屏宽高 317 | * 318 | * @param context 319 | * @return 320 | */ 321 | public static int[] getScreenSize(Context context) { 322 | int[] size = new int[]{0, 0}; 323 | if (context == null) { 324 | return size; 325 | } 326 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 327 | Display display = windowManager.getDefaultDisplay(); 328 | DisplayMetrics dm = new DisplayMetrics(); 329 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 330 | display.getRealMetrics(dm); 331 | } else { 332 | display.getMetrics(dm); 333 | } 334 | size[0] = dm.widthPixels; 335 | size[1] = dm.heightPixels; 336 | return size; 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_ad_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 27 | -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxhdpi/flutterads_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/android/src/main/res/mipmap-xxhdpi/flutterads_logo.png -------------------------------------------------------------------------------- /android/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /android/src/main/res/xml/bd_file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/src/main/res/xml/gdt_file_path.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | -------------------------------------------------------------------------------- /android/src/main/res/xml/mb_provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /android/src/main/res/xml/network_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | i.snssdk.com 6 | is.snssdk.com 7 | pangolin.snssdk.com 8 | extlog.snssdk.com 9 | sf3-ttcdn-tos.pstatp.com 10 | bds.snssdk.com 11 | dig.bdurl.net 12 | 13 | 14 | api-access.pangolin-sdk-toutiao.com 15 | sf1-fe-tos.pglstatp-toutiao.com 16 | sf1-be-pack.pglstatp-toutiao.com 17 | sf3-fe-tos.pglstatp-toutiao.com 18 | log-api.pangolin-sdk-toutiao.com 19 | s3-fe-scm.pglstatp-toutiao.com 20 | s3a.pstatp.com 21 | 22 | api-access.pangolin-sdk-toutiao-b.com 23 | log-api.pangolin-sdk-toutiao-b.com 24 | dm.pstatp.com 25 | 26 | 27 | toblog.ctobsnssdk.com 28 | sdfp.snssdk.com 29 | tosv.byted.org 30 | sf1-ttcdn-tos.pstatp.com 31 | sf6-fe-tos.pglstatp-toutiao.com 32 | log.snssdk.com 33 | tosv.boe.byted.org 34 | dm.toutiao.com 35 | dm.bytedance.com 36 | 37 | 127.0.0.1 38 | 39 | //信任用户自己安装的证书 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /android/src/main/res/xml/pangle_file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/src/main/res/xml/sigmob_provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/src/main/res/xml/tt_file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Pro 付费功能 2 | 3 | - 此功能是插件 Pro 付费功能,需要购买插件后才能使用 4 | - 请联系微信:`toponelan` 咨询购买并获得技术支持 5 | - 日活 10W 以上,可咨询其他合作模式,目前已合作百万级别的 App 客户 6 | 7 | ---- 8 | 9 | ![Pro 版](assets/images/img_pro.png) 10 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | id "dev.flutter.flutter-gradle-plugin" 5 | } 6 | 7 | android { 8 | namespace = "com.zero.flutter_gromore_ads_example" 9 | compileSdk = 34 10 | ndkVersion = flutter.ndkVersion 11 | 12 | compileOptions { 13 | sourceCompatibility = JavaVersion.VERSION_1_8 14 | targetCompatibility = JavaVersion.VERSION_1_8 15 | } 16 | 17 | kotlinOptions { 18 | jvmTarget = JavaVersion.VERSION_1_8 19 | } 20 | 21 | defaultConfig { 22 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 23 | applicationId "com.flutterads.app" 24 | // You can update the following values to match your application needs. 25 | // For more information, see: https://flutter.dev/to/review-gradle-config. 26 | minSdk = flutter.minSdkVersion 27 | targetSdk = flutter.targetSdkVersion 28 | versionCode = flutter.versionCode 29 | versionName = flutter.versionName 30 | multiDexEnabled = true 31 | } 32 | 33 | buildTypes { 34 | release { 35 | // TODO: Add your own signing config for the release build. 36 | // Signing with the debug keys for now, so `flutter run --release` works. 37 | signingConfig signingConfigs.debug 38 | // 开启混淆 39 | minifyEnabled true 40 | // Zipalign优化 41 | zipAlignEnabled true 42 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 43 | } 44 | } 45 | } 46 | 47 | flutter { 48 | source = "../.." 49 | } 50 | 51 | dependencies { 52 | implementation 'androidx.multidex:multidex:2.0.1' 53 | //GroMore_sdk adapter 54 | implementation "com.pangle.cn:mediation-gdt-adapter:4.561.1431.0" //gdt adapter 55 | implementation "com.qq.e.union:union:4.561.1431"// 广点通广告 SDK 56 | // 其他厂商参考 https://www.csjplatform.com/union/media/union/download/detail?id=142&docId=27562&osType=android 57 | } 58 | -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | # 聚合混淆 23 | -keep class bykvm*.** 24 | -keep class com.bytedance.msdk.adapter.**{ public *; } 25 | -keep class com.bytedance.msdk.api.** { 26 | public *; 27 | } 28 | -keep class com.bytedance.msdk.base.TTBaseAd{*;} 29 | -keep class com.bytedance.msdk.adapter.TTAbsAdLoaderAdapter{ 30 | public *; 31 | protected ; 32 | } 33 | 34 | # baidu sdk 不接入baidu sdk可以不引入 35 | -ignorewarnings 36 | -dontwarn com.baidu.mobads.sdk.api.** 37 | -keepclassmembers class * extends android.app.Activity { 38 | public void *(android.view.View); 39 | } 40 | 41 | -keepclassmembers enum * { 42 | public static **[] values(); 43 | public static ** valueOf(java.lang.String); 44 | } 45 | 46 | -keep class com.baidu.mobads.** { *; } 47 | -keep class com.style.widget.** {*;} 48 | -keep class com.component.** {*;} 49 | -keep class com.baidu.ad.magic.flute.** {*;} 50 | -keep class com.baidu.mobstat.forbes.** {*;} 51 | 52 | #ks 不接入ks sdk可以不引入 53 | -keep class org.chromium.** {*;} 54 | -keep class org.chromium.** { *; } 55 | -keep class aegon.chrome.** { *; } 56 | -keep class com.kwai.**{ *; } 57 | -dontwarn com.kwai.** 58 | -dontwarn com.kwad.** 59 | -dontwarn com.ksad.** 60 | -dontwarn aegon.chrome.** 61 | 62 | # Admob 不接入admob sdk可以不引入 63 | -keep class com.google.android.gms.ads.MobileAds { 64 | public *; 65 | } 66 | 67 | #sigmob 不接入sigmob sdk可以不引入 68 | -dontwarn android.support.v4.** 69 | -keep class android.support.v4.** { *; } 70 | -keep interface android.support.v4.** { *; } 71 | -keep public class * extends android.support.v4.** 72 | 73 | -keep class sun.misc.Unsafe { *; } 74 | -dontwarn com.sigmob.** 75 | -keep class com.sigmob.**.**{*;} 76 | 77 | #oaid 不同的版本混淆代码不太一致,你注意你接入的oaid版本 ,不接入oaid可以不添加 78 | -dontwarn com.bun.** 79 | -keep class com.bun.** {*;} 80 | -keep class a.**{*;} 81 | -keep class XI.CA.XI.**{*;} 82 | -keep class XI.K0.XI.**{*;} 83 | -keep class XI.XI.K0.**{*;} 84 | -keep class XI.vs.K0.**{*;} 85 | -keep class XI.xo.XI.XI.**{*;} 86 | -keep class com.asus.msa.SupplementaryDID.**{*;} 87 | -keep class com.asus.msa.sdid.**{*;} 88 | -keep class com.huawei.hms.ads.identifier.**{*;} 89 | -keep class com.samsung.android.deviceidservice.**{*;} 90 | -keep class com.zui.opendeviceidlibrary.**{*;} 91 | -keep class org.json.**{*;} 92 | -keep public class com.netease.nis.sdkwrapper.Utils {public ;} 93 | 94 | 95 | #klevin 游可赢 96 | -keep class com.tencent.tgpa.**{*;} 97 | -keep class com.tencent.klevin.**{*;} 98 | 99 | 100 | #Mintegral 不接入Mintegral sdk,可以不引入 101 | -keepattributes Signature 102 | -keepattributes *Annotation* 103 | -keep class com.mbridge.** {*; } 104 | -keep interface com.mbridge.** {*; } 105 | -keep class android.support.v4.** { *; } 106 | -dontwarn com.mbridge.** 107 | -keep class **.R$* { public static final int mbridge*; } -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 27 | 35 | 39 | 43 | 48 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 62 | 63 | 64 | 65 | 70 | 73 | 74 | 75 | 79 | 80 | 81 | 82 | 83 | 88 | 91 | 92 | 93 | 98 | 104 | 105 | 106 | 109 | 110 | 111 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/zero/flutter_gromore_ads_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.zero.flutter_gromore_ads_example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/flutterads_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/android/app/src/main/res/mipmap-xxhdpi/flutterads_logo.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/flutterads_logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/android/app/src/main/res/mipmap-xxhdpi/flutterads_logo2.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | android.injected.testOnly=false 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 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-7.6.3-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "7.3.0" apply false 22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false 23 | } 24 | 25 | include ":app" 26 | -------------------------------------------------------------------------------- /example/assets/images/img_pro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/assets/images/img_pro.png -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /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/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | # use_frameworks! 32 | # use_modular_headers! 33 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 34 | #1.GroMoreSDK核心库 35 | # 广点通/优量汇 36 | pod 'CSJMGdtAdapter', '4.14.50.0' 37 | pod 'GDTMobSDK','4.14.50' 38 | # 百度SDK 39 | # pod 'CSJMBaiduAdapter', '5.300.0' 40 | # pod 'BaiduMobAdSDK', '5.300' 41 | # UnityAds 42 | # pod 'CSJMUnityAdapter', '4.3.0.0' 43 | # pod 'UnityAds', '4.3.0' 44 | # Admob/GoogleAd 45 | # pod 'CSJMAdmobAdapter', '10.0.0.0' 46 | # pod 'Google-Mobile-Ads-SDK', '10.0.0' 47 | # SigmobAd 48 | # pod 'CSJMSigmobAdapter', '4.8.0.0' 49 | # pod 'SigmobAd-iOS', '4.8.0' 50 | # MintegralAdSDK 51 | # pod 'CSJMMintegralAdapter', '7.3.6.0.0' 52 | # MintegralAdSDK 使用时请务必使用cocoapod源 53 | # pod 'MintegralAdSDK', '7.3.6.0', :subspecs => [ 54 | # 'SplashAd', 55 | # 'InterstitialAd', 56 | # 'NewInterstitialAd', 57 | # 'InterstitialVideoAd', 58 | # 'RewardVideoAd', 59 | # 'NativeAd', 60 | # 'NativeAdvancedAd', 61 | # 'BannerAd', 62 | # 'BidNativeAd', 63 | # 'BidNewInterstitialAd', 64 | # 'BidInterstitialVideoAd', 65 | # 'BidRewardVideoAd' 66 | # ] 67 | # pod 'CSJMKlevinAdapter', '2.11.0.211.1' 68 | # pod 'KlevinAdSDK', '2.11.0.211' 69 | # 快手 70 | # pod 'CSJMKsAdapter', '3.3.47.0' 71 | # pod 'KSAdSDK', '3.3.47' 72 | end 73 | 74 | post_install do |installer| 75 | installer.pods_project.targets.each do |target| 76 | flutter_additional_ios_build_settings(target) 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 04DD503428DB1FDB00D57BA7 /* ios_config_5209496.json in Resources */ = {isa = PBXBuildFile; fileRef = 04DD503328DB1FDB00D57BA7 /* ios_config_5209496.json */; }; 11 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 14 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 18 | FDD33B8C0FE34A2719D19059 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E97716EF707F52964DF8476 /* libPods-Runner.a */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXCopyFilesBuildPhase section */ 22 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 23 | isa = PBXCopyFilesBuildPhase; 24 | buildActionMask = 2147483647; 25 | dstPath = ""; 26 | dstSubfolderSpec = 10; 27 | files = ( 28 | ); 29 | name = "Embed Frameworks"; 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXCopyFilesBuildPhase section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 04DD503328DB1FDB00D57BA7 /* ios_config_5209496.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ios_config_5209496.json; sourceTree = ""; }; 36 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 37 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 38 | 283DAB62945052BCDBBB39E6 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 39 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 40 | 4703E65FBD011537C610E06E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 41 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 42 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 43 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 44 | 7E97716EF707F52964DF8476 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 46 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 47 | 97658E5BC508BE58AAB991B0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 48 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 50 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 52 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | FDD33B8C0FE34A2719D19059 /* libPods-Runner.a in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 04DD503228DB1FBC00D57BA7 /* configs */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 04DD503328DB1FDB00D57BA7 /* ios_config_5209496.json */, 72 | ); 73 | path = configs; 74 | sourceTree = ""; 75 | }; 76 | 12024B3CFB70776F4F8E0CBC /* Pods */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 283DAB62945052BCDBBB39E6 /* Pods-Runner.debug.xcconfig */, 80 | 97658E5BC508BE58AAB991B0 /* Pods-Runner.release.xcconfig */, 81 | 4703E65FBD011537C610E06E /* Pods-Runner.profile.xcconfig */, 82 | ); 83 | path = Pods; 84 | sourceTree = ""; 85 | }; 86 | 75A3B89DCA7285B44ED589D8 /* Frameworks */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 7E97716EF707F52964DF8476 /* libPods-Runner.a */, 90 | ); 91 | name = Frameworks; 92 | sourceTree = ""; 93 | }; 94 | 9740EEB11CF90186004384FC /* Flutter */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 98 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 99 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 100 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 101 | ); 102 | name = Flutter; 103 | sourceTree = ""; 104 | }; 105 | 97C146E51CF9000F007C117D = { 106 | isa = PBXGroup; 107 | children = ( 108 | 9740EEB11CF90186004384FC /* Flutter */, 109 | 97C146F01CF9000F007C117D /* Runner */, 110 | 97C146EF1CF9000F007C117D /* Products */, 111 | 12024B3CFB70776F4F8E0CBC /* Pods */, 112 | 75A3B89DCA7285B44ED589D8 /* Frameworks */, 113 | ); 114 | sourceTree = ""; 115 | }; 116 | 97C146EF1CF9000F007C117D /* Products */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 97C146EE1CF9000F007C117D /* Runner.app */, 120 | ); 121 | name = Products; 122 | sourceTree = ""; 123 | }; 124 | 97C146F01CF9000F007C117D /* Runner */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 04DD503228DB1FBC00D57BA7 /* configs */, 128 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 129 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 130 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 131 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 132 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 133 | 97C147021CF9000F007C117D /* Info.plist */, 134 | 97C146F11CF9000F007C117D /* Supporting Files */, 135 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 136 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 137 | ); 138 | path = Runner; 139 | sourceTree = ""; 140 | }; 141 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 97C146F21CF9000F007C117D /* main.m */, 145 | ); 146 | name = "Supporting Files"; 147 | sourceTree = ""; 148 | }; 149 | /* End PBXGroup section */ 150 | 151 | /* Begin PBXNativeTarget section */ 152 | 97C146ED1CF9000F007C117D /* Runner */ = { 153 | isa = PBXNativeTarget; 154 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 155 | buildPhases = ( 156 | BDFEF42CE1B8FF69BD3D733B /* [CP] Check Pods Manifest.lock */, 157 | 9740EEB61CF901F6004384FC /* Run Script */, 158 | 97C146EA1CF9000F007C117D /* Sources */, 159 | 97C146EB1CF9000F007C117D /* Frameworks */, 160 | 97C146EC1CF9000F007C117D /* Resources */, 161 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 162 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 163 | D06C9F2C459062A83121FB6A /* [CP] Copy Pods Resources */, 164 | ); 165 | buildRules = ( 166 | ); 167 | dependencies = ( 168 | ); 169 | name = Runner; 170 | productName = Runner; 171 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 172 | productType = "com.apple.product-type.application"; 173 | }; 174 | /* End PBXNativeTarget section */ 175 | 176 | /* Begin PBXProject section */ 177 | 97C146E61CF9000F007C117D /* Project object */ = { 178 | isa = PBXProject; 179 | attributes = { 180 | LastUpgradeCheck = 1510; 181 | ORGANIZATIONNAME = ""; 182 | TargetAttributes = { 183 | 97C146ED1CF9000F007C117D = { 184 | CreatedOnToolsVersion = 7.3.1; 185 | }; 186 | }; 187 | }; 188 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 189 | compatibilityVersion = "Xcode 9.3"; 190 | developmentRegion = en; 191 | hasScannedForEncodings = 0; 192 | knownRegions = ( 193 | en, 194 | Base, 195 | ); 196 | mainGroup = 97C146E51CF9000F007C117D; 197 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 198 | projectDirPath = ""; 199 | projectRoot = ""; 200 | targets = ( 201 | 97C146ED1CF9000F007C117D /* Runner */, 202 | ); 203 | }; 204 | /* End PBXProject section */ 205 | 206 | /* Begin PBXResourcesBuildPhase section */ 207 | 97C146EC1CF9000F007C117D /* Resources */ = { 208 | isa = PBXResourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 212 | 04DD503428DB1FDB00D57BA7 /* ios_config_5209496.json in Resources */, 213 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 214 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 215 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 216 | ); 217 | runOnlyForDeploymentPostprocessing = 0; 218 | }; 219 | /* End PBXResourcesBuildPhase section */ 220 | 221 | /* Begin PBXShellScriptBuildPhase section */ 222 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 223 | isa = PBXShellScriptBuildPhase; 224 | alwaysOutOfDate = 1; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | ); 228 | inputPaths = ( 229 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 230 | ); 231 | name = "Thin Binary"; 232 | outputPaths = ( 233 | ); 234 | runOnlyForDeploymentPostprocessing = 0; 235 | shellPath = /bin/sh; 236 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 237 | }; 238 | 9740EEB61CF901F6004384FC /* Run Script */ = { 239 | isa = PBXShellScriptBuildPhase; 240 | alwaysOutOfDate = 1; 241 | buildActionMask = 2147483647; 242 | files = ( 243 | ); 244 | inputPaths = ( 245 | ); 246 | name = "Run Script"; 247 | outputPaths = ( 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | shellPath = /bin/sh; 251 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 252 | }; 253 | BDFEF42CE1B8FF69BD3D733B /* [CP] Check Pods Manifest.lock */ = { 254 | isa = PBXShellScriptBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | inputFileListPaths = ( 259 | ); 260 | inputPaths = ( 261 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 262 | "${PODS_ROOT}/Manifest.lock", 263 | ); 264 | name = "[CP] Check Pods Manifest.lock"; 265 | outputFileListPaths = ( 266 | ); 267 | outputPaths = ( 268 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | shellPath = /bin/sh; 272 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 273 | showEnvVarsInLog = 0; 274 | }; 275 | D06C9F2C459062A83121FB6A /* [CP] Copy Pods Resources */ = { 276 | isa = PBXShellScriptBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | inputFileListPaths = ( 281 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", 282 | ); 283 | name = "[CP] Copy Pods Resources"; 284 | outputFileListPaths = ( 285 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | shellPath = /bin/sh; 289 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; 290 | showEnvVarsInLog = 0; 291 | }; 292 | /* End PBXShellScriptBuildPhase section */ 293 | 294 | /* Begin PBXSourcesBuildPhase section */ 295 | 97C146EA1CF9000F007C117D /* Sources */ = { 296 | isa = PBXSourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 300 | 97C146F31CF9000F007C117D /* main.m in Sources */, 301 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | /* End PBXSourcesBuildPhase section */ 306 | 307 | /* Begin PBXVariantGroup section */ 308 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 309 | isa = PBXVariantGroup; 310 | children = ( 311 | 97C146FB1CF9000F007C117D /* Base */, 312 | ); 313 | name = Main.storyboard; 314 | sourceTree = ""; 315 | }; 316 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 317 | isa = PBXVariantGroup; 318 | children = ( 319 | 97C147001CF9000F007C117D /* Base */, 320 | ); 321 | name = LaunchScreen.storyboard; 322 | sourceTree = ""; 323 | }; 324 | /* End PBXVariantGroup section */ 325 | 326 | /* Begin XCBuildConfiguration section */ 327 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 328 | isa = XCBuildConfiguration; 329 | buildSettings = { 330 | ALWAYS_SEARCH_USER_PATHS = NO; 331 | CLANG_ANALYZER_NONNULL = YES; 332 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 333 | CLANG_CXX_LIBRARY = "libc++"; 334 | CLANG_ENABLE_MODULES = YES; 335 | CLANG_ENABLE_OBJC_ARC = YES; 336 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 337 | CLANG_WARN_BOOL_CONVERSION = YES; 338 | CLANG_WARN_COMMA = YES; 339 | CLANG_WARN_CONSTANT_CONVERSION = YES; 340 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 341 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 342 | CLANG_WARN_EMPTY_BODY = YES; 343 | CLANG_WARN_ENUM_CONVERSION = YES; 344 | CLANG_WARN_INFINITE_RECURSION = YES; 345 | CLANG_WARN_INT_CONVERSION = YES; 346 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 347 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 348 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 349 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 350 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 351 | CLANG_WARN_STRICT_PROTOTYPES = YES; 352 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 353 | CLANG_WARN_UNREACHABLE_CODE = YES; 354 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 355 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 356 | COPY_PHASE_STRIP = NO; 357 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 358 | ENABLE_NS_ASSERTIONS = NO; 359 | ENABLE_STRICT_OBJC_MSGSEND = YES; 360 | GCC_C_LANGUAGE_STANDARD = gnu99; 361 | GCC_NO_COMMON_BLOCKS = YES; 362 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 363 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 364 | GCC_WARN_UNDECLARED_SELECTOR = YES; 365 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 366 | GCC_WARN_UNUSED_FUNCTION = YES; 367 | GCC_WARN_UNUSED_VARIABLE = YES; 368 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 369 | MTL_ENABLE_DEBUG_INFO = NO; 370 | SDKROOT = iphoneos; 371 | SUPPORTED_PLATFORMS = iphoneos; 372 | TARGETED_DEVICE_FAMILY = "1,2"; 373 | VALIDATE_PRODUCT = YES; 374 | }; 375 | name = Profile; 376 | }; 377 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 378 | isa = XCBuildConfiguration; 379 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 380 | buildSettings = { 381 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 382 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 383 | DEVELOPMENT_TEAM = N943VT2CQD; 384 | ENABLE_BITCODE = NO; 385 | HEADER_SEARCH_PATHS = ( 386 | "$(inherited)", 387 | "\"${PODS_ROOT}/Headers/Public\"", 388 | "\"${PODS_ROOT}/Headers/Public/GDTMobSDK\"", 389 | "\"${PODS_ROOT}/Headers/Public/flutter_gromore_ads\"", 390 | "\"${PODS_ROOT}/Headers/Public/flutter_pangle_ads\"", 391 | "\"${PODS_ROOT}/Headers/Public/flutter_qq_ads\"", 392 | "$(SDKROOT)/usr/include/libxml2", 393 | ); 394 | INFOPLIST_FILE = Runner/Info.plist; 395 | LD_RUNPATH_SEARCH_PATHS = ( 396 | "$(inherited)", 397 | "@executable_path/Frameworks", 398 | ); 399 | PRODUCT_BUNDLE_IDENTIFIER = com.flutterads.app; 400 | PRODUCT_NAME = "$(TARGET_NAME)"; 401 | USER_HEADER_SEARCH_PATHS = ""; 402 | VERSIONING_SYSTEM = "apple-generic"; 403 | }; 404 | name = Profile; 405 | }; 406 | 97C147031CF9000F007C117D /* Debug */ = { 407 | isa = XCBuildConfiguration; 408 | buildSettings = { 409 | ALWAYS_SEARCH_USER_PATHS = NO; 410 | CLANG_ANALYZER_NONNULL = YES; 411 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 412 | CLANG_CXX_LIBRARY = "libc++"; 413 | CLANG_ENABLE_MODULES = YES; 414 | CLANG_ENABLE_OBJC_ARC = YES; 415 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 416 | CLANG_WARN_BOOL_CONVERSION = YES; 417 | CLANG_WARN_COMMA = YES; 418 | CLANG_WARN_CONSTANT_CONVERSION = YES; 419 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 420 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 421 | CLANG_WARN_EMPTY_BODY = YES; 422 | CLANG_WARN_ENUM_CONVERSION = YES; 423 | CLANG_WARN_INFINITE_RECURSION = YES; 424 | CLANG_WARN_INT_CONVERSION = YES; 425 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 426 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 427 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 428 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 429 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 430 | CLANG_WARN_STRICT_PROTOTYPES = YES; 431 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 432 | CLANG_WARN_UNREACHABLE_CODE = YES; 433 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 434 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 435 | COPY_PHASE_STRIP = NO; 436 | DEBUG_INFORMATION_FORMAT = dwarf; 437 | ENABLE_STRICT_OBJC_MSGSEND = YES; 438 | ENABLE_TESTABILITY = YES; 439 | GCC_C_LANGUAGE_STANDARD = gnu99; 440 | GCC_DYNAMIC_NO_PIC = NO; 441 | GCC_NO_COMMON_BLOCKS = YES; 442 | GCC_OPTIMIZATION_LEVEL = 0; 443 | GCC_PREPROCESSOR_DEFINITIONS = ( 444 | "DEBUG=1", 445 | "$(inherited)", 446 | ); 447 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 448 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 449 | GCC_WARN_UNDECLARED_SELECTOR = YES; 450 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 451 | GCC_WARN_UNUSED_FUNCTION = YES; 452 | GCC_WARN_UNUSED_VARIABLE = YES; 453 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 454 | MTL_ENABLE_DEBUG_INFO = YES; 455 | ONLY_ACTIVE_ARCH = YES; 456 | SDKROOT = iphoneos; 457 | TARGETED_DEVICE_FAMILY = "1,2"; 458 | }; 459 | name = Debug; 460 | }; 461 | 97C147041CF9000F007C117D /* Release */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | ALWAYS_SEARCH_USER_PATHS = NO; 465 | CLANG_ANALYZER_NONNULL = YES; 466 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 467 | CLANG_CXX_LIBRARY = "libc++"; 468 | CLANG_ENABLE_MODULES = YES; 469 | CLANG_ENABLE_OBJC_ARC = YES; 470 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 471 | CLANG_WARN_BOOL_CONVERSION = YES; 472 | CLANG_WARN_COMMA = YES; 473 | CLANG_WARN_CONSTANT_CONVERSION = YES; 474 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 475 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 476 | CLANG_WARN_EMPTY_BODY = YES; 477 | CLANG_WARN_ENUM_CONVERSION = YES; 478 | CLANG_WARN_INFINITE_RECURSION = YES; 479 | CLANG_WARN_INT_CONVERSION = YES; 480 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 481 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 482 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 483 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 484 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 485 | CLANG_WARN_STRICT_PROTOTYPES = YES; 486 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 487 | CLANG_WARN_UNREACHABLE_CODE = YES; 488 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 489 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 490 | COPY_PHASE_STRIP = NO; 491 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 492 | ENABLE_NS_ASSERTIONS = NO; 493 | ENABLE_STRICT_OBJC_MSGSEND = YES; 494 | GCC_C_LANGUAGE_STANDARD = gnu99; 495 | GCC_NO_COMMON_BLOCKS = YES; 496 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 497 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 498 | GCC_WARN_UNDECLARED_SELECTOR = YES; 499 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 500 | GCC_WARN_UNUSED_FUNCTION = YES; 501 | GCC_WARN_UNUSED_VARIABLE = YES; 502 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 503 | MTL_ENABLE_DEBUG_INFO = NO; 504 | SDKROOT = iphoneos; 505 | SUPPORTED_PLATFORMS = iphoneos; 506 | TARGETED_DEVICE_FAMILY = "1,2"; 507 | VALIDATE_PRODUCT = YES; 508 | }; 509 | name = Release; 510 | }; 511 | 97C147061CF9000F007C117D /* Debug */ = { 512 | isa = XCBuildConfiguration; 513 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 514 | buildSettings = { 515 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 516 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 517 | DEVELOPMENT_TEAM = N943VT2CQD; 518 | ENABLE_BITCODE = NO; 519 | HEADER_SEARCH_PATHS = ( 520 | "$(inherited)", 521 | "\"${PODS_ROOT}/Headers/Public\"", 522 | "\"${PODS_ROOT}/Headers/Public/GDTMobSDK\"", 523 | "\"${PODS_ROOT}/Headers/Public/flutter_gromore_ads\"", 524 | "\"${PODS_ROOT}/Headers/Public/flutter_pangle_ads\"", 525 | "\"${PODS_ROOT}/Headers/Public/flutter_qq_ads\"", 526 | "$(SDKROOT)/usr/include/libxml2", 527 | ); 528 | INFOPLIST_FILE = Runner/Info.plist; 529 | LD_RUNPATH_SEARCH_PATHS = ( 530 | "$(inherited)", 531 | "@executable_path/Frameworks", 532 | ); 533 | PRODUCT_BUNDLE_IDENTIFIER = com.flutterads.app; 534 | PRODUCT_NAME = "$(TARGET_NAME)"; 535 | USER_HEADER_SEARCH_PATHS = ""; 536 | VERSIONING_SYSTEM = "apple-generic"; 537 | }; 538 | name = Debug; 539 | }; 540 | 97C147071CF9000F007C117D /* Release */ = { 541 | isa = XCBuildConfiguration; 542 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 543 | buildSettings = { 544 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 545 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 546 | DEVELOPMENT_TEAM = N943VT2CQD; 547 | ENABLE_BITCODE = NO; 548 | HEADER_SEARCH_PATHS = ( 549 | "$(inherited)", 550 | "\"${PODS_ROOT}/Headers/Public\"", 551 | "\"${PODS_ROOT}/Headers/Public/GDTMobSDK\"", 552 | "\"${PODS_ROOT}/Headers/Public/flutter_gromore_ads\"", 553 | "\"${PODS_ROOT}/Headers/Public/flutter_pangle_ads\"", 554 | "\"${PODS_ROOT}/Headers/Public/flutter_qq_ads\"", 555 | "$(SDKROOT)/usr/include/libxml2", 556 | ); 557 | INFOPLIST_FILE = Runner/Info.plist; 558 | LD_RUNPATH_SEARCH_PATHS = ( 559 | "$(inherited)", 560 | "@executable_path/Frameworks", 561 | ); 562 | PRODUCT_BUNDLE_IDENTIFIER = com.flutterads.app; 563 | PRODUCT_NAME = "$(TARGET_NAME)"; 564 | USER_HEADER_SEARCH_PATHS = ""; 565 | VERSIONING_SYSTEM = "apple-generic"; 566 | }; 567 | name = Release; 568 | }; 569 | /* End XCBuildConfiguration section */ 570 | 571 | /* Begin XCConfigurationList section */ 572 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 573 | isa = XCConfigurationList; 574 | buildConfigurations = ( 575 | 97C147031CF9000F007C117D /* Debug */, 576 | 97C147041CF9000F007C117D /* Release */, 577 | 249021D3217E4FDB00AE95B9 /* Profile */, 578 | ); 579 | defaultConfigurationIsVisible = 0; 580 | defaultConfigurationName = Release; 581 | }; 582 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 583 | isa = XCConfigurationList; 584 | buildConfigurations = ( 585 | 97C147061CF9000F007C117D /* Debug */, 586 | 97C147071CF9000F007C117D /* Release */, 587 | 249021D4217E4FDB00AE95B9 /* Profile */, 588 | ); 589 | defaultConfigurationIsVisible = 0; 590 | defaultConfigurationName = Release; 591 | }; 592 | /* End XCConfigurationList section */ 593 | }; 594 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 595 | } 596 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "size": "20x20", 5 | "idiom": "iphone", 6 | "filename": "icon-20@2x.png", 7 | "scale": "2x" 8 | }, 9 | { 10 | "size": "20x20", 11 | "idiom": "iphone", 12 | "filename": "icon-20@3x.png", 13 | "scale": "3x" 14 | }, 15 | { 16 | "size": "29x29", 17 | "idiom": "iphone", 18 | "filename": "icon-29.png", 19 | "scale": "1x" 20 | }, 21 | { 22 | "size": "29x29", 23 | "idiom": "iphone", 24 | "filename": "icon-29@2x.png", 25 | "scale": "2x" 26 | }, 27 | { 28 | "size": "29x29", 29 | "idiom": "iphone", 30 | "filename": "icon-29@3x.png", 31 | "scale": "3x" 32 | }, 33 | { 34 | "size": "40x40", 35 | "idiom": "iphone", 36 | "filename": "icon-40@2x.png", 37 | "scale": "2x" 38 | }, 39 | { 40 | "size": "40x40", 41 | "idiom": "iphone", 42 | "filename": "icon-40@3x.png", 43 | "scale": "3x" 44 | }, 45 | { 46 | "size": "60x60", 47 | "idiom": "iphone", 48 | "filename": "icon-60@2x.png", 49 | "scale": "2x" 50 | }, 51 | { 52 | "size": "60x60", 53 | "idiom": "iphone", 54 | "filename": "icon-60@3x.png", 55 | "scale": "3x" 56 | }, 57 | { 58 | "size": "20x20", 59 | "idiom": "ipad", 60 | "filename": "icon-20-ipad.png", 61 | "scale": "1x" 62 | }, 63 | { 64 | "size": "20x20", 65 | "idiom": "ipad", 66 | "filename": "icon-20@2x-ipad.png", 67 | "scale": "2x" 68 | }, 69 | { 70 | "size": "29x29", 71 | "idiom": "ipad", 72 | "filename": "icon-29-ipad.png", 73 | "scale": "1x" 74 | }, 75 | { 76 | "size": "29x29", 77 | "idiom": "ipad", 78 | "filename": "icon-29@2x-ipad.png", 79 | "scale": "2x" 80 | }, 81 | { 82 | "size": "40x40", 83 | "idiom": "ipad", 84 | "filename": "icon-40.png", 85 | "scale": "1x" 86 | }, 87 | { 88 | "size": "40x40", 89 | "idiom": "ipad", 90 | "filename": "icon-40@2x.png", 91 | "scale": "2x" 92 | }, 93 | { 94 | "size": "76x76", 95 | "idiom": "ipad", 96 | "filename": "icon-76.png", 97 | "scale": "1x" 98 | }, 99 | { 100 | "size": "76x76", 101 | "idiom": "ipad", 102 | "filename": "icon-76@2x.png", 103 | "scale": "2x" 104 | }, 105 | { 106 | "size": "83.5x83.5", 107 | "idiom": "ipad", 108 | "filename": "icon-83.5@2x.png", 109 | "scale": "2x" 110 | }, 111 | { 112 | "size": "1024x1024", 113 | "idiom": "ios-marketing", 114 | "filename": "icon-1024.png", 115 | "scale": "1x" 116 | } 117 | ], 118 | "info": { 119 | "version": 1, 120 | "author": "icon.wuruihong.com" 121 | } 122 | } -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-1024.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchImage@1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "LaunchImage@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "LaunchImage@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchImage2@1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "LaunchImage2@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "LaunchImage2@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage2.imageset/LaunchImage2@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/LaunchImage2.imageset/LaunchImage2@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage2.imageset/LaunchImage2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/LaunchImage2.imageset/LaunchImage2@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage2.imageset/LaunchImage2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/example/ios/Runner/Assets.xcassets/LaunchImage2.imageset/LaunchImage2@3x.png -------------------------------------------------------------------------------- /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 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /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/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_gromore_ads_example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | 32 | NSUserTrackingUsageDescription 33 | 为了向您提供更优质、安全的个性化服务及内容,需要您允许使用相关权限 34 | UIApplicationSupportsIndirectInputEvents 35 | 36 | UILaunchStoryboardName 37 | LaunchScreen 38 | UIMainStoryboardFile 39 | Main 40 | UISupportedInterfaceOrientations 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UISupportedInterfaceOrientations~ipad 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationPortraitUpsideDown 50 | UIInterfaceOrientationLandscapeLeft 51 | UIInterfaceOrientationLandscapeRight 52 | 53 | UIViewControllerBasedStatusBarAppearance 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_gromore_ads/flutter_gromore_ads.dart'; 3 | 4 | import 'pro_page.dart'; 5 | 6 | void main() { 7 | // 绑定引擎 8 | WidgetsFlutterBinding.ensureInitialized(); 9 | // 启动 10 | runApp(const MyApp()); 11 | 12 | // 初始化 13 | init(); 14 | } 15 | 16 | class MyApp extends StatefulWidget { 17 | const MyApp({Key? key}) : super(key: key); 18 | 19 | @override 20 | State createState() => _MyAppState(); 21 | } 22 | 23 | class _MyAppState extends State { 24 | @override 25 | Widget build(BuildContext context) { 26 | return const MaterialApp( 27 | home: ProPage(), 28 | ); 29 | } 30 | } 31 | 32 | /// 初始化 33 | Future init() async { 34 | // 设置监听 35 | FlutterGromoreAds.onEventListener((event) { 36 | print('🎉🎉🎉 FlutterAds ==> $event'); 37 | }); 38 | 39 | // 初始化 40 | await FlutterGromoreAds.initAd( 41 | '1234567890', 42 | config: 'config.json', 43 | ); 44 | 45 | // 展示开屏广告 46 | await FlutterGromoreAds.showSplashAd('1234567890'); 47 | } 48 | -------------------------------------------------------------------------------- /example/lib/pro_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Pro 页面 4 | class ProPage extends StatefulWidget { 5 | const ProPage({Key? key}) : super(key: key); 6 | 7 | @override 8 | State createState() => _ProPageState(); 9 | } 10 | 11 | class _ProPageState extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: AppBar( 16 | title: const Text('Pro 版体验'), 17 | ), 18 | body: SingleChildScrollView( 19 | child: Column( 20 | children: [ 21 | const Center( 22 | child: Padding( 23 | padding: EdgeInsets.all(10.0), 24 | child: Text( 25 | '开源版不提供示例,请扫码下载 Pro 版体验', 26 | textAlign: TextAlign.center, 27 | ), 28 | ), 29 | ), 30 | Image.network( 31 | 'https://flutterads.top/gzh_qrcode.webp', 32 | fit: BoxFit.cover, 33 | ), 34 | const Center( 35 | child: Padding( 36 | padding: EdgeInsets.all(10.0), 37 | child: Text( 38 | '扫码关注公众号回复【Pro】,即可下载体验', 39 | textAlign: TextAlign.center, 40 | style: TextStyle( 41 | color: Colors.purple, 42 | fontSize: 16, 43 | fontWeight: FontWeight.bold, 44 | ), 45 | ), 46 | ), 47 | ), 48 | ], 49 | ), 50 | ), 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_gromore_ads_example 2 | description: Demonstrates how to use the flutter_gromore_ads plugin. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 7 | version: 3.2.0+16 8 | 9 | environment: 10 | sdk: ">=2.12.0 <4.0.0" 11 | 12 | # Dependencies specify other packages that your package needs in order to work. 13 | # To automatically upgrade your package dependencies to the latest versions 14 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 15 | # dependencies can be manually updated by changing the version numbers below to 16 | # the latest version available on pub.dev. To see which dependencies have newer 17 | # versions available, run `flutter pub outdated`. 18 | dependencies: 19 | flutter: 20 | sdk: flutter 21 | 22 | flutter_gromore_ads: 23 | # When depending on this package from a real application you should use: 24 | # flutter_gromore_ads: ^x.y.z 25 | # See https://dart.dev/tools/pub/dependencies#version-constraints 26 | # The example app is bundled with the plugin so we use a path dependency on 27 | # the parent directory to use the current plugin's version. 28 | path: ../ 29 | 30 | # The following adds the Cupertino Icons font to your application. 31 | # Use with the CupertinoIcons class for iOS style icons. 32 | cupertino_icons: ^1.0.2 33 | loadany: ^1.0.0 34 | 35 | dev_dependencies: 36 | flutter_test: 37 | sdk: flutter 38 | 39 | # For information on the generic Dart part of this file, see the 40 | # following page: https://dart.dev/tools/pub/pubspec 41 | 42 | # The following section is specific to Flutter. 43 | flutter: 44 | # The following line ensures that the Material Icons font is 45 | # included with your application, so that you can use the icons in 46 | # the material Icons class. 47 | uses-material-design: true 48 | 49 | # To add assets to your application, add an assets section, like this: 50 | assets: 51 | - assets/images/img_pro.png 52 | # - images/a_dot_ham.jpeg 53 | 54 | # An image asset can refer to one or more resolution-specific "variants", see 55 | # https://flutter.dev/assets-and-images/#resolution-aware. 56 | 57 | # For details regarding adding assets from package dependencies, see 58 | # https://flutter.dev/assets-and-images/#from-packages 59 | 60 | # To add custom fonts to your application, add a fonts section here, 61 | # in this "flutter" section. Each entry in this list should have a 62 | # "family" key with the font family name, and a "fonts" key with a 63 | # list giving the asset and other descriptors for the font. For 64 | # example: 65 | # fonts: 66 | # - family: Schyler 67 | # fonts: 68 | # - asset: fonts/Schyler-Regular.ttf 69 | # - asset: fonts/Schyler-Italic.ttf 70 | # style: italic 71 | # - family: Trajan Pro 72 | # fonts: 73 | # - asset: fonts/TrajanPro.ttf 74 | # - asset: fonts/TrajanPro_Bold.ttf 75 | # weight: 700 76 | # 77 | # For details regarding fonts from package dependencies, 78 | # see https://flutter.dev/custom-fonts/#from-packages 79 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module app_store 2 | 3 | go 1.16 4 | 5 | require github.com/flutter/flutter v2.2.3 // indirect -------------------------------------------------------------------------------- /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 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlutterAds/flutter_gromore_ads/b164474995aa1502c9d37eac8f853c3c8af8f840/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/Event/FGMAdErrorEvent.h: -------------------------------------------------------------------------------- 1 | // 2 | // FGMAdErrorEvent.h 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/11. 6 | // 7 | 8 | #import "FGMAdEvent.h" 9 | 10 | // 广告错误事件 11 | @interface FGMAdErrorEvent : FGMAdEvent 12 | // 错误码 13 | @property (assign,nonatomic) NSInteger errCode; 14 | // 错误信息 15 | @property (copy,nonatomic) NSString *errMsg; 16 | 17 | -(id) initWithAdId:(NSString *)adId errCode:(NSInteger)errCode errMsg:(NSString*) errMsg; 18 | -(id) initWithAdId:(NSString *)adId error:(NSError *)error; 19 | @end 20 | -------------------------------------------------------------------------------- /ios/Classes/Event/FGMAdErrorEvent.m: -------------------------------------------------------------------------------- 1 | // 2 | // FGMAdErrorEvent.m 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/11. 6 | // 7 | 8 | #import "FGMAdErrorEvent.h" 9 | 10 | @implementation FGMAdErrorEvent 11 | - (id)initWithAdId:(NSString *)adId errCode:(NSInteger)errCode errMsg:(NSString *)errMsg{ 12 | self.adId=adId; 13 | self.action=onAdError; 14 | self.errCode=errCode; 15 | self.errMsg=errMsg; 16 | return self; 17 | } 18 | 19 | - (id)initWithAdId:(NSString *)adId error:(NSError *)error{ 20 | return [self initWithAdId:adId errCode:error.code errMsg:error.localizedDescription]; 21 | } 22 | 23 | - (NSDictionary *)toMap{ 24 | NSMutableDictionary *errData=[[NSMutableDictionary alloc] initWithDictionary:[super toMap]]; 25 | [errData setObject:@(self.errCode) forKey:@"errCode"]; 26 | [errData setObject:self.errMsg forKey:@"errMsg"]; 27 | return errData; 28 | } 29 | @end 30 | -------------------------------------------------------------------------------- /ios/Classes/Event/FGMAdEvent.h: -------------------------------------------------------------------------------- 1 | // 2 | // FGMAdEvent.h 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/11. 6 | // 7 | 8 | #import 9 | // 广告操作事件 10 | // 广告错误 11 | static NSString *const onAdError=@"onAdError"; 12 | // 广告加载成功 13 | static NSString *const onAdLoaded=@"onAdLoaded"; 14 | // 广告填充 15 | static NSString *const onAdPresent=@"onAdPresent"; 16 | // 广告曝光 17 | static NSString *const onAdExposure=@"onAdExposure"; 18 | // 广告关闭(计时结束或者用户点击关闭) 19 | static NSString *const onAdClosed=@"onAdClosed"; 20 | // 广告点击 21 | static NSString * const onAdClicked=@"onAdClicked"; 22 | // 广告跳过 23 | static NSString *const onAdSkip=@"onAdSkip"; 24 | // 广告播放或计时完毕 25 | static NSString *const onAdComplete=@"onAdComplete"; 26 | // 获得广告激励 27 | static NSString *const onAdReward=@"onAdReward"; 28 | 29 | // 广告事件 30 | @interface FGMAdEvent : NSObject 31 | // 广告id 32 | @property (copy,nonatomic) NSString *adId; 33 | // 操作事件 34 | @property (copy,nonatomic) NSString *action; 35 | // 构造广告事件 36 | - (id) initWithAdId:(NSString *) adId action:(NSString *) action; 37 | // 转换为 map 38 | - (NSDictionary *) toMap; 39 | @end 40 | -------------------------------------------------------------------------------- /ios/Classes/Event/FGMAdEvent.m: -------------------------------------------------------------------------------- 1 | // 2 | // FGMAdEvent.m 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/11. 6 | // 7 | 8 | #import "FGMAdEvent.h" 9 | 10 | @implementation FGMAdEvent 11 | - (id)initWithAdId:(NSString *)adId action:(NSString *)action{ 12 | self.adId=adId; 13 | self.action=action; 14 | return self; 15 | } 16 | 17 | - (NSDictionary *)toMap{ 18 | NSDictionary *data=@{@"adId":self.adId,@"action":self.action}; 19 | return data; 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /ios/Classes/FGMGroMore.h: -------------------------------------------------------------------------------- 1 | // 2 | // FGMGroMore.h 3 | // Pods 4 | // 5 | // Created by zero on 2021/12/12. 6 | // 7 | 8 | #import 9 | -------------------------------------------------------------------------------- /ios/Classes/FlutterGromoreAdsPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "FGMSplashPage.h" 3 | #import "FGMInterstitialPage.h" 4 | 5 | @interface FlutterGromoreAdsPlugin : NSObject 6 | @property (strong,nonatomic) FlutterEventSink eventSink;// 事件 7 | @property (strong,nonatomic) FGMSplashPage *sad;// 开屏广告 8 | @property (strong,nonatomic) FGMInterstitialPage *iad;// 插屏广告 9 | 10 | extern NSString *const kGMAdBannerViewId; 11 | @end 12 | -------------------------------------------------------------------------------- /ios/Classes/FlutterGromoreAdsPlugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterGromoreAdsPlugin.h" 2 | #import 3 | #import 4 | #import "FGMGroMore.h" 5 | #import "FGMNativeViewFactory.h" 6 | 7 | @implementation FlutterGromoreAdsPlugin 8 | // AdBannerView 9 | NSString *const kGMAdBannerViewId=@"flutter_gromore_ads_banner"; 10 | 11 | + (void)registerWithRegistrar:(NSObject*)registrar { 12 | FlutterMethodChannel* methodChannel = [FlutterMethodChannel 13 | methodChannelWithName:@"flutter_gromore_ads" 14 | binaryMessenger:[registrar messenger]]; 15 | 16 | FlutterEventChannel* eventChannel=[FlutterEventChannel eventChannelWithName:@"flutter_gromore_ads_event" binaryMessenger:[registrar messenger]]; 17 | 18 | FlutterGromoreAdsPlugin* instance = [[FlutterGromoreAdsPlugin alloc] init]; 19 | [registrar addMethodCallDelegate:instance channel:methodChannel]; 20 | [eventChannel setStreamHandler:instance]; 21 | 22 | // 注册平台View 工厂 23 | FGMNativeViewFactory *bannerFactory=[[FGMNativeViewFactory alloc] initWithViewName:kGMAdBannerViewId withMessenger:registrar.messenger withPlugin:instance]; 24 | // 注册 View 25 | [registrar registerViewFactory:bannerFactory withId:kGMAdBannerViewId]; 26 | 27 | 28 | } 29 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 30 | NSString *methodStr=call.method; 31 | if ([@"getPlatformVersion" isEqualToString:methodStr]) { 32 | result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); 33 | }else if ([@"requestIDFA" isEqualToString:methodStr]) { 34 | [self requestIDFA:call result:result]; 35 | }else if ([@"initAd" isEqualToString:methodStr]){ 36 | [self initAd:call result:result]; 37 | }else if ([@"showSplashAd" isEqualToString:methodStr]) { 38 | [self showSplashAd:call result:result]; 39 | }else if ([@"showInterstitialAd" isEqualToString:methodStr]) { 40 | [self showInterstitialAd:call result:result]; 41 | }else { 42 | result(FlutterMethodNotImplemented); 43 | } 44 | } 45 | 46 | // 请求 IDFA 47 | - (void) requestIDFA:(FlutterMethodCall*) call result:(FlutterResult) result{ 48 | if (@available(iOS 14, *)) { 49 | [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { 50 | BOOL requestResult=status == ATTrackingManagerAuthorizationStatusAuthorized; 51 | NSLog(@"FlutterGromoreAdsPlugin requestIDFA:%@",requestResult?@"YES":@"NO"); 52 | result(@(requestResult)); 53 | }]; 54 | } else { 55 | result(@(YES)); 56 | } 57 | } 58 | 59 | // 初始化广告 60 | - (void) initAd:(FlutterMethodCall*) call result:(FlutterResult) result{ 61 | NSString *appId=call.arguments[@"appId"]; 62 | NSString *config=call.arguments[@"config"]; 63 | int limitPersonalAds=[call.arguments[@"limitPersonalAds"] intValue]; 64 | BUAdSDKConfiguration *configuration = [BUAdSDKConfiguration configuration]; 65 | // 是否开启调试 66 | #ifdef DEBUG 67 | configuration.debugLog = @(1); 68 | #endif 69 | // 配置 appid 和使用聚合 70 | configuration.appID = appId; 71 | configuration.useMediation = YES; 72 | // 隐私合规 73 | configuration.mediation.limitPersonalAds = @(limitPersonalAds); 74 | configuration.mediation.limitProgrammaticAds = @(limitPersonalAds); 75 | configuration.mediation.forbiddenCAID = @(limitPersonalAds); 76 | // 提前导入配置 77 | if (![config isKindOfClass:[NSNull class]] && [config length]!=0) { 78 | configuration.mediation.advanceSDKConfigPath = [[NSBundle mainBundle]pathForResource:config ofType:@"json"]; 79 | } 80 | 81 | [BUAdSDKManager startWithAsyncCompletionHandler:^(BOOL success, NSError *error) { 82 | if (success) { 83 | result(@(YES)); 84 | } else { 85 | result(@(NO)); 86 | NSLog(@"FlutterGromoreAdsPlugin initAd error:%@",error.description); 87 | } 88 | }]; 89 | 90 | } 91 | 92 | // 开屏广告 93 | - (void) showSplashAd:(FlutterMethodCall*) call result:(FlutterResult) result{ 94 | if (self.sad!=nil&&self.sad.isDisplay) { 95 | result(@(NO)); 96 | return; 97 | } 98 | self.sad=[[FGMSplashPage alloc] init]; 99 | [self.sad showAd:call eventSink:self.eventSink]; 100 | result(@(YES)); 101 | } 102 | 103 | // 插屏广告 104 | - (void) showInterstitialAd:(FlutterMethodCall *)call result:(FlutterResult) result{ 105 | self.iad=[[FGMInterstitialPage alloc] init]; 106 | [self.iad showAd:call eventSink:self.eventSink]; 107 | result(@(YES)); 108 | } 109 | 110 | #pragma mark - FlutterStreamHandler 111 | 112 | - (FlutterError *)onCancelWithArguments:(id)arguments{ 113 | self.eventSink = nil; 114 | return nil; 115 | } 116 | - (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events{ 117 | self.eventSink = events; 118 | return nil; 119 | } 120 | 121 | - (void) addEvent:(NSObject *) event{ 122 | if(self.eventSink){ 123 | self.eventSink(event); 124 | } 125 | } 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMAdBannerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FGMAdBannerView.h 3 | // flutter_gromore_ads 4 | // 5 | // Created by Zero on 2023/1/12. 6 | // 7 | 8 | #import "FGMBasePage.h" 9 | #import "FlutterGromoreAdsPlugin.h" 10 | 11 | @interface FGMAdBannerView : FGMBasePage 12 | @property (strong,nonatomic,nullable) FlutterGromoreAdsPlugin *plugin; 13 | - (nonnull instancetype)initWithFrame:(CGRect)frame 14 | viewIdentifier:(int64_t)viewId 15 | arguments:(id _Nullable)args 16 | binaryMessenger:(NSObject* _Nullable)messenger plugin:(FlutterGromoreAdsPlugin* _Nullable) plugin; 17 | 18 | - (nonnull UIView*)view; 19 | @end 20 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMAdBannerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FGMAdBannerView.m 3 | // flutter_gromore_ads 4 | // 5 | // Created by Zero on 2023/1/12. 6 | // 7 | 8 | #import "FGMAdBannerView.h" 9 | 10 | @interface FGMAdBannerView() 11 | @property (strong,nonatomic) BUNativeExpressBannerView *bad; 12 | @property (strong,nonatomic) UIView *bannerView; 13 | 14 | @end 15 | 16 | @implementation FGMAdBannerView 17 | 18 | - (instancetype)initWithFrame:(CGRect)frame 19 | viewIdentifier:(int64_t)viewId 20 | arguments:(id _Nullable)args 21 | binaryMessenger:(NSObject*)messenger 22 | plugin:(FlutterGromoreAdsPlugin*) plugin{ 23 | if (self = [super init]) { 24 | self.bannerView = [[UIView alloc] init]; 25 | FlutterMethodCall *call=[FlutterMethodCall methodCallWithMethodName:@"AdBannerView" arguments:args]; 26 | [self showAd:call eventSink:plugin.eventSink]; 27 | } 28 | return self; 29 | } 30 | 31 | - (UIView*)view { 32 | return self.bannerView; 33 | } 34 | // 加载广告 35 | - (void)loadAd:(FlutterMethodCall *)call{ 36 | // 刷新间隔 37 | int width = [call.arguments[@"width"] intValue]; 38 | int height = [call.arguments[@"height"] intValue]; 39 | self.bad=[[BUNativeExpressBannerView alloc] initWithSlotID:self.posId rootViewController:self.rootController adSize:CGSizeMake(width, height)]; 40 | self.bad.delegate=self; 41 | [self.bad loadAdData]; 42 | } 43 | 44 | 45 | #pragma mark ----- ABUBannerAdDelegate ----- 46 | /// 加载成功回调 47 | - (void)nativeExpressBannerAdViewDidLoad:(BUNativeExpressBannerView *)bannerAdView { 48 | NSLog(@"%s",__FUNCTION__); 49 | [self.bannerView addSubview:bannerAdView]; 50 | // 发送事件 51 | [self sendEventAction:onAdLoaded]; 52 | } 53 | 54 | /// 加载失败回调 55 | - (void)nativeExpressBannerAdView:(BUNativeExpressBannerView *)bannerAdView didLoadFailWithError:(NSError *)error { 56 | NSLog(@"%s-error:%@", __FUNCTION__, error); 57 | // 发送事件 58 | [self sendErrorEvent:error]; 59 | // 销毁广告 60 | [self destoryAd:nil]; 61 | } 62 | 63 | /// 展示成功回调 64 | - (void)nativeExpressBannerAdViewDidBecomeVisible:(BUNativeExpressBannerView *)bannerAdView { 65 | NSLog(@"%s",__FUNCTION__); 66 | // 发送事件 67 | [self sendEventAction:onAdExposure]; 68 | } 69 | 70 | /// 广告点击回调 71 | - (void)nativeExpressBannerAdViewDidClick:(BUNativeExpressBannerView *)bannerAdView { 72 | NSLog(@"%s",__FUNCTION__); 73 | // 发送事件 74 | [self sendEventAction:onAdClicked]; 75 | } 76 | 77 | - (void)nativeExpressBannerAdView:(BUNativeExpressBannerView *)bannerAdView dislikeWithReason:(NSArray *)filterwords { 78 | NSLog(@"%s",__FUNCTION__); 79 | } 80 | 81 | - (void)nativeExpressBannerAdViewDidCloseOtherController:(BUNativeExpressBannerView *)bannerAdView interactionType:(BUInteractionType)interactionType { 82 | NSLog(@"%s",__FUNCTION__); 83 | } 84 | 85 | - (void)nativeExpressBannerAdViewDidRemoved:(BUNativeExpressBannerView *)nativeExpressAdView { 86 | NSLog(@"%s",__FUNCTION__); 87 | // 可于此处移除广告view 88 | [self destoryAd:self.bannerView]; 89 | // 发送事件 90 | [self sendEventAction:onAdClosed]; 91 | } 92 | 93 | // 销毁广告 94 | - (void)destoryAd:(UIView *)bannerView{ 95 | if(bannerView){ 96 | [bannerView removeFromSuperview]; 97 | } 98 | self.bad.delegate=nil; 99 | self.bad=nil; 100 | } 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMBasePage.h: -------------------------------------------------------------------------------- 1 | // 2 | // FGMBasePage.h 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/11. 6 | // 7 | 8 | #import 9 | #import 10 | #import "FGMGroMore.h" 11 | #import "FGMAdErrorEvent.h" 12 | // 基础广告页面 13 | @interface FGMBasePage : NSObject 14 | // 广告位 id 15 | @property (strong,nonatomic) NSString *posId; 16 | // 回调事件 17 | @property (strong,nonatomic) FlutterEventSink eventSink; 18 | // 窗口 19 | @property (strong,nonatomic) UIWindow *mainWin; 20 | // 跟控制器 21 | @property (strong,nonatomic) UIViewController *rootController; 22 | //显示广告 23 | - (void) showAd:(FlutterMethodCall*) call eventSink:(FlutterEventSink) events; 24 | // 加载广告 25 | - (void) loadAd:(FlutterMethodCall*) call; 26 | // 发送广告事件 27 | - (void) sendEvent:(FGMAdEvent*) event; 28 | // 发送广告事件 29 | - (void) sendEventAction:(NSString*) action; 30 | // 发送错误广告事件 31 | - (void) sendErrorEvent:(NSError*) error; 32 | @end 33 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMBasePage.m: -------------------------------------------------------------------------------- 1 | // 2 | // FGMBasePage.m 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/11. 6 | // 7 | 8 | #import "FGMBasePage.h" 9 | 10 | @implementation FGMBasePage 11 | - (void)showAd:(FlutterMethodCall *)call eventSink:(FlutterEventSink)events{ 12 | self.posId=call.arguments[@"posId"]; 13 | self.eventSink=events; 14 | // 获取控制器 15 | self.mainWin=[[UIApplication sharedApplication] keyWindow]; 16 | self.rootController=[self.mainWin rootViewController]; 17 | //加载广告 18 | [self loadAd:call]; 19 | } 20 | 21 | - (void)loadAd:(FlutterMethodCall *)call{ 22 | NSLog(@"%s",__FUNCTION__); 23 | 24 | } 25 | 26 | - (void)sendEvent:(FGMAdEvent *)event{ 27 | if(self.eventSink){ 28 | self.eventSink(event.toMap); 29 | } 30 | } 31 | 32 | - (void)sendEventAction:(NSString *)action{ 33 | FGMAdEvent *event=[[FGMAdEvent alloc] initWithAdId:self.posId action:action]; 34 | [self sendEvent:event]; 35 | 36 | } 37 | 38 | - (void)sendErrorEvent:(NSError *)error{ 39 | if (self.eventSink) { 40 | FGMAdErrorEvent *event=[[FGMAdErrorEvent alloc] initWithAdId:self.posId error:error]; 41 | self.eventSink(event.toMap); 42 | } 43 | } 44 | @end 45 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMInterstitialPage.h: -------------------------------------------------------------------------------- 1 | // 2 | // FGMInterstitialPage.h 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/12. 6 | // 7 | 8 | #import "FGMBasePage.h" 9 | // 插屏广告 10 | @interface FGMInterstitialPage : FGMBasePage 11 | @property (strong,nonatomic) BUNativeExpressFullscreenVideoAd *ad; 12 | @end 13 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMInterstitialPage.m: -------------------------------------------------------------------------------- 1 | // 2 | // FGMInterstitialPage.m 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/12. 6 | // 7 | 8 | #import "FGMInterstitialPage.h" 9 | 10 | @interface FGMInterstitialPage() 11 | 12 | @end 13 | 14 | @implementation FGMInterstitialPage 15 | 16 | - (void)loadAd:(FlutterMethodCall *)call{ 17 | int width=[call.arguments[@"width"] intValue]; 18 | int height=[call.arguments[@"height"] intValue]; 19 | self.ad= [[BUNativeExpressFullscreenVideoAd alloc] initWithSlotID:self.posId]; 20 | self.ad.delegate=self; 21 | [self.ad loadAdData]; 22 | } 23 | 24 | #pragma mark - BUMNativeExpressFullscreenVideoAdDelegate 25 | - (void)nativeExpressFullscreenVideoAdDidLoad:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { 26 | NSLog(@"%s",__FUNCTION__); 27 | if(self.ad && self.ad.mediation.isReady){ 28 | [self.ad showAdFromRootViewController:self.rootController]; 29 | } 30 | // 发送事件 31 | [self sendEventAction:onAdLoaded]; 32 | } 33 | 34 | - (void)nativeExpressFullscreenVideoAd:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error { 35 | NSLog(@"%s-error:%@", __FUNCTION__, error); 36 | // 发送事件 37 | [self sendErrorEvent:error]; 38 | } 39 | 40 | - (void)nativeExpressFullscreenVideoAdViewRenderSuccess:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd { 41 | NSLog(@"%s",__FUNCTION__); 42 | // 发送事件 43 | [self sendEventAction:onAdExposure]; 44 | } 45 | 46 | - (void)nativeExpressFullscreenVideoAdViewRenderFail:(BUNativeExpressFullscreenVideoAd *)rewardedVideoAd error:(NSError *_Nullable)error { 47 | NSLog(@"%s-error:%@", __FUNCTION__, error); 48 | // 发送事件 49 | [self sendErrorEvent:error]; 50 | } 51 | 52 | - (void)nativeExpressFullscreenVideoAdDidDownLoadVideo:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { 53 | NSLog(@"%s",__FUNCTION__); 54 | } 55 | 56 | - (void)nativeExpressFullscreenVideoAdWillVisible:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { 57 | NSLog(@"%s",__FUNCTION__); 58 | } 59 | 60 | - (void)nativeExpressFullscreenVideoAdDidVisible:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { 61 | NSLog(@"%s",__FUNCTION__); 62 | } 63 | 64 | - (void)nativeExpressFullscreenVideoAdDidClick:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { 65 | NSLog(@"%s",__FUNCTION__); 66 | // 发送事件 67 | [self sendEventAction:onAdClicked]; 68 | } 69 | 70 | - (void)nativeExpressFullscreenVideoAdDidClickSkip:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { 71 | NSLog(@"%s",__FUNCTION__); 72 | // 发送事件 73 | [self sendEventAction:onAdComplete]; 74 | } 75 | 76 | - (void)nativeExpressFullscreenVideoAdWillClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { 77 | NSLog(@"%s",__FUNCTION__); 78 | } 79 | 80 | - (void)nativeExpressFullscreenVideoAdDidClose:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd { 81 | NSLog(@"%s",__FUNCTION__); 82 | // 发送事件 83 | [self sendEventAction:onAdClosed]; 84 | } 85 | 86 | - (void)nativeExpressFullscreenVideoAdDidPlayFinish:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd didFailWithError:(NSError *_Nullable)error { 87 | NSLog(@"%s",__FUNCTION__); 88 | } 89 | 90 | - (void)nativeExpressFullscreenVideoAdCallback:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd withType:(BUNativeExpressFullScreenAdType) nativeExpressVideoAdType{ 91 | NSLog(@"%s",__FUNCTION__); 92 | } 93 | 94 | - (void)nativeExpressFullscreenVideoAdDidCloseOtherController:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd interactionType:(BUInteractionType)interactionType { 95 | NSLog(@"%s",__FUNCTION__); 96 | } 97 | 98 | - (void)nativeExpressFullscreenVideoAdServerRewardDidSucceed:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd verify:(BOOL)verify { 99 | NSLog(@"%s",__FUNCTION__); 100 | } 101 | 102 | - (void)nativeExpressFullscreenVideoAdServerRewardDidFail:(BUNativeExpressFullscreenVideoAd *)fullscreenVideoAd error:(NSError *)error { 103 | NSLog(@"%s",__FUNCTION__); 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMNativeViewFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // FGMNativeViewFactory.h 3 | // flutter_gromore_ads 4 | // 5 | // Created by Zero on 2023/1/12. 6 | // 7 | 8 | #import 9 | #import 10 | #import "FlutterGromoreAdsPlugin.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface FGMNativeViewFactory : NSObject 15 | @property (strong,nonatomic) NSObject *messenger; 16 | @property (strong,nonatomic) FlutterGromoreAdsPlugin *plugin; 17 | @property (strong,nonatomic) NSString *viewName; 18 | - (instancetype)initWithViewName:(NSString*) viewName withMessenger:(NSObject*)messenger withPlugin:(FlutterGromoreAdsPlugin*) plugin; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMNativeViewFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // FGMNativeViewFactory.m 3 | // flutter_gromore_ads 4 | // 5 | // Created by Zero on 2023/1/12. 6 | // 7 | 8 | #import "FGMNativeViewFactory.h" 9 | #import "FGMAdBannerView.h" 10 | 11 | @implementation FGMNativeViewFactory 12 | 13 | 14 | - (instancetype)initWithViewName:(NSString *)viewName withMessenger:(NSObject *)messenger withPlugin:(FlutterGromoreAdsPlugin *)plugin{ 15 | self = [super init]; 16 | if (self) { 17 | self.viewName = viewName; 18 | self.messenger = messenger; 19 | self.plugin = plugin; 20 | } 21 | return self; 22 | } 23 | 24 | - (NSObject*)createArgsCodec { 25 | return [FlutterStandardMessageCodec sharedInstance]; 26 | } 27 | 28 | - (NSObject*)createWithFrame:(CGRect)frame 29 | viewIdentifier:(int64_t)viewId 30 | arguments:(id _Nullable)args { 31 | if (self.viewName==kGMAdBannerViewId) { 32 | return [[FGMAdBannerView alloc] initWithFrame:frame 33 | viewIdentifier:viewId 34 | arguments:args 35 | binaryMessenger:self.messenger 36 | plugin:self.plugin]; 37 | } 38 | return nil; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMSplashPage.h: -------------------------------------------------------------------------------- 1 | // 2 | // FGMSplashPage.h 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/11. 6 | // 7 | 8 | #import 9 | #import "FGMBasePage.h" 10 | 11 | // 开屏广告 12 | @interface FGMSplashPage :FGMBasePage 13 | // 开屏 14 | @property (strong,nonatomic) BUSplashAd *ad; 15 | @property (retain,nonatomic) UIView *bottomView; 16 | @property (assign,nonatomic ) BOOL fullScreenAd; 17 | // 广告是否展示中 18 | @property (assign,nonatomic ) BOOL isDisplay; 19 | @end 20 | -------------------------------------------------------------------------------- /ios/Classes/Page/FGMSplashPage.m: -------------------------------------------------------------------------------- 1 | // 2 | // FGMSplashPage.m 3 | // flutter_gromore_ads 4 | // 5 | // Created by zero on 2021/12/11. 6 | // 7 | 8 | #import "FGMSplashPage.h" 9 | 10 | @interface FGMSplashPage () 11 | 12 | @end 13 | 14 | @implementation FGMSplashPage 15 | 16 | - (void)loadAd:(FlutterMethodCall *)call{ 17 | NSLog(@"%s,%@",__FUNCTION__,self.posId); 18 | self.isDisplay=YES; 19 | NSString* logo=call.arguments[@"logo"]; 20 | double timeout=[call.arguments[@"timeout"] doubleValue]; 21 | // logo 判断为空,则全屏展示 22 | self.fullScreenAd=[logo isKindOfClass:[NSNull class]]||[logo length]==0; 23 | 24 | // 创建广告 25 | self.ad =[[BUSplashAd alloc] initWithSlotID:self.posId adSize:CGSizeZero]; 26 | self.ad.delegate=self; 27 | self.ad.supportCardView = YES; 28 | self.ad.supportZoomOutView = YES; 29 | self.ad.tolerateTimeout=timeout; 30 | if (!self.fullScreenAd) { 31 | CGSize size=[[UIScreen mainScreen] bounds].size; 32 | CGFloat width=size.width; 33 | CGFloat height=112.5;// 这里按照 15% 进行logo 的展示,防止尺寸不够的问题,750*15%=112.5 34 | // 设置底部 logo 35 | self.bottomView=nil; 36 | self.bottomView=[[UIView alloc]initWithFrame:CGRectMake(0, 0,width, height)]; 37 | self.bottomView.backgroundColor=[UIColor whiteColor]; 38 | UIImageView *logoView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:logo]]; 39 | logoView.frame=CGRectMake(0, 0, width, height); 40 | logoView.contentMode=UIViewContentModeCenter; 41 | logoView.center=self.bottomView.center; 42 | [self.bottomView addSubview:logoView]; 43 | [self.ad.mediation setCustomBottomView:self.bottomView]; 44 | } 45 | [self.ad loadAdData]; 46 | } 47 | 48 | - (void)splashAdLoadSuccess:(nonnull BUSplashAd *)splashAd { 49 | NSLog(@"%s",__FUNCTION__); 50 | [self.ad showSplashViewInRootViewController:self.rootController]; 51 | // 发送事件 52 | [self sendEventAction:onAdLoaded]; 53 | } 54 | - (void)splashAdLoadFail:(nonnull BUSplashAd *)splashAd error:(BUAdError * _Nullable)error { 55 | NSLog(@"%s-error:%@", __func__, error); 56 | // 发送事件 57 | [self sendErrorEvent:error]; 58 | self.isDisplay=NO; 59 | } 60 | 61 | - (void)splashAdDidShow:(nonnull BUSplashAd *)splashAd { 62 | NSLog(@"%s",__FUNCTION__); 63 | // 发送事件 64 | [self sendEventAction:onAdExposure]; 65 | } 66 | 67 | - (void)splashAdDidShowFailed:(BUSplashAd *)splashAd error:(NSError *)error{ 68 | NSLog(@"%s",__FUNCTION__); 69 | // 发送事件 70 | [self sendErrorEvent:error]; 71 | self.isDisplay=NO; 72 | } 73 | 74 | - (void)splashAdDidClick:(nonnull BUSplashAd *)splashAd { 75 | NSLog(@"%s",__FUNCTION__); 76 | // 发送事件 77 | [self sendEventAction:onAdClicked]; 78 | } 79 | 80 | - (void)splashAdDidClose:(nonnull BUSplashAd *)splashAd closeType:(BUSplashAdCloseType)closeType { 81 | NSLog(@"%s",__FUNCTION__); 82 | // 发送事件 83 | [self sendEventAction:onAdClosed]; 84 | // 销毁广告 85 | if (self.ad) { 86 | [self.ad.mediation destoryAd]; 87 | } 88 | self.isDisplay=NO; 89 | } 90 | 91 | 92 | - (void)splashCardReadyToShow:(nonnull BUSplashAd *)splashAd { 93 | NSLog(@"%s",__FUNCTION__); 94 | [self.ad showSplashViewInRootViewController:self.rootController]; 95 | // 发送事件 96 | [self sendEventAction:onAdLoaded]; 97 | } 98 | 99 | - (void)splashCardViewDidClick:(nonnull BUSplashAd *)splashAd { 100 | NSLog(@"%s",__FUNCTION__); 101 | // 发送事件 102 | [self sendEventAction:onAdClicked]; 103 | } 104 | 105 | - (void)splashCardViewDidClose:(nonnull BUSplashAd *)splashAd { 106 | NSLog(@"%s",__FUNCTION__); 107 | // 发送事件 108 | [self sendEventAction:onAdClosed]; 109 | // 销毁广告 110 | if (self.ad) { 111 | [self.ad.mediation destoryAd]; 112 | } 113 | self.isDisplay=NO; 114 | } 115 | 116 | - (void)splashAdViewControllerDidClose:(BUSplashAd *)splashAd { 117 | NSLog(@"%s",__FUNCTION__); 118 | } 119 | 120 | - (void)splashDidCloseOtherController:(nonnull BUSplashAd *)splashAd interactionType:(BUInteractionType)interactionType { 121 | NSLog(@"%s",__FUNCTION__); 122 | } 123 | 124 | 125 | - (void)splashVideoAdDidPlayFinish:(BUSplashAd *)splashAd didFailWithError:(NSError *)error { 126 | NSLog(@"%s",__FUNCTION__); 127 | } 128 | 129 | 130 | - (void)splashZoomOutViewDidClick:(nonnull BUSplashAd *)splashAd { 131 | NSLog(@"%s",__FUNCTION__); 132 | // 发送事件 133 | [self sendEventAction:onAdClicked]; 134 | } 135 | 136 | 137 | - (void)splashZoomOutViewDidClose:(nonnull BUSplashAd *)splashAd { 138 | NSLog(@"%s",__FUNCTION__); 139 | // 发送事件 140 | [self sendEventAction:onAdClosed]; 141 | // 销毁广告 142 | if (self.ad) { 143 | [self.ad.mediation destoryAd]; 144 | } 145 | self.isDisplay=NO; 146 | } 147 | 148 | - (void)splashZoomOutReadyToShow:(nonnull BUSplashAd *)splashAd { 149 | NSLog(@"%s",__FUNCTION__); 150 | // 接入方法一:使用SDK提供动画接入 151 | if (self.ad.zoomOutView) { 152 | [self.ad showZoomOutViewInRootViewController:self.rootController]; 153 | } 154 | } 155 | 156 | @end 157 | -------------------------------------------------------------------------------- /ios/flutter_gromore_ads.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_gromore_ads.podspec' to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_gromore_ads' 7 | s.version = '3.2.0' 8 | s.summary = '一款优质的 Flutter 广告插件(GroMore、穿山甲)' 9 | s.description = <<-DESC 10 | FlutterAds 致力于构建优质的 Flutter 广告插件 11 | DESC 12 | s.homepage = 'https://github.com/FlutterAds' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'ZeroFlutter' => '1300326388@qq.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.public_header_files = 'Classes/**/*.h' 18 | s.dependency 'Flutter' 19 | # 这里仅加载 framework,在 Podfile 中加载 Ads-Mediation-CN 要去掉 framework 的加载,防止冲突 20 | # s.vendored_frameworks = 'Frameworks/Ads-Mediation-CN/Ads-Mediation-CN/ABUAdSDK.framework' 21 | # 依赖地址:https://github.com/CocoaPods/Specs/tree/master/Specs/9/b/0/Ads-Fusion-CN-Beta/ 22 | s.dependency 'Ads-Fusion-CN-Beta', '5.9.1.5' 23 | s.platform = :ios, '9.0' 24 | s.static_framework = true 25 | # Flutter.framework does not contain a i386 slice. 26 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 27 | 28 | end 29 | -------------------------------------------------------------------------------- /lib/event/ad_error_event.dart: -------------------------------------------------------------------------------- 1 | import 'ad_event.dart'; 2 | 3 | /// 广告错误事件 4 | class AdErrorEvent extends AdEvent { 5 | AdErrorEvent({ 6 | required String adId, 7 | required String action, 8 | required this.errCode, 9 | this.errMsg, 10 | }) : super(adId: adId, action: action); 11 | // 错误码 12 | final int errCode; 13 | // 错误信息 14 | final String? errMsg; 15 | // 解析 json 为错误事件对象 16 | factory AdErrorEvent.fromJson(Map json) { 17 | return AdErrorEvent( 18 | adId: json['adId'], 19 | action: json['action'], 20 | errCode: json['errCode'], 21 | errMsg: json['errMsg'], 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/event/ad_event.dart: -------------------------------------------------------------------------------- 1 | import 'ad_error_event.dart'; 2 | import 'ad_event_action.dart'; 3 | import 'ad_reward_event.dart'; 4 | export 'ad_error_event.dart'; 5 | export 'ad_event_action.dart'; 6 | export 'ad_reward_event.dart'; 7 | 8 | /// 广告事件 9 | class AdEvent { 10 | AdEvent({required this.adId, required this.action}); 11 | // 广告 id 12 | final String adId; 13 | // 操作 14 | final String action; 15 | 16 | /// 解析 AdEvent 17 | factory AdEvent.fromJson(Map json) { 18 | String action = json['action']; 19 | if (action == AdEventAction.onAdError) { 20 | return AdErrorEvent.fromJson(json); 21 | } else if (action == AdEventAction.onAdReward) { 22 | return AdRewardEvent.fromJson(json); 23 | } else { 24 | return AdEvent( 25 | adId: json['adId'], 26 | action: action, 27 | ); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/event/ad_event_action.dart: -------------------------------------------------------------------------------- 1 | /// 广告事件操作 2 | class AdEventAction { 3 | // 广告错误 4 | static const String onAdError = "onAdError"; 5 | // 广告加载成功 6 | static const String onAdLoaded = "onAdLoaded"; 7 | // 广告填充 8 | static const String onAdPresent = "onAdPresent"; 9 | // 广告曝光 10 | static const String onAdExposure = "onAdExposure"; 11 | // 广告关闭(计时结束或者用户点击关闭) 12 | static const String onAdClosed = "onAdClosed"; 13 | // 广告点击 14 | static const String onAdClicked = "onAdClicked"; 15 | // 广告跳过 16 | static const String onAdSkip = "onAdSkip"; 17 | // 广告播放或计时完毕 18 | static const String onAdComplete = "onAdComplete"; 19 | // 获得广告激励 20 | static const String onAdReward = "onAdReward"; 21 | } 22 | -------------------------------------------------------------------------------- /lib/event/ad_event_handler.dart: -------------------------------------------------------------------------------- 1 | import 'ad_event.dart'; 2 | export 'ad_event.dart'; 3 | 4 | /// 广告事件回调监听 5 | typedef OnAdEventListener = void Function(AdEvent event); 6 | 7 | /// 处理广告事件 8 | void hanleAdEvent(dynamic data, OnAdEventListener listener) { 9 | if (data != null) { 10 | AdEvent adEvent = AdEvent.fromJson(data); 11 | listener.call(adEvent); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/event/ad_reward_event.dart: -------------------------------------------------------------------------------- 1 | import 'ad_event.dart'; 2 | 3 | /// 广告激励事件 4 | class AdRewardEvent extends AdEvent { 5 | AdRewardEvent( 6 | {required this.rewardVerify, 7 | required this.rewardAmount, 8 | required this.rewardName, 9 | this.errCode, 10 | this.errMsg, 11 | this.customData, 12 | this.userId, 13 | required String adId, 14 | required String action}) 15 | : super(adId: adId, action: action); 16 | // 奖励是否有效 17 | final bool rewardVerify; 18 | // 奖励数量 19 | final int rewardAmount; 20 | // 奖励名称 21 | final String rewardName; 22 | // 错误码 23 | final int? errCode; 24 | // 错误信息 25 | final String? errMsg; 26 | // 服务端验证的自定义信息 27 | final String? customData; 28 | // 服务端验证的用户信息 29 | final String? userId; 30 | // 解析 json 为激励事件对象 31 | factory AdRewardEvent.fromJson(Map json) { 32 | return AdRewardEvent( 33 | adId: json['adId'], 34 | action: json['action'], 35 | rewardVerify: json['rewardVerify'], 36 | rewardAmount: json['rewardAmount'], 37 | rewardName: json['rewardName'], 38 | errCode: json['errCode'], 39 | errMsg: json['errMsg'], 40 | customData: json['customData'], 41 | userId: json['userId'], 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/flutter_gromore_ads.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'flutter_gromore_ads_platform_interface.dart'; 3 | import 'event/ad_event_handler.dart'; 4 | 5 | export 'event/ad_event_handler.dart'; 6 | export 'view/ad_banner_widget.dart'; 7 | 8 | /// GroMore 广告插件 9 | class FlutterGromoreAds { 10 | ///事件回调 11 | ///@params onData 事件回调 12 | static Future onEventListener( 13 | OnAdEventListener onAdEventListener) async { 14 | FlutterGromoreAdsPlatform.instance.getEventStream().listen((data) { 15 | hanleAdEvent(data, onAdEventListener); 16 | }); 17 | } 18 | 19 | /// 请求应用跟踪透明度授权(仅 iOS) 20 | static Future get requestIDFA async { 21 | if (Platform.isIOS) { 22 | return FlutterGromoreAdsPlatform.instance.requestIDFA(); 23 | } 24 | return true; 25 | } 26 | 27 | /// 动态请求相关权限(仅 Android) 28 | static Future get requestPermissionIfNecessary async { 29 | if (Platform.isAndroid) { 30 | return FlutterGromoreAdsPlatform.instance.requestPermissionIfNecessary(); 31 | } 32 | return true; 33 | } 34 | 35 | /// 初始化广告 36 | /// [appId] 应用ID 37 | /// [config] 配置文件名称 38 | /// [limitPersonalAds] 是否限制个性化广告,0:不限制 1:限制 39 | static Future initAd(String appId, 40 | {String? config, int limitPersonalAds = 0}) { 41 | return FlutterGromoreAdsPlatform.instance.initAd( 42 | appId, 43 | config: config, 44 | limitPersonalAds: limitPersonalAds, 45 | ); 46 | } 47 | 48 | /// 展示开屏广告 49 | /// [posId] 广告位 id 50 | /// [logo] 如果传值则展示底部logo,不传不展示,则全屏展示 51 | /// [timeout] 加载超时时间 52 | static Future showSplashAd(String posId, 53 | {String? logo, double timeout = 3.5}) { 54 | return FlutterGromoreAdsPlatform.instance.showSplashAd( 55 | posId, 56 | logo: logo, 57 | timeout: timeout, 58 | ); 59 | } 60 | 61 | /// 展示插屏广告 62 | /// [posId] 广告位 id 63 | static Future showInterstitialAd(String posId) { 64 | return FlutterGromoreAdsPlatform.instance.showInterstitialAd(posId); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/flutter_gromore_ads_method_channel.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'flutter_gromore_ads_platform_interface.dart'; 4 | 5 | class MethodChannelFlutterGromoreAds extends FlutterGromoreAdsPlatform { 6 | @visibleForTesting 7 | final methodChannel = const MethodChannel('flutter_gromore_ads'); 8 | 9 | @visibleForTesting 10 | final eventChannel = const EventChannel('flutter_gromore_ads_event'); 11 | 12 | @override 13 | Future requestIDFA() async { 14 | final bool result = await methodChannel.invokeMethod('requestIDFA'); 15 | return result; 16 | } 17 | 18 | @override 19 | Future requestPermissionIfNecessary() async { 20 | final bool result = 21 | await methodChannel.invokeMethod('requestPermissionIfNecessary'); 22 | return result; 23 | } 24 | 25 | @override 26 | Future initAd(String appId, 27 | {String? config, int limitPersonalAds = 0}) async { 28 | final bool result = await methodChannel.invokeMethod( 29 | 'initAd', 30 | { 31 | 'appId': appId, 32 | 'config': config, 33 | 'limitPersonalAds': limitPersonalAds, 34 | }, 35 | ); 36 | print( 37 | "🎉🎉🎉 FlutterAds ==> 初始化完成,推荐使用 GroMore Pro 版本,获得更高的收益:https://flutterads.top/"); 38 | //打印购买正版 39 | print( 40 | "🎉🎉🎉 FlutterAds ==> 请购买支持正版,否则可能出现上线后广告不加载的情况,避免收益下降、不结算等情况,请访问:https://flutterads.top/"); 41 | return result; 42 | } 43 | 44 | @override 45 | Future showSplashAd(String posId, 46 | {String? logo, double timeout = 3.5}) async { 47 | final bool result = await methodChannel.invokeMethod( 48 | 'showSplashAd', 49 | { 50 | 'posId': posId, 51 | 'logo': logo, 52 | 'timeout': timeout, 53 | }, 54 | ); 55 | return result; 56 | } 57 | 58 | @override 59 | Future showInterstitialAd(String posId) async { 60 | final bool result = await methodChannel.invokeMethod( 61 | 'showInterstitialAd', 62 | {'posId': posId}, 63 | ); 64 | return result; 65 | } 66 | 67 | @override 68 | Stream getEventStream() { 69 | return eventChannel.receiveBroadcastStream(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/flutter_gromore_ads_platform_interface.dart: -------------------------------------------------------------------------------- 1 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 2 | import 'flutter_gromore_ads_method_channel.dart'; 3 | 4 | abstract class FlutterGromoreAdsPlatform extends PlatformInterface { 5 | FlutterGromoreAdsPlatform() : super(token: _token); 6 | 7 | static final Object _token = Object(); 8 | 9 | static FlutterGromoreAdsPlatform _instance = MethodChannelFlutterGromoreAds(); 10 | 11 | static FlutterGromoreAdsPlatform get instance => _instance; 12 | 13 | static set instance(FlutterGromoreAdsPlatform instance) { 14 | PlatformInterface.verifyToken(instance, _token); 15 | _instance = instance; 16 | } 17 | 18 | Future requestIDFA() { 19 | throw UnimplementedError('requestIDFA() has not been implemented.'); 20 | } 21 | 22 | Future requestPermissionIfNecessary() { 23 | throw UnimplementedError( 24 | 'requestPermissionIfNecessary() has not been implemented.'); 25 | } 26 | 27 | Future initAd(String appId, 28 | {String? config, int limitPersonalAds = 0}) { 29 | throw UnimplementedError('initAd() has not been implemented.'); 30 | } 31 | 32 | Future showSplashAd(String posId, 33 | {String? logo, double timeout = 3.5}) { 34 | throw UnimplementedError('showSplashAd() has not been implemented.'); 35 | } 36 | 37 | Future showInterstitialAd(String posId) { 38 | throw UnimplementedError('showInterstitialAd() has not been implemented.'); 39 | } 40 | 41 | Stream getEventStream() { 42 | throw UnimplementedError('getEventStream() has not been implemented.'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/view/ad_banner_widget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/services.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | 6 | /// Banner 广告组件 7 | class AdBannerWidget extends StatefulWidget { 8 | const AdBannerWidget({ 9 | Key? key, 10 | required this.posId, 11 | this.width = 300, 12 | this.height = 150, 13 | this.show = true, 14 | }) : super(key: key); 15 | // 广告 id 16 | final String posId; 17 | // 创建 Banner 广告位时选择的宽度,默认值是 300 18 | final int width; 19 | // 创建 Banner 广告位时选择的高度,默认值是 150 20 | final int height; 21 | // 是否显示广告 22 | final bool show; 23 | 24 | @override 25 | _AdBannerWidgetState createState() => _AdBannerWidgetState(); 26 | } 27 | 28 | class _AdBannerWidgetState extends State 29 | with AutomaticKeepAliveClientMixin { 30 | // View 类型 31 | final String viewType = 'flutter_gromore_ads_banner'; 32 | // 创建参数 33 | late Map creationParams; 34 | 35 | @override 36 | void initState() { 37 | creationParams = { 38 | "posId": widget.posId, 39 | "width": widget.width, 40 | "height": widget.height, 41 | }; 42 | super.initState(); 43 | } 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | super.build(context); 48 | if (!widget.show) { 49 | return const SizedBox.shrink(); 50 | } 51 | if (Platform.isIOS) { 52 | return SizedBox.fromSize( 53 | size: Size(widget.width.toDouble(), widget.height.toDouble()), 54 | child: UiKitView( 55 | viewType: viewType, 56 | creationParams: creationParams, 57 | creationParamsCodec: const StandardMessageCodec(), 58 | ), 59 | ); 60 | } else { 61 | return SizedBox.fromSize( 62 | size: Size(widget.width.toDouble(), widget.height.toDouble()), 63 | child: AndroidView( 64 | viewType: viewType, 65 | creationParams: creationParams, 66 | creationParamsCodec: const StandardMessageCodec(), 67 | ), 68 | ); 69 | } 70 | } 71 | 72 | @override 73 | bool get wantKeepAlive => true; 74 | } 75 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_gromore_ads 2 | description: 【持续更新】一款优质的穿山甲 GroMore 聚合 Flutter 广告插件,支持 Android、iOS 平台,可快速接入进行广告变现。 3 | version: 3.2.0 4 | homepage: https://flutterads.top 5 | repository: https://github.com/FlutterAds/flutter_gromore_ads 6 | issue_tracker: https://github.com/FlutterAds/flutter_gromore_ads/issues 7 | documentation: https://github.com/FlutterAds/flutter_gromore_ads/wiki 8 | topics: [flutterads, ads, gromore, pangle, income] 9 | funding: [https://github.com/FlutterAds/.github] 10 | 11 | environment: 12 | sdk: ">=2.12.0 <4.0.0" 13 | flutter: ">=2.5.0" 14 | 15 | dependencies: 16 | flutter: 17 | sdk: flutter 18 | plugin_platform_interface: ^2.0.2 19 | 20 | dev_dependencies: 21 | flutter_test: 22 | sdk: flutter 23 | # The following section is specific to Flutter. 24 | flutter: 25 | plugin: 26 | platforms: 27 | android: 28 | package: com.zero.flutter_gromore_ads 29 | pluginClass: FlutterGromoreAdsPlugin 30 | ios: 31 | pluginClass: FlutterGromoreAdsPlugin 32 | -------------------------------------------------------------------------------- /test/flutter_gromore_ads_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | --------------------------------------------------------------------------------