├── .gitattributes
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── proguard-rules.pro
├── settings.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── kotlin
│ └── com
│ │ └── gstory
│ │ └── flutter_tencentad
│ │ ├── DownloadApkConfirmDialog.java
│ │ ├── DownloadConfirmHelper.java
│ │ ├── FlutterTencentAdConfig.kt
│ │ ├── FlutterTencentAdEventPlugin.kt
│ │ ├── FlutterTencentAdViewPlugin.kt
│ │ ├── FlutterTencentadPlugin.kt
│ │ ├── LogUtil.kt
│ │ ├── UIUtils.kt
│ │ ├── bannerad
│ │ ├── BannerAdView.kt
│ │ └── BannerAdViewFactory.kt
│ │ ├── expressad
│ │ ├── NativeExpressAdView.kt
│ │ └── NativeExpressAdViewFactory.kt
│ │ ├── interstitialad
│ │ └── InterstitialAd.kt
│ │ ├── rewardvideoad
│ │ └── RewardVideoAd.kt
│ │ └── splashad
│ │ ├── SplashAdView.kt
│ │ └── SplashAdViewFactory.kt
│ └── res
│ ├── anim
│ ├── download_confirm_dialog_slide_right_in.xml
│ └── download_confirm_dialog_slide_up.xml
│ ├── drawable
│ ├── download_confirm_background_confirm.xml
│ ├── download_confirm_background_landscape.xml
│ ├── download_confirm_background_portrait.xml
│ └── ic_download_confirm_close.xml
│ ├── layout
│ └── download_confirm_dialog.xml
│ └── values
│ └── styles.xml
├── error.md
├── example
├── .gitignore
├── .metadata
├── README.md
├── analysis_options.yaml
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── gstory
│ │ │ │ │ └── flutter_tencentad_example
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable-v21
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── values-night
│ │ │ │ └── styles.xml
│ │ │ │ └── values
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Podfile.lock
│ ├── 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-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── main.m
├── lib
│ ├── banner_page.dart
│ ├── express_page.dart
│ ├── main.dart
│ └── splash_page.dart
├── pubspec.lock
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── images
├── tencentad.gif
└── weixin.jpg
├── ios
├── .gitignore
├── Assets
│ └── .gitkeep
├── Classes
│ ├── FlutterTencentadPlugin.h
│ ├── FlutterTencentadPlugin.m
│ ├── banner
│ │ ├── BannerAd.h
│ │ └── BannerAd.m
│ ├── event
│ │ ├── FlutterTencentAdEvent.h
│ │ └── FlutterTencentAdEvent.m
│ ├── insert
│ │ ├── InsertAd.h
│ │ └── InsertAd.m
│ ├── native
│ │ ├── NativeAd.h
│ │ └── NativeAd.m
│ ├── reward
│ │ ├── RewardAd.h
│ │ └── RewardAd.m
│ ├── splash
│ │ ├── SplashAd.h
│ │ └── SplashAd.m
│ └── utils
│ │ ├── TLogUtil.h
│ │ ├── TLogUtil.m
│ │ ├── TUIViewController+getCurrentVC.h
│ │ └── TUIViewController+getCurrentVC.m
└── flutter_tencentad.podspec
├── lib
├── banner
│ └── banner_ad_view.dart
├── express
│ └── express_ad_view.dart
├── flutter_tencentad.dart
├── flutter_tencentad_bidding_controller.dart
├── flutter_tencentad_callback.dart
├── flutter_tencentad_code.dart.dart
├── flutter_tencentad_stream.dart
└── splash
│ └── splash_ad_view.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── flutter_tencentad_test.dart
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.kt linguist-language=dart
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # Visual Studio Code related
19 | .vscode/
20 |
21 | # Flutter/Dart/Pub related
22 | **/doc/api/
23 | .dart_tool/
24 | .flutter-plugins
25 | .flutter-plugins-dependencies
26 | .packages
27 | .pub-cache/
28 | .pub/
29 | /build/
30 |
31 | # Android related
32 | **/android/**/gradle-wrapper.jar
33 | **/android/.gradle
34 | **/android/captures/
35 | **/android/gradlew
36 | **/android/gradlew.bat
37 | **/android/local.properties
38 | **/android/**/GeneratedPluginRegistrant.java
39 | **/android/key/
40 |
41 | # iOS/XCode related
42 | **/ios/**/*.mode1v3
43 | **/ios/**/*.mode2v3
44 | **/ios/**/*.moved-aside
45 | **/ios/**/*.pbxuser
46 | **/ios/**/*.perspectivev3
47 | **/ios/**/*sync/
48 | **/ios/**/.sconsign.dblite
49 | **/ios/**/.tags*
50 | **/ios/**/.vagrant/
51 | **/ios/**/DerivedData/
52 | **/ios/**/Icon?
53 | **/ios/**/Pods/
54 | **/ios/**/.symlinks/
55 | **/ios/**/profile
56 | **/ios/**/xcuserdata
57 | **/ios/.generated/
58 | **/ios/Flutter/App.framework
59 | **/ios/Flutter/Flutter.framework
60 | **/ios/Flutter/Generated.xcconfig
61 | **/ios/Flutter/app.flx
62 | **/ios/Flutter/app.zip
63 | **/ios/Flutter/flutter_assets/
64 | **/ios/ServiceDefinitions.json
65 | **/ios/Runner/GeneratedPluginRegistrant.*
66 |
67 | # Exceptions to above rules.
68 | !**/ios/**/default.mode1v3
69 | !**/ios/**/default.mode2v3
70 | !**/ios/**/default.pbxuser
71 | !**/ios/**/default.perspectivev3
72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: f4abaa0735eba4dfd8f33f73363911d63931fe03
8 | channel: stable
9 |
10 | project_type: plugin
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.2.35
2 | * android sdk升级4.640.1510
3 | * ios sdk升级4.15.40
4 | * 优化ios激励广告监听
5 |
6 | ## 1.2.34
7 | * android sdk升级4.630.1500
8 | * ios sdk升级4.15.30
9 |
10 | ## 1.2.33
11 | * ios sdk升级4.15.22
12 |
13 | ## 1.2.32
14 | * ios sdk回退4.15.10
15 |
16 | ## 1.2.31
17 | * android sdk升级4.620.1490
18 | * ios sdk升级4.15.21
19 |
20 | ## 1.2.30
21 | * 修复ios sdk中包路径问题
22 |
23 | ## 1.2.29
24 | * android sdk升级4.611.1481
25 | * ios sdk升级4.15.20
26 | * android隐私权限修改
27 |
28 | ## 1.2.28
29 | * android高版本兼容
30 |
31 | ## 1.2.27
32 | * android升级4.610.1480
33 |
34 |
35 | ## 1.2.26
36 | * 新增安卓隐私合规,是否开启收集应用安装状态(感谢@[langyuxiansheng](https://github.com/langyuxiansheng) pr)
37 |
38 | ## 1.2.25
39 | * android增加namespace
40 |
41 |
42 | ## 1.2.24
43 | * android更新4.603.1473
44 | * ios更新4.15.10
45 |
46 | ## 1.2.23
47 | * android更新4.600.1470
48 | * ios更新4.15.00
49 | * 初始化新增android隐私设置androidPrivacy
50 |
51 | ## 1.2.22
52 | * android更新4.591.1461
53 | * ios更新4.14.90
54 |
55 | ## 1.2.21
56 | * android升级4.562.1432
57 | * ios升级4.14.63
58 |
59 | ## 1.2.19
60 | * android升级4.542.1412
61 | * ios升级4.14.45
62 |
63 | ## 1.2.19
64 | * android升级4.541.1411
65 | * ios升级4.14.42
66 | * loadRewardVideoAd激励广告新增videoMuted控制视频是否静音播放
67 |
68 | ## 1.2.18
69 | * android升级4.540.1410
70 |
71 | ## 1.2.17
72 | * android升级4.531.1401
73 | * ios升级4.14.32
74 |
75 | ## 1.2.16
76 | * android kt升级1.6.10 gradle插件7.1.2
77 |
78 | ## 1.2.15
79 | * android升级4.530.1400
80 | * ios升级4.14.30
81 |
82 | ## 1.2.14
83 | * android升级4.510.1380
84 | * ios升级4.14.10
85 |
86 | ## 1.2.13
87 | * 修复ios banner广告无法加载
88 |
89 | ## 1.2.12
90 | * android 升级4.500.1370
91 | * iOS 升级4.14.01
92 |
93 | * ## 1.2.11
94 | * android升级4.492.1362 兼容13
95 |
96 | ## 1.2.10
97 | * fix bug
98 |
99 | ## 1.2.8
100 | * android升级4.490.1361
101 | * fix bug
102 |
103 | ## 1.2.7
104 | * android升级4.490.1360
105 | * ios升级4.13.90
106 |
107 | ## 1.2.6
108 | * fix bug
109 | * ios升级4.13.83
110 |
111 | ## 1.2.5
112 | * fix bug
113 |
114 |
115 | ## 1.2.4
116 | * 支持bidding模式
117 |
118 |
119 | ## 1.2.3
120 | * ios错误日志优化
121 |
122 | ## 1.2.2
123 | * android升级[4.482.1352](https://developers.adnet.qq.com/doc/android/union/union_version)
124 | * ios升级[4.13.81](https://developers.adnet.qq.com/doc/ios/union/union_version)
125 | *
126 | ## 1.2.1
127 | * android升级[4.13.65](https://developers.adnet.qq.com/doc/android/union/union_version)
128 | * ios升级[4.13.65](https://developers.adnet.qq.com/doc/ios/union/union_version)
129 |
130 | ## 1.2.0
131 | * 兼容Flutter3.0
132 | * ios升级4.13.65
133 |
134 | ## 1.1.7
135 | * 修复与flutter_pangrowth文件冲突问题
136 |
137 | ## 1.1.6
138 | * 降低andorid编译版本
139 |
140 | ## 1.1.5
141 | *Android sdk升级4.460.1330
142 | *iOS sdk升级4.13.62
143 |
144 | ## 1.1.4
145 | * android sdk升级4.441.1311聚合
146 | * ios sdk升级4.13.41聚合
147 |
148 | ## 1.1.3
149 | * 优化插屏激励广告
150 |
151 | ## 1.1.2
152 | * 修复参数异常
153 |
154 | ## 1.1.1
155 |
156 | * android sdk升级4.440.1310
157 | * ios sdk升级4.13.40
158 | * FlutterTencentad.register新增参数
159 | ```
160 | channelId 渠道id [FlutterTencentadChannel]
161 | personalized 是否开启个性化广告 [FlutterTencentadPersonalized]
162 | ```
163 | * FlutterTencentadInteractionCallBack插屏广告回调新增激励奖励凭证id回调
164 | ```dart
165 | FlutterTencentadInteractionCallBack(
166 | onVerify: (transId,rewardName,rewardAmount){
167 | print("广告奖励凭证id $transId");
168 | }
169 | ),
170 | ```
171 |
172 | ## 1.1.0
173 |
174 | * 1、ios部分使用OC重写
175 | * 2、android sdk升级4.431.1301
176 | * 3、ios sdk升级4.13.32
177 |
178 | ## 1.0.5
179 |
180 | * 1、升级sdk版本
181 |
182 |
183 | ## 1.0.4
184 |
185 | * 1、修复ios激励广告穿透参数
186 |
187 |
188 | ## 1.0.3
189 |
190 | * 1、优化api
191 | * 2、升级sdk版本
192 |
193 |
194 | ## 1.0.2
195 |
196 | * 1、优化api
197 | * 2、fix bug
198 |
199 |
200 | ## 1.0.1
201 |
202 | * 1、新增激励广告扩展参数
203 | * 2、fix bug
204 |
205 | ## 1.0.0
206 |
207 | * 1、增加ios端广告
208 | * 2、优化api
209 |
210 | ## 0.0.6
211 |
212 | * 1、优化API
213 |
214 | ## 0.0.5
215 |
216 | * 1、优化API
217 |
218 | ## 0.0.4
219 |
220 | * 1、优化动态信息流/横幅/视频贴片广告加载方式
221 |
222 | ## 0.0.3
223 |
224 | * 1、fix bug
225 |
226 |
227 | ## 0.0.2
228 |
229 | * 1、完善android 激励广告、开屏广告、banner广告、动态信息流/横幅/视频贴片广告
230 |
231 | ## 0.0.1
232 |
233 | * Describe initial release.
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
3 | # Additional information about this file can be found at
4 | # https://dart.dev/guides/language/analysis-options
5 |
--------------------------------------------------------------------------------
/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.gstory.flutter_tencentad'
2 | version '1.0-SNAPSHOT'
3 |
4 | buildscript {
5 | ext.kotlin_version = '1.6.10'
6 | repositories {
7 | google()
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:7.1.2'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | }
15 | }
16 |
17 | rootProject.allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 | flatDir {
22 | dirs project(':flutter_tencentad').file('libs')
23 | }
24 | }
25 | }
26 |
27 | apply plugin: 'com.android.library'
28 | apply plugin: 'kotlin-android'
29 |
30 | android {
31 | namespace = "com.gstory.flutter_tencentad"
32 | compileSdkVersion 31
33 |
34 | compileOptions {
35 | sourceCompatibility JavaVersion.VERSION_1_8
36 | targetCompatibility JavaVersion.VERSION_1_8
37 | }
38 |
39 | kotlinOptions {
40 | jvmTarget = '1.8'
41 | }
42 |
43 | sourceSets {
44 | main.java.srcDirs += 'src/main/kotlin'
45 | }
46 | defaultConfig {
47 | minSdkVersion 16
48 | }
49 | lintOptions {
50 | disable 'InvalidPackage'
51 | }
52 | }
53 |
54 | repositories {
55 | flatDir {
56 | dirs 'libs'
57 | }
58 | }
59 |
60 | dependencies {
61 | api fileTree(dir: 'libs', include: ['*.jar'])
62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
63 | implementation 'com.qq.e.union:union:4.640.1510'
64 | // implementation(name: 'GDTSDK.unionNormal.4.611.1481', ext: 'aar')
65 | // implementation 'com.qq.e.union:tools:+'
66 | }
67 |
--------------------------------------------------------------------------------
/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-5.6.2-all.zip
6 |
--------------------------------------------------------------------------------
/android/proguard-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/android/proguard-rules.pro
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'flutter_tencentad'
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
11 |
14 |
15 |
16 |
21 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/DownloadApkConfirmDialog.java:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.content.res.Configuration;
7 | import android.text.TextUtils;
8 | import android.util.Log;
9 | import android.view.Gravity;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.view.Window;
13 | import android.view.WindowManager;
14 | import android.webkit.WebResourceError;
15 | import android.webkit.WebResourceRequest;
16 | import android.webkit.WebView;
17 | import android.webkit.WebViewClient;
18 | import android.widget.Button;
19 | import android.widget.FrameLayout;
20 | import android.widget.ImageView;
21 | import android.widget.ProgressBar;
22 |
23 | import com.qq.e.comm.compliance.DownloadConfirmCallBack;
24 |
25 |
26 | public class DownloadApkConfirmDialog extends Dialog implements View.OnClickListener {
27 | private static final String TAG = "ConfirmDialogWebView";
28 | private Context context;
29 | private int orientation;
30 | private DownloadConfirmCallBack callBack;
31 | private WebView webView;
32 | private ImageView close;
33 | private Button confirm;
34 |
35 | private ViewGroup contentHolder;
36 | private ProgressBar loadingBar;
37 | private Button reloadButton;
38 |
39 | private String url;
40 | private boolean urlLoadError = false;
41 |
42 | private static final String RELOAD_TEXT = "重新加载";
43 | private static final String LOAD_ERROR_TEXT = "抱歉,应用信息获取失败";
44 |
45 | public DownloadApkConfirmDialog(Context context, String infoUrl,
46 | DownloadConfirmCallBack callBack) {
47 | super(context, R.style.DownloadConfirmDialogFullScreen);//需要全屏显示,同时显示非窗口蒙版
48 | this.context = context;
49 | this.callBack = callBack;
50 | this.url = infoUrl;
51 | orientation = context.getResources().getConfiguration().orientation;
52 | requestWindowFeature(Window.FEATURE_NO_TITLE);
53 | setCanceledOnTouchOutside(true);
54 | initView();
55 | }
56 |
57 | private void initView() {
58 | setContentView(R.layout.download_confirm_dialog);
59 | View root = findViewById(R.id.download_confirm_root);
60 | if (orientation == Configuration.ORIENTATION_PORTRAIT) {
61 | root.setBackgroundResource(R.drawable.download_confirm_background_portrait);
62 | } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
63 | root.setBackgroundResource(R.drawable.download_confirm_background_landscape);
64 | }
65 | close = findViewById(R.id.download_confirm_close);
66 | close.setOnClickListener(this);
67 | reloadButton = findViewById(R.id.download_confirm_reload_button);
68 | reloadButton.setOnClickListener(this);
69 | confirm = findViewById(R.id.download_confirm_confirm);
70 | confirm.setOnClickListener(this);
71 | loadingBar = findViewById(R.id.download_confirm_progress_bar);
72 | contentHolder = findViewById(R.id.download_confirm_content);
73 | createTextView();
74 | }
75 |
76 | private void createTextView(){
77 | FrameLayout layout = findViewById(R.id.download_confirm_holder);
78 | webView = new WebView(context);
79 | webView.getSettings().setJavaScriptEnabled(true);
80 | webView.setWebViewClient(new Client());
81 | layout.addView(webView);
82 | }
83 | @Override
84 | public void show() {
85 | super.show();
86 | try {
87 | loadUrl(url);
88 | } catch (Exception e) {
89 | Log.e(DownloadApkConfirmDialog.TAG, "load error url:" + url, e);
90 | }
91 | }
92 |
93 |
94 | private void loadUrl(String url) {
95 | if (TextUtils.isEmpty(url)) {
96 | loadingBar.setVisibility(View.GONE);
97 | contentHolder.setVisibility(View.GONE);
98 | reloadButton.setVisibility(View.VISIBLE);
99 | reloadButton.setText(LOAD_ERROR_TEXT);
100 | reloadButton.setEnabled(false);
101 | return;
102 | }
103 | urlLoadError = false;
104 | Log.d(TAG, "download confirm load url:" + url);
105 | webView.loadUrl(url);
106 | }
107 |
108 | public void setInstallTip() {
109 | confirm.setText("立即安装");
110 | }
111 |
112 | @Override
113 | protected void onStart() {
114 | int height = (int) UIUtils.INSTANCE.getScreenHeight(context);
115 | int width =(int) UIUtils.INSTANCE.getScreenWidth(context);
116 | Window window = getWindow();
117 | window.getDecorView().setPadding(0, 0, 0, 0);
118 | WindowManager.LayoutParams layoutParams = window.getAttributes();
119 | if (orientation == Configuration.ORIENTATION_PORTRAIT) {
120 | layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
121 | layoutParams.height = (int) (height * 0.6);
122 | layoutParams.gravity = Gravity.BOTTOM;
123 | layoutParams.windowAnimations = R.style.DownloadConfirmDialogAnimationUp;
124 | } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
125 | layoutParams.width = (int) (width * 0.5);
126 | layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
127 | layoutParams.gravity = Gravity.RIGHT;
128 | layoutParams.windowAnimations = R.style.DownloadConfirmDialogAnimationRight;
129 | }
130 | //弹窗外区域蒙版50%透明度
131 | layoutParams.dimAmount = 0.5f;
132 |
133 | //resume后动画会重复,在显示出来后重置无动画
134 | window.setAttributes(layoutParams);
135 | setOnShowListener(new OnShowListener() {
136 | @Override
137 | public void onShow(DialogInterface dialog) {
138 | try {
139 | Window window = getWindow();
140 | window.setWindowAnimations(0);
141 | } catch (Throwable t) {
142 | }
143 | }
144 | });
145 | }
146 |
147 | @Override
148 | public void onClick(View v) {
149 | if (v == close) {
150 | if (callBack != null) {
151 | callBack.onCancel();
152 | }
153 | dismiss();
154 | } else if (v == confirm) {
155 | if (callBack != null) {
156 | callBack.onConfirm();
157 | }
158 | dismiss();
159 | } else if (v == reloadButton) {
160 | loadUrl(url);
161 | }
162 |
163 | }
164 |
165 | @Override
166 | public void cancel() {
167 | super.cancel();
168 | if (callBack != null) {
169 | callBack.onCancel();
170 | }
171 | }
172 |
173 | class Client extends WebViewClient {
174 | @Override
175 | public void onPageFinished(WebView view, String url) {
176 | super.onPageFinished(view, url);
177 | if (!urlLoadError) {
178 | loadingBar.setVisibility(View.GONE);
179 | reloadButton.setVisibility(View.GONE);
180 | contentHolder.setVisibility(View.VISIBLE);
181 | }
182 | }
183 |
184 | @Override
185 | public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
186 | super.onReceivedError(view, request, error);
187 | Log.d(TAG, "doConfirmWithInfo onReceivedError:" + error + " " + request);
188 | urlLoadError = true;
189 | loadingBar.setVisibility(View.GONE);
190 | contentHolder.setVisibility(View.GONE);
191 | reloadButton.setVisibility(View.VISIBLE);
192 | reloadButton.setText(RELOAD_TEXT);
193 | reloadButton.setEnabled(true);
194 | }
195 | }
196 |
197 |
198 | }
199 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/FlutterTencentAdConfig.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad
2 |
3 | /**
4 | * @Description: 描述
5 | * @Author: gstory
6 | * @CreateDate: 2021/8/7 17:49
7 | **/
8 | class FlutterTencentAdConfig {
9 |
10 | companion object {
11 | //event事件
12 | const val adevent = "com.gstory.flutter_tencentad/adevent"
13 | //BannerAdView
14 | const val bannerAdView = "com.gstory.flutter_tencentad/BannerAdView"
15 | //SplashAdView
16 | const val splashAdView = "com.gstory.flutter_tencentad/SplashAdView"
17 | //NativeExpressADView
18 | const val nativeAdView = "com.gstory.flutter_tencentad/NativeExpressAdView"
19 | }
20 | }
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/FlutterTencentAdEventPlugin.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_unionad
2 |
3 | import android.content.Context
4 | import com.gstory.flutter_tencentad.FlutterTencentAdConfig
5 | import io.flutter.embedding.engine.plugins.FlutterPlugin
6 | import io.flutter.plugin.common.EventChannel
7 |
8 | /**
9 | * @Description:
10 | * @Author: gstory0404@gmail
11 | * @CreateDate: 2020/8/19 18:52
12 | */
13 | class FlutterTencentAdEventPlugin : FlutterPlugin, EventChannel.StreamHandler {
14 |
15 | companion object {
16 | private var eventChannel: EventChannel? = null
17 |
18 | private var eventSink: EventChannel.EventSink? = null
19 |
20 | private var context: Context? = null
21 |
22 | fun sendContent(content: MutableMap) {
23 | eventSink?.success(content);
24 | }
25 | }
26 |
27 | override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
28 | eventSink = events
29 | }
30 |
31 | override fun onCancel(arguments: Any?) {
32 | eventSink = null
33 | }
34 |
35 | override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
36 | eventChannel = EventChannel(binding.binaryMessenger, FlutterTencentAdConfig.adevent)
37 | eventChannel!!.setStreamHandler(this)
38 | context = binding.applicationContext
39 | }
40 |
41 | override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
42 | eventChannel = null
43 | eventChannel!!.setStreamHandler(null)
44 | }
45 | }
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/FlutterTencentAdViewPlugin.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad
2 |
3 | import android.app.Activity
4 | import com.gstory.flutter_tencentad.bannerad.BannerAdViewFactory
5 | import com.gstory.flutter_tencentad.expressad.NativeExpressAdViewFactory
6 | import com.gstory.flutter_tencentad.splashad.SplashAdViewFactory
7 | import io.flutter.embedding.engine.plugins.FlutterPlugin
8 |
9 | /**
10 | * @Description:
11 | * @Author: gstory0404@gmail
12 | * @CreateDate: 2021/8/7 11:38
13 | */
14 |
15 | object FlutterTencentAdViewPlugin {
16 | fun registerWith(binding: FlutterPlugin.FlutterPluginBinding, activity: Activity) {
17 | //注册banner广告
18 | binding.platformViewRegistry.registerViewFactory(FlutterTencentAdConfig.bannerAdView, BannerAdViewFactory(binding.binaryMessenger, activity))
19 | //注册splash广告
20 | binding.platformViewRegistry.registerViewFactory(FlutterTencentAdConfig.splashAdView, SplashAdViewFactory(binding.binaryMessenger,activity))
21 | //注册Express广告
22 | binding.platformViewRegistry.registerViewFactory(FlutterTencentAdConfig.nativeAdView, NativeExpressAdViewFactory(binding.binaryMessenger,activity))
23 | }
24 | }
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/FlutterTencentadPlugin.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Intent
6 | import androidx.annotation.NonNull
7 | import com.gstory.flutter_tencentad.interstitialad.InterstitialAd
8 | import com.gstory.flutter_tencentad.rewardvideoad.RewardVideoAd
9 | import com.gstory.flutter_unionad.FlutterTencentAdEventPlugin
10 | import com.qq.e.comm.DownloadService
11 | import com.qq.e.comm.managers.GDTAdSdk
12 | import com.qq.e.comm.managers.setting.GlobalSetting
13 | import com.qq.e.comm.managers.status.SDKStatus
14 | //import com.qq.e.union.tools.ToolsActivity
15 | import io.flutter.embedding.engine.plugins.FlutterPlugin
16 | import io.flutter.embedding.engine.plugins.activity.ActivityAware
17 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
18 | import io.flutter.plugin.common.MethodCall
19 | import io.flutter.plugin.common.MethodChannel
20 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler
21 | import io.flutter.plugin.common.MethodChannel.Result
22 |
23 |
24 | /** FlutterTencentadPlugin */
25 | class FlutterTencentadPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
26 |
27 | private lateinit var channel: MethodChannel
28 | private var applicationContext: Context? = null
29 | private var mActivity: Activity? = null
30 | private var mFlutterPluginBinding: FlutterPlugin.FlutterPluginBinding? = null
31 |
32 | override fun onAttachedToActivity(binding: ActivityPluginBinding) {
33 | mActivity = binding.activity
34 | // Log.e("FlutterUnionadPlugin->","onAttachedToActivity")
35 | FlutterTencentAdViewPlugin.registerWith(mFlutterPluginBinding!!, mActivity!!)
36 | }
37 |
38 | override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
39 | mActivity = binding.activity
40 | // Log.e("FlutterUnionadPlugin->","onReattachedToActivityForConfigChanges")
41 | }
42 |
43 | override fun onDetachedFromActivityForConfigChanges() {
44 | mActivity = null
45 | // Log.e("FlutterUnionadPlugin->","onDetachedFromActivityForConfigChanges")
46 | }
47 |
48 | override fun onDetachedFromActivity() {
49 | mActivity = null
50 | // Log.e("FlutterUnionadPlugin->","onDetachedFromActivity")
51 | }
52 |
53 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
54 | channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter_tencentad")
55 | channel.setMethodCallHandler(this)
56 | applicationContext = flutterPluginBinding.applicationContext
57 | mFlutterPluginBinding = flutterPluginBinding
58 | FlutterTencentAdEventPlugin().onAttachedToEngine(flutterPluginBinding)
59 | }
60 |
61 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
62 | //注册初始化
63 | if (call.method == "register") {
64 | var arguments = call.arguments as Map
65 | val appId = arguments["androidId"] as String
66 | val debug = arguments["debug"] as Boolean
67 | val channelId = arguments["channelId"] as Int
68 | val personalized = arguments["personalized"] as Int
69 | //隐私管理
70 | val androidPrivacy = arguments["androidPrivacy"] as Map?
71 | val convOptimizelnfo = arguments["convOptimizelnfo"] as Map?
72 |
73 | val enableCollectAppInstallStatus = arguments["enableCollectAppInstallStatus"] as Boolean?
74 |
75 | //日志
76 | LogUtil.setAppName("flutter_tencentad")
77 | LogUtil.setShow(debug!!)
78 | //是否开启个性化
79 | GlobalSetting.setPersonalizedState(personalized!!)
80 | //设置渠道id
81 | GlobalSetting.setChannel(channelId!!)
82 | GlobalSetting.setAgreeReadPrivacyInfo(androidPrivacy);
83 |
84 | // 安卓隐私合规,设置是否收集应用安装状态
85 | // https://e.qq.com/dev/help_detail.html?cid=3607&pid=10118
86 | if(enableCollectAppInstallStatus != null){
87 | // 建议在初始化 SDK 前进行此设置
88 | GlobalSetting.setEnableCollectAppInstallStatus(enableCollectAppInstallStatus);
89 | }
90 | //关闭应用安装监听状态
91 | GlobalSetting.setConvOptimizeInfo(convOptimizelnfo)
92 |
93 | GDTAdSdk.initWithoutStart(applicationContext, appId)
94 | GDTAdSdk.start(object : GDTAdSdk.OnStartListener {
95 | override fun onStartSuccess() {
96 | result.success(true)
97 | }
98 |
99 | override fun onStartFailed(p0: Exception?) {
100 | result.success(false)
101 | }
102 |
103 | })
104 | //获取sdk版本
105 | } else if (call.method == "getSDKVersion") {
106 | result.success(SDKStatus.getIntegrationSDKVersion())
107 | //预加载激励广告
108 | } else if (call.method == "loadRewardVideoAd") {
109 | RewardVideoAd.init(applicationContext!!, call.arguments as Map<*, *>)
110 | result.success(true)
111 | //展示激励广告
112 | } else if (call.method == "showRewardVideoAd") {
113 | RewardVideoAd.showAd(call.arguments as Map<*, *>)
114 | result.success(true)
115 | //预加载插屏广告
116 | } else if (call.method == "loadInterstitialAD") {
117 | InterstitialAd.init(mActivity!!, call.arguments as Map<*, *>)
118 | result.success(true)
119 | //展示插屏广告
120 | } else if (call.method == "showInterstitialAD") {
121 | InterstitialAd.showAd(call.arguments as Map<*, *>)
122 | result.success(true)
123 | //进入下载列表
124 | } else if (call.method == "enterAPPDownloadListPage") {
125 | DownloadService.enterAPPDownloadListPage(mActivity)
126 | result.success(true)
127 | //广告助手
128 | } else if (call.method == "enterADTools") {
129 | // mActivity?.startActivity(Intent(applicationContext, ToolsActivity::class.java))
130 | result.success(true)
131 | } else {
132 | result.notImplemented()
133 | }
134 | }
135 |
136 | override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
137 | channel.setMethodCallHandler(null)
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/LogUtil.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad
2 |
3 | import android.text.TextUtils
4 | import android.util.Log
5 |
6 |
7 | /**
8 | * @Description: 打印工具类
9 | * @Author: gstory
10 | * @CreateDate: 2021/8/6 17:51
11 | **/
12 |
13 | /**
14 | *
15 | * 可自动把调用位置所在的类名和方法名作为tag,并可设置打印级别
16 | * dway
17 | */
18 | object LogUtil {
19 | //以下为打印级别,级别从低到高
20 | const val LOG_LEVEL_VERBOSE = 1
21 | const val LOG_LEVEL_DEBUG = 2
22 | const val LOG_LEVEL_INFO = 3
23 | const val LOG_LEVEL_WARN = 4
24 | const val LOG_LEVEL_ERROR = 5
25 | const val LOG_LEVEL_NOLOG = 6
26 | private var AppName = ""
27 | private var PrintLine = false
28 | private var LogLevel = LOG_LEVEL_VERBOSE
29 | private var isShow = false
30 |
31 | /**
32 | * 可在打印的TAG前添加应用名标识,不设置则不输出
33 | */
34 | fun setAppName(appName: String) {
35 | AppName = appName
36 | }
37 |
38 | /**
39 | * 是否输出打印所在的行数,默认不输出
40 | */
41 | fun setPrintLine(enable: Boolean) {
42 | PrintLine = enable
43 | }
44 |
45 | /**
46 | * 可在打印的TAG前添加应用名标识,不设置则不输出
47 | */
48 | fun setShow(show: Boolean) {
49 | isShow = show
50 | }
51 |
52 |
53 | /**
54 | * 设置打印级别,且只有等于或高于该级别的打印才会输出
55 | */
56 | fun setLogLevel(logLevel: Int) {
57 | LogLevel = logLevel
58 | }
59 |
60 | fun v() {
61 | log(LOG_LEVEL_VERBOSE, "")
62 | }
63 |
64 | fun d() {
65 | log(LOG_LEVEL_DEBUG, "")
66 | }
67 |
68 | fun i() {
69 | log(LOG_LEVEL_INFO, "")
70 | }
71 |
72 | fun w() {
73 | log(LOG_LEVEL_WARN, "")
74 | }
75 |
76 | fun e() {
77 | log(LOG_LEVEL_ERROR, "")
78 | }
79 |
80 | fun v(msg: String) {
81 | if (LogLevel <= LOG_LEVEL_VERBOSE) {
82 | log(LOG_LEVEL_VERBOSE, msg)
83 | }
84 | }
85 |
86 | fun d(msg: String) {
87 | if (LogLevel <= LOG_LEVEL_DEBUG) {
88 | log(LOG_LEVEL_DEBUG, msg)
89 | }
90 | }
91 |
92 | fun i(msg: String) {
93 | if (LogLevel <= LOG_LEVEL_INFO) {
94 | log(LOG_LEVEL_INFO, msg)
95 | }
96 | }
97 |
98 | fun w(msg: String) {
99 | if (LogLevel <= LOG_LEVEL_WARN) {
100 | log(LOG_LEVEL_WARN, msg)
101 | }
102 | }
103 |
104 | fun e(msg: String) {
105 | if (LogLevel <= LOG_LEVEL_ERROR) {
106 | log(LOG_LEVEL_ERROR, msg)
107 | }
108 | }
109 |
110 | private fun log(logLevel: Int, msg: String) {
111 | if(!isShow){
112 | return
113 | }
114 | val caller = Thread.currentThread().stackTrace[4]
115 | var callerClazzName = caller.className
116 | if (callerClazzName.contains(".")) {
117 | callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1)
118 | }
119 | if (callerClazzName.contains("$")) {
120 | callerClazzName = callerClazzName.substring(0, callerClazzName.indexOf("$"))
121 | }
122 | var tag = callerClazzName
123 | if (!TextUtils.isEmpty(AppName)) {
124 | tag = AppName + "_" + tag
125 | }
126 | if (PrintLine) {
127 | tag += "(Line:%d)"
128 | tag = String.format(tag, caller.lineNumber)
129 | }
130 | tag = String.format(tag, callerClazzName)
131 | val message = "---" + caller.methodName + "---" + msg
132 | when (logLevel) {
133 | LOG_LEVEL_VERBOSE -> Log.v(tag, message)
134 | LOG_LEVEL_DEBUG -> Log.d(tag, message)
135 | LOG_LEVEL_INFO -> Log.i(tag, message)
136 | LOG_LEVEL_WARN -> Log.w(tag, message)
137 | LOG_LEVEL_ERROR -> Log.e(tag, message)
138 | LOG_LEVEL_NOLOG -> {
139 | }
140 | }
141 | }
142 | }
143 |
144 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/bannerad/BannerAdView.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad.bannerad
2 |
3 | import android.app.Activity
4 | import android.util.Log
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.FrameLayout
8 | import com.gstory.flutter_tencentad.*
9 | import com.qq.e.ads.banner2.UnifiedBannerADListener
10 | import com.qq.e.ads.banner2.UnifiedBannerView
11 | import com.qq.e.comm.pi.IBidding
12 | import com.qq.e.comm.util.AdError
13 | import io.flutter.plugin.common.BinaryMessenger
14 | import io.flutter.plugin.common.MethodCall
15 | import io.flutter.plugin.common.MethodChannel
16 | import io.flutter.plugin.platform.PlatformView
17 |
18 | /**
19 | * @Description: 平台模板Banner广告
20 | * @Author: gstory
21 | * @CreateDate: 2021/8/7 17:43
22 | **/
23 |
24 | internal class BannerAdView(
25 | var activity: Activity, messenger: BinaryMessenger, id: Int, params: Map
26 | ) : PlatformView, UnifiedBannerADListener, MethodChannel.MethodCallHandler {
27 |
28 | private val TAG = "BannerAdView"
29 |
30 | private var mContainer: FrameLayout? = null
31 |
32 | //广告所需参数
33 | private var codeId: String
34 | private var viewWidth: Float
35 | private var viewHeight: Float
36 |
37 | private var unifiedBannerView: UnifiedBannerView? = null
38 |
39 | private var channel: MethodChannel?
40 |
41 | private var downloadConfirm: Boolean
42 |
43 | //是否开启竞价
44 | private var isBidding: Boolean = params["isBidding"] as Boolean
45 |
46 |
47 | init {
48 | codeId = params["androidId"] as String
49 | var width = params["viewWidth"] as Double
50 | var height = params["viewHeight"] as Double
51 | downloadConfirm = params["downloadConfirm"] as Boolean
52 | viewWidth = width.toFloat()
53 | viewHeight = height.toFloat()
54 | mContainer = FrameLayout(activity)
55 | mContainer?.layoutParams?.width = ViewGroup.LayoutParams.WRAP_CONTENT
56 | mContainer?.layoutParams?.height = ViewGroup.LayoutParams.WRAP_CONTENT
57 | channel = MethodChannel(messenger, FlutterTencentAdConfig.bannerAdView + "_" + id)
58 | channel?.setMethodCallHandler(this)
59 | loadBannerAd()
60 | }
61 |
62 | private fun loadBannerAd() {
63 | unifiedBannerView = UnifiedBannerView(activity, codeId, this)
64 | unifiedBannerView?.loadAD()
65 | }
66 |
67 | override fun getView(): View {
68 | return mContainer!!
69 | }
70 |
71 |
72 | //广告加载失败,error 对象包含了错误码和错误信息
73 | override fun onNoAD(p0: AdError?) {
74 | LogUtil.e("$TAG Banner广告加载失败 ${p0?.errorCode} ${p0?.errorMsg}")
75 | var map: MutableMap =
76 | mutableMapOf("code" to p0?.errorCode, "message" to p0?.errorMsg)
77 | channel?.invokeMethod("onFail", map)
78 | }
79 |
80 | //广告加载成功回调,表示广告相关的资源已经加载完毕,Ready To Show
81 | override fun onADReceive() {
82 | mContainer?.removeAllViews()
83 | if (unifiedBannerView == null) {
84 | LogUtil.e("$TAG Banner广告加载失败 unifiedBannerView不存在或已销毁")
85 | var map: MutableMap =
86 | mutableMapOf("code" to 0, "message" to "BannerView不存在或已销毁")
87 | channel?.invokeMethod("onFail", map)
88 | return
89 | }
90 | if (downloadConfirm) {
91 | unifiedBannerView?.setDownloadConfirmListener(DownloadConfirmHelper.DOWNLOAD_CONFIRM_LISTENER)
92 | }
93 | //竞价 则返回价格 不直接加载
94 | if (isBidding) {
95 | channel?.invokeMethod(
96 | "onECPM", mutableMapOf(
97 | "ecpmLevel" to unifiedBannerView?.ecpmLevel, "ecpm" to unifiedBannerView?.ecpm
98 | )
99 | )
100 | } else {
101 | LogUtil.e("$TAG Banner广告加载成功回调")
102 | mContainer?.addView(
103 | unifiedBannerView, FrameLayout.LayoutParams(viewWidth.toInt(), viewHeight.toInt())
104 | )
105 | val map: MutableMap = mutableMapOf(
106 | // "width" to UIUtils.px2dip(activity, unifiedBannerView?.width!!.toFloat()),
107 | // "height" to UIUtils.px2dip(activity, unifiedBannerView?.height!!.toFloat())
108 | "width" to viewWidth.toInt(),
109 | "height" to viewHeight.toInt()
110 | )
111 | channel?.invokeMethod("onShow", map)
112 | }
113 | }
114 |
115 | //当广告曝光时发起的回调
116 | override fun onADExposure() {
117 | LogUtil.e("$TAG Banner广告曝光")
118 | channel?.invokeMethod("onExpose", "")
119 | }
120 |
121 | //当广告关闭时调用
122 | override fun onADClosed() {
123 | LogUtil.e("$TAG Banner广告关闭")
124 | channel?.invokeMethod("onClose", "")
125 | }
126 |
127 | //当广告点击时发起的回调,由于点击去重等原因可能和平台最终的统计数据有差异
128 | override fun onADClicked() {
129 | LogUtil.e("$TAG Banner广告点击")
130 | channel?.invokeMethod("onClick", "")
131 | }
132 |
133 | //由于广告点击离开 APP 时调用
134 | override fun onADLeftApplication() {
135 | LogUtil.e("$TAG Banner广告点击离开 APP")
136 | }
137 |
138 | override fun dispose() {
139 | unifiedBannerView?.destroy()
140 | unifiedBannerView = null
141 | }
142 |
143 | override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
144 | when (call.method) {
145 | //竞价成功
146 | "biddingSucceeded" -> {
147 | var arguments = call.arguments as Map<*, *>
148 | val map: MutableMap = mutableMapOf(
149 | //对应值为竞胜出价,类型为Integer
150 | IBidding.EXPECT_COST_PRICE to arguments["expectCostPrice"],
151 | //对应值为最大竞败方出价,类型为Integer
152 | IBidding.HIGHEST_LOSS_PRICE to arguments["highestLossPrice"],
153 | )
154 | unifiedBannerView?.sendWinNotification(map)
155 | //展示banner
156 | mContainer?.addView(unifiedBannerView)
157 | val map2: MutableMap = mutableMapOf(
158 | "width" to UIUtils.px2dip(activity, unifiedBannerView?.width!!.toFloat()),
159 | "height" to UIUtils.px2dip(activity, unifiedBannerView?.height!!.toFloat())
160 | )
161 | channel?.invokeMethod("onShow", map2)
162 | }
163 | //竞价失败
164 | "biddingFail" -> {
165 | var arguments = call.arguments as Map<*, *>
166 | val map: MutableMap = mutableMapOf(
167 | //值为本次竞胜方出价(单位:分),类型为Integer。选填
168 | IBidding.WIN_PRICE to arguments["winPrice"],
169 | //值为优量汇广告竞败原因,类型为Integer。必填
170 | IBidding.LOSS_REASON to arguments["lossReason"],
171 | //值为本次竞胜方渠道ID,类型为Integer。必填。
172 | IBidding.ADN_ID to arguments["adnId"],
173 | )
174 | unifiedBannerView?.sendLossNotification(map)
175 | }
176 |
177 | }
178 | }
179 |
180 | }
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/bannerad/BannerAdViewFactory.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad.bannerad
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import io.flutter.plugin.common.BinaryMessenger
6 | import io.flutter.plugin.common.StandardMessageCodec
7 | import io.flutter.plugin.platform.PlatformView
8 | import io.flutter.plugin.platform.PlatformViewFactory
9 |
10 | /**
11 | * @Description: 描述
12 | * @Author: gstory
13 | * @CreateDate: 2021/8/7 17:42
14 | **/
15 |
16 | internal class BannerAdViewFactory(private val messenger: BinaryMessenger, private val activity: Activity) : PlatformViewFactory(
17 | StandardMessageCodec.INSTANCE) {
18 |
19 | override fun create(context: Context?, viewId: Int, args: Any?): PlatformView {
20 | val params = args as Map
21 | return BannerAdView(activity,messenger, viewId, params)
22 | }
23 | }
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/expressad/NativeExpressAdViewFactory.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad.expressad
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import io.flutter.plugin.common.BinaryMessenger
6 | import io.flutter.plugin.common.StandardMessageCodec
7 | import io.flutter.plugin.platform.PlatformView
8 | import io.flutter.plugin.platform.PlatformViewFactory
9 |
10 | /**
11 | * @Description: 描述
12 | * @Author: gstory
13 | * @CreateDate: 2021/8/7 17:42
14 | **/
15 |
16 | internal class NativeExpressAdViewFactory(private val messenger: BinaryMessenger, private val activity: Activity) : PlatformViewFactory(
17 | StandardMessageCodec.INSTANCE) {
18 |
19 | override fun create(context: Context?, viewId: Int, args: Any?): PlatformView {
20 | val params = args as Map
21 | return NativeExpressAdView(activity,messenger, viewId, params)
22 | }
23 | }
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/rewardvideoad/RewardVideoAd.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad.rewardvideoad
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import com.gstory.flutter_tencentad.DownloadApkConfirmDialog
6 | import com.gstory.flutter_tencentad.DownloadConfirmHelper
7 | import com.gstory.flutter_tencentad.LogUtil
8 | import com.gstory.flutter_tencentad.interstitialad.InterstitialAd
9 | import com.gstory.flutter_unionad.FlutterTencentAdEventPlugin
10 | import com.qq.e.ads.rewardvideo.RewardVideoAD
11 | import com.qq.e.ads.rewardvideo.RewardVideoADListener
12 | import com.qq.e.ads.rewardvideo.ServerSideVerificationOptions
13 | import com.qq.e.comm.pi.IBidding
14 | import com.qq.e.comm.util.AdError
15 |
16 |
17 | @SuppressLint("StaticFieldLeak")
18 | object RewardVideoAd {
19 | private val TAG = "RewardVideoAd"
20 |
21 | private lateinit var context: Context
22 | private var rewardVideoAD: RewardVideoAD? = null
23 |
24 | private var codeId: String? = null
25 | private var userID: String = ""
26 | private var rewardName: String = ""
27 | private var rewardAmount: Int = 0
28 | private var customData: String = ""
29 | private var downloadConfirm: Boolean = false
30 | private var videoMuted: Boolean = false
31 |
32 | //是否开启竞价
33 | private var isBidding: Boolean = false
34 |
35 | fun init(context: Context, params: Map<*, *>) {
36 | this.context = context
37 | this.codeId = params["androidId"] as String
38 | this.userID = params["userID"] as String
39 | this.rewardName = params["rewardName"] as String
40 | this.rewardAmount = params["rewardAmount"] as Int
41 | this.customData = params["customData"] as String
42 | this.downloadConfirm = params["downloadConfirm"] as Boolean
43 | this.isBidding = params["isBidding"] as Boolean
44 | this.videoMuted = params["videoMuted"] as Boolean
45 | loadRewardVideoAd()
46 | }
47 |
48 | private fun loadRewardVideoAd() {
49 | rewardVideoAD = RewardVideoAD(context, codeId, rewardVideoADListener,videoMuted)
50 | var options = ServerSideVerificationOptions.Builder()
51 | .setUserId(userID)
52 | .setCustomData(customData)
53 | .build()
54 | rewardVideoAD?.setServerSideVerificationOptions(options)
55 | rewardVideoAD?.loadAD()
56 | }
57 |
58 | fun showAd(params: Map<*, *>) {
59 | if (rewardVideoAD == null) {
60 | var map: MutableMap =
61 | mutableMapOf("adType" to "rewardAd", "onAdMethod" to "onUnReady")
62 | FlutterTencentAdEventPlugin.sendContent(map)
63 | return
64 | }
65 | //是否为竞价模式
66 | if (isBidding) {
67 | var isSuccess: Boolean = params["isSuccess"] as Boolean
68 | //是否成功
69 | if (isSuccess) {
70 | rewardVideoAD?.sendWinNotification(
71 | mutableMapOf(
72 | //对应值为竞胜出价,类型为Integer
73 | IBidding.EXPECT_COST_PRICE to params["expectCostPrice"],
74 | //对应值为最大竞败方出价,类型为Integer
75 | IBidding.HIGHEST_LOSS_PRICE to params["highestLossPrice"],
76 | )
77 | )
78 | rewardVideoAD?.showAD()
79 | } else {
80 | rewardVideoAD?.sendLossNotification(
81 | mutableMapOf(
82 | //值为本次竞胜方出价(单位:分),类型为Integer。选填
83 | IBidding.WIN_PRICE to params["winPrice"],
84 | //值为优量汇广告竞败原因,类型为Integer。必填
85 | IBidding.LOSS_REASON to params["lossReason"],
86 | //值为本次竞胜方渠道ID,类型为Integer。必填。
87 | IBidding.ADN_ID to params["adnId"],
88 | )
89 | )
90 | }
91 | } else {
92 | rewardVideoAD?.showAD()
93 | }
94 |
95 | }
96 |
97 | private var rewardVideoADListener = object : RewardVideoADListener {
98 | override fun onADLoad() {
99 | LogUtil.e("$TAG 激励广告加载成功")
100 | if (downloadConfirm) {
101 | rewardVideoAD?.setDownloadConfirmListener(DownloadConfirmHelper.DOWNLOAD_CONFIRM_LISTENER)
102 | }
103 | }
104 |
105 | override fun onVideoCached() {
106 | LogUtil.e("$TAG 激励广告视频素材缓存成功")
107 | if (isBidding) {
108 | var map: MutableMap =
109 | mutableMapOf(
110 | "adType" to "rewardAd",
111 | "onAdMethod" to "onECPM",
112 | "ecpmLevel" to rewardVideoAD?.ecpmLevel,
113 | "ecpm" to rewardVideoAD?.ecpm
114 | )
115 | FlutterTencentAdEventPlugin.sendContent(map)
116 | } else {
117 | var map: MutableMap =
118 | mutableMapOf("adType" to "rewardAd", "onAdMethod" to "onReady")
119 | FlutterTencentAdEventPlugin.sendContent(map)
120 | }
121 | }
122 |
123 | override fun onADShow() {
124 | LogUtil.e("$TAG 激励视频广告页面展示")
125 | var map: MutableMap =
126 | mutableMapOf("adType" to "rewardAd", "onAdMethod" to "onShow")
127 | FlutterTencentAdEventPlugin.sendContent(map)
128 | }
129 |
130 | override fun onADExpose() {
131 | LogUtil.e("$TAG 激励视频广告曝光")
132 | var map: MutableMap =
133 | mutableMapOf("adType" to "rewardAd", "onAdMethod" to "onExpose")
134 | FlutterTencentAdEventPlugin.sendContent(map)
135 | }
136 |
137 | override fun onReward(p0: MutableMap?) {
138 | LogUtil.e("$TAG 激励视频广告激励发放 $p0")
139 |
140 | var map: MutableMap = mutableMapOf(
141 | "adType" to "rewardAd",
142 | "onAdMethod" to "onVerify",
143 | "transId" to p0!!["transId"],
144 | "rewardName" to rewardName,
145 | "rewardAmount" to rewardAmount
146 | )
147 | FlutterTencentAdEventPlugin.sendContent(map)
148 | }
149 |
150 | override fun onADClick() {
151 | LogUtil.e("$TAG 激励视频广告被点击")
152 | var map: MutableMap =
153 | mutableMapOf("adType" to "rewardAd", "onAdMethod" to "onClick")
154 | FlutterTencentAdEventPlugin.sendContent(map)
155 | }
156 |
157 | override fun onVideoComplete() {
158 | LogUtil.e("$TAG 激励视频广告视频素材播放完毕")
159 | var map: MutableMap =
160 | mutableMapOf("adType" to "rewardAd", "onAdMethod" to "onFinish")
161 | FlutterTencentAdEventPlugin.sendContent(map)
162 | }
163 |
164 | override fun onADClose() {
165 | LogUtil.e("$TAG 激励视频广告被关闭")
166 | var map: MutableMap =
167 | mutableMapOf("adType" to "rewardAd", "onAdMethod" to "onClose")
168 | FlutterTencentAdEventPlugin.sendContent(map)
169 | rewardVideoAD = null
170 | }
171 |
172 | override fun onError(p0: AdError?) {
173 | LogUtil.e("$TAG 广告流程出错 ${p0?.errorCode} ${p0?.errorMsg}")
174 | var map: MutableMap = mutableMapOf(
175 | "adType" to "rewardAd",
176 | "onAdMethod" to "onFail",
177 | "code" to p0?.errorCode,
178 | "message" to p0?.errorMsg
179 | )
180 | FlutterTencentAdEventPlugin.sendContent(map)
181 | }
182 |
183 | }
184 | }
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/splashad/SplashAdView.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad.splashad
2 |
3 | import android.app.Activity
4 | import android.util.Log
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.FrameLayout
8 | import com.gstory.flutter_tencentad.DownloadApkConfirmDialog
9 | import com.gstory.flutter_tencentad.DownloadConfirmHelper
10 | import com.gstory.flutter_tencentad.FlutterTencentAdConfig
11 | import com.gstory.flutter_tencentad.LogUtil
12 | import com.qq.e.ads.splash.SplashAD
13 | import com.qq.e.ads.splash.SplashADListener
14 | import com.qq.e.comm.pi.IBidding
15 | import com.qq.e.comm.util.AdError
16 | import io.flutter.plugin.common.BinaryMessenger
17 | import io.flutter.plugin.common.MethodCall
18 | import io.flutter.plugin.common.MethodChannel
19 | import io.flutter.plugin.platform.PlatformView
20 |
21 |
22 | internal class SplashAdView(
23 | var activity: Activity,
24 | messenger: BinaryMessenger,
25 | id: Int,
26 | params: Map
27 | ) :
28 | PlatformView, SplashADListener , MethodChannel.MethodCallHandler {
29 |
30 | private var mContainer: FrameLayout? = null
31 | private var channel: MethodChannel?
32 |
33 | private var splashAD: SplashAD? = null
34 |
35 | //广告所需参数
36 | private var codeId: String = params["androidId"] as String
37 | private var fetchDelay: Int = params["fetchDelay"] as Int
38 | private var downloadConfirm: Boolean = params["downloadConfirm"] as Boolean
39 | //是否开启竞价
40 | private var isBidding: Boolean = params["isBidding"] as Boolean
41 |
42 | init {
43 | mContainer = FrameLayout(activity)
44 | mContainer?.layoutParams?.width = ViewGroup.LayoutParams.WRAP_CONTENT
45 | mContainer?.layoutParams?.height = ViewGroup.LayoutParams.WRAP_CONTENT
46 | channel = MethodChannel(messenger, FlutterTencentAdConfig.splashAdView + "_" + id)
47 | channel?.setMethodCallHandler(this)
48 | loadSplashAd()
49 | }
50 |
51 | private fun loadSplashAd() {
52 | splashAD = SplashAD(activity, codeId, this, fetchDelay)
53 | mContainer?.removeAllViews()
54 | splashAD?.fetchAdOnly()
55 | }
56 |
57 |
58 | override fun getView(): View {
59 | return mContainer!!
60 | }
61 |
62 | /*************开屏广告回调******************/
63 | //广告关闭时调用,可能是用户关闭或者展示时间到。此时一般需要跳过开屏的 Activity,进入应用内容页面
64 | override fun onADDismissed() {
65 | LogUtil.e("开屏广告关闭")
66 | channel?.invokeMethod("onClose", "")
67 | }
68 |
69 | //广告加载失败,error 对象包含了错误码和错误信息,错误码的详细内容可以参考文档第5章
70 | override fun onNoAD(p0: AdError?) {
71 | LogUtil.e("开屏广告加载失败 ${p0?.errorCode} ${p0?.errorMsg}")
72 | var map: MutableMap = mutableMapOf("code" to p0?.errorCode, "message" to p0?.errorMsg)
73 | channel?.invokeMethod("onFail", map)
74 | }
75 |
76 | //广告成功展示时调用,成功展示不等于有效展示(比如广告容器高度不够)
77 | override fun onADPresent() {
78 | LogUtil.e("开屏广告成功展示")
79 | channel?.invokeMethod("onShow", "")
80 | }
81 |
82 | //广告被点击时调用,不代表满足计费条件(如点击时网络异常)
83 | override fun onADClicked() {
84 | LogUtil.e("开屏广告被点击")
85 | channel?.invokeMethod("onClick", "")
86 | }
87 |
88 | //倒计时回调,返回广告还将被展示的剩余时间,单位是 ms
89 | override fun onADTick(p0: Long) {
90 | LogUtil.e("开屏广告倒计时回调 $p0")
91 | channel?.invokeMethod("onADTick", p0)
92 | }
93 |
94 | //广告曝光时调用
95 | override fun onADExposure() {
96 | LogUtil.e("开屏广告曝光")
97 | channel?.invokeMethod("onExpose", "")
98 | }
99 |
100 | //广告加载成功的回调,在fetchAdOnly的情况下,
101 | // 表示广告拉取成功可以显示了。广告需要在SystemClock.elapsedRealtime {
128 | var arguments = call.arguments as Map<*, *>
129 | splashAD?.sendWinNotification(mutableMapOf(
130 | //对应值为竞胜出价,类型为Integer
131 | IBidding.EXPECT_COST_PRICE to arguments["expectCostPrice"],
132 | //对应值为最大竞败方出价,类型为Integer
133 | IBidding.HIGHEST_LOSS_PRICE to arguments["highestLossPrice"],
134 | ))
135 | //展示banner
136 | splashAD?.showAd(mContainer)
137 | }
138 | //竞价失败
139 | "biddingFail" -> {
140 | var arguments = call.arguments as Map<*, *>
141 | splashAD?.sendLossNotification(mutableMapOf(
142 | //值为本次竞胜方出价(单位:分),类型为Integer。选填
143 | IBidding.WIN_PRICE to arguments["winPrice"],
144 | //值为优量汇广告竞败原因,类型为Integer。必填
145 | IBidding.LOSS_REASON to arguments["lossReason"],
146 | //值为本次竞胜方渠道ID,类型为Integer。必填。
147 | IBidding.ADN_ID to arguments["adnId"],
148 | ))
149 | }
150 |
151 | }
152 | }
153 | }
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/gstory/flutter_tencentad/splashad/SplashAdViewFactory.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad.splashad
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import com.gstory.flutter_tencentad.bannerad.BannerAdView
6 | import io.flutter.plugin.common.BinaryMessenger
7 | import io.flutter.plugin.common.StandardMessageCodec
8 | import io.flutter.plugin.platform.PlatformView
9 | import io.flutter.plugin.platform.PlatformViewFactory
10 |
11 | class SplashAdViewFactory (private val messenger: BinaryMessenger, private val activity: Activity) : PlatformViewFactory(
12 | StandardMessageCodec.INSTANCE) {
13 |
14 | override fun create(context: Context?, viewId: Int, args: Any?): PlatformView {
15 | val params = args as Map
16 | return SplashAdView(activity,messenger, viewId, params)
17 | }
18 | }
--------------------------------------------------------------------------------
/android/src/main/res/anim/download_confirm_dialog_slide_right_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/src/main/res/anim/download_confirm_dialog_slide_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/src/main/res/drawable/download_confirm_background_confirm.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/android/src/main/res/drawable/download_confirm_background_landscape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/android/src/main/res/drawable/download_confirm_background_portrait.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/android/src/main/res/drawable/ic_download_confirm_close.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/android/src/main/res/layout/download_confirm_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
19 |
20 |
28 |
36 |
37 |
38 |
39 |
43 |
48 |
49 |
54 |
55 |
65 |
66 |
72 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/android/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/error.md:
--------------------------------------------------------------------------------
1 | * The 'Pods-Runner' target has transitive dependencies that include statically linked binaries
2 | ```
3 | [!] The 'Pods-Runner' target has transitive dependencies that include statically linked binaries: (/Users/xx/mywork/my/flutter_tencentad/example/ios/Pods/GDTMobSDK/lib/libGDTMobSDK.a)
4 | ```
5 | 打开iOS目录下的Podfile,删除掉use_frameworks!,重新build
--------------------------------------------------------------------------------
/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/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: f4abaa0735eba4dfd8f33f73363911d63931fe03
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # flutter_tencentad_example
2 |
3 | Demonstrates how to use the flutter_tencentad plugin.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | def localProperties = new Properties()
8 | def localPropertiesFile = rootProject.file('local.properties')
9 | if (localPropertiesFile.exists()) {
10 | localPropertiesFile.withReader('UTF-8') { reader ->
11 | localProperties.load(reader)
12 | }
13 | }
14 |
15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
16 | if (flutterVersionCode == null) {
17 | flutterVersionCode = '1'
18 | }
19 |
20 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
21 | if (flutterVersionName == null) {
22 | flutterVersionName = '1.0'
23 | }
24 |
25 | android {
26 | namespace = "com.gstory.flutter_tencentad_example"
27 | // compileSdk = flutter.compileSdkVersion
28 | compileSdk = 34
29 | ndkVersion = flutter.ndkVersion
30 |
31 | compileOptions {
32 | sourceCompatibility = JavaVersion.VERSION_1_8
33 | targetCompatibility = JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlinOptions {
37 | jvmTarget = JavaVersion.VERSION_1_8
38 | }
39 |
40 | defaultConfig {
41 | applicationId "com.gstory.flutter_tencentad_example"
42 | // applicationId "com.hnnuomi.atree"
43 | minSdkVersion flutter.minSdkVersion
44 | // targetSdkVersion flutter.targetSdkVersion
45 | targetSdkVersion 34
46 | versionCode flutterVersionCode.toInteger()
47 | versionName flutterVersionName
48 | }
49 |
50 | signingConfigs {
51 | config {
52 |
53 | }
54 | }
55 |
56 |
57 | buildTypes {
58 | // debug {
59 | // signingConfig signingConfigs.config
60 | // }
61 | // release {
62 | // signingConfig signingConfigs.config
63 | // }
64 | }
65 | }
66 |
67 | flutter {
68 | source '../..'
69 | }
70 |
71 | dependencies{
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/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 |
17 |
25 |
29 |
33 |
38 |
42 |
43 |
44 |
45 |
46 |
47 |
49 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/com/gstory/flutter_tencentad_example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.gstory.flutter_tencentad_example
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:7.4.2'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | mavenCentral()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | tasks.register("clean", Delete) {
28 | delete rootProject.buildDir
29 | }
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | #????java??
5 | #org.gradle.java.home=/Users/guoweijia/Library/Java/JavaVirtualMachines/corretto-11.0.24/Contents/Home
6 |
--------------------------------------------------------------------------------
/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.7.10" apply false
23 | }
24 |
25 | include ":app"
26 |
--------------------------------------------------------------------------------
/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 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
32 | end
33 |
34 | post_install do |installer|
35 | installer.pods_project.targets.each do |target|
36 | flutter_additional_ios_build_settings(target)
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/example/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - flutter_tencentad (0.0.1):
4 | - Flutter
5 | - GDTMobSDK (= 4.15.40)
6 | - GDTMobSDK (4.15.40)
7 |
8 | DEPENDENCIES:
9 | - Flutter (from `Flutter`)
10 | - flutter_tencentad (from `.symlinks/plugins/flutter_tencentad/ios`)
11 |
12 | SPEC REPOS:
13 | trunk:
14 | - GDTMobSDK
15 |
16 | EXTERNAL SOURCES:
17 | Flutter:
18 | :path: Flutter
19 | flutter_tencentad:
20 | :path: ".symlinks/plugins/flutter_tencentad/ios"
21 |
22 | SPEC CHECKSUMS:
23 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
24 | flutter_tencentad: 660b537cd236e247eaf1208bd2de62820a401f71
25 | GDTMobSDK: ec2e9b392268a556e4d5e6ade6d00885d76a2cc5
26 |
27 | PODFILE CHECKSUM: cf0c950f7e9a456b4e325f5b8fc0f98906a3705a
28 |
29 | COCOAPODS: 1.16.2
30 |
--------------------------------------------------------------------------------
/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 |
55 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
74 |
76 |
82 |
83 |
84 |
85 |
87 |
88 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/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-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/ios/Runner/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_tencentad_example
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UIApplicationSupportsIndirectInputEvents
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIMainStoryboardFile
32 | Main
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | UIViewControllerBasedStatusBarAppearance
47 |
48 | io.flutter.embedded_views_preview
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/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/banner_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tencentad/flutter_tencentad.dart';
3 |
4 | ///
5 | /// Description: 描述
6 | /// Author: Gstory
7 | /// Email: gstory0404@gmail.com
8 | /// CreateDate: 2021/8/7 18:09
9 | ///
10 |
11 | class BannerPage extends StatefulWidget {
12 | const BannerPage({Key? key}) : super(key: key);
13 |
14 | @override
15 | _BannerPageState createState() => _BannerPageState();
16 | }
17 |
18 | class _BannerPageState extends State {
19 | FlutterTencentAdBiddingController _bidding =
20 | new FlutterTencentAdBiddingController();
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return Scaffold(
25 | appBar: AppBar(
26 | title: Text("Banner广告(平台模板)"),
27 | ),
28 | body: Column(
29 | children: [
30 | FlutterTencentad.bannerAdView(
31 | //android广告id
32 | androidId: "2062550725221056",
33 | //ios广告id
34 | iosId: "5065170861631459",
35 | //广告宽 单位dp
36 | viewWidth: 640,
37 | //广告高 单位dp 宽高比应该为6.4:1
38 | viewHeight: 100,
39 | //下载二次确认弹窗 默认false
40 | downloadConfirm: true,
41 | // 广告回调
42 | callBack: FlutterTencentadBannerCallBack(
43 | onShow: () {
44 | print("Banner广告显示");
45 | },
46 | onFail: (code, message) {
47 | print("Banner广告错误 $code $message");
48 | },
49 | onClose: () {
50 | print("Banner广告关闭");
51 | },
52 | onExpose: () {
53 | print("Banner广告曝光");
54 | },
55 | onClick: () {
56 | print("Banner广告点击");
57 | },
58 | ),
59 | ),
60 | FlutterTencentad.bannerAdView(
61 | //android广告id
62 | androidId: "2062550725221056",
63 | //ios广告id
64 | iosId: "5065170861631459",
65 | //广告宽 单位dp
66 | viewWidth: 640,
67 | //广告高 单位dp 宽高比应该为6.4:1
68 | viewHeight: 60,
69 | //下载二次确认弹窗 默认false
70 | downloadConfirm: true,
71 | // 广告回调
72 | callBack: FlutterTencentadBannerCallBack(
73 | onShow: () {
74 | print("Banner广告显示");
75 | },
76 | onFail: (code, message) {
77 | print("Banner广告错误 $code $message");
78 | },
79 | onClose: () {
80 | print("Banner广告关闭");
81 | },
82 | onExpose: () {
83 | print("Banner广告曝光");
84 | },
85 | onClick: () {
86 | print("Banner广告点击");
87 | },
88 | ),
89 | ),
90 | //竞价banner
91 | // FlutterTencentad.bannerAdView(
92 | // //android广告id
93 | // androidId: "3093291064428297",
94 | // //ios广告id
95 | // iosId: "3093291064428297",
96 | // viewWidth: 500,
97 | // viewHeight: 100,
98 | // isBidding: true,
99 | // bidding: _bidding,
100 | // // 广告回调
101 | // callBack: FlutterTencentadBannerCallBack(onShow: () {
102 | // print("Banner广告显示");
103 | // }, onFail: (code, message) {
104 | // print("Banner广告错误 $code $message");
105 | // }, onClose: () {
106 | // print("Banner广告关闭");
107 | // }, onExpose: () {
108 | // print("Banner广告曝光");
109 | // }, onClick: () {
110 | // print("Banner广告点击");
111 | // }, onECPM: (ecpmLevel, ecpm) {
112 | // print("Banner广告竞价 ecpmLevel=$ecpmLevel ecpm=$ecpm");
113 | // //规则 自己根据业务处理
114 | // if (ecpm > 0) {
115 | // //竞胜出价,类型为Integer
116 | // //最大竞败方出价,类型为Integer
117 | // _bidding.biddingResult(
118 | // FlutterTencentBiddingResult().success(ecpm, 0));
119 | // } else {
120 | // //竞胜方出价(单位:分),类型为Integer
121 | // //优量汇广告竞败原因 FlutterTencentAdBiddingLossReason
122 | // //竞胜方渠道ID FlutterTencentAdADNID
123 | // _bidding.biddingResult(FlutterTencentBiddingResult().fail(
124 | // 1000,
125 | // FlutterTencentAdBiddingLossReason.LOW_PRICE,
126 | // FlutterTencentAdADNID.othoerADN));
127 | // }
128 | // }),
129 | // ),
130 | ],
131 | ),
132 | );
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/example/lib/express_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tencentad/flutter_tencentad.dart';
3 |
4 | ///
5 | /// Description: 描述
6 | /// Author: Gstory
7 | /// Email: gstory0404@gmail.com
8 | /// CreateDate: 2021/8/7 18:09
9 | ///
10 |
11 | class ExpressPage extends StatefulWidget {
12 | const ExpressPage({Key? key}) : super(key: key);
13 |
14 | @override
15 | _ExpressPageState createState() => _ExpressPageState();
16 | }
17 |
18 | class _ExpressPageState extends State {
19 | FlutterTencentAdBiddingController _bidding =
20 | new FlutterTencentAdBiddingController();
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return Scaffold(
25 | appBar: AppBar(
26 | title: Text("动态信息流/横幅/视频贴片广告"),
27 | ),
28 | body: SingleChildScrollView(
29 | child: Column(
30 | children: [
31 | //动态信息流-原生-平台模板2.0
32 | Text("动态信息流/横幅/视频贴片广告"),
33 | FlutterTencentad.expressAdView(
34 | //android广告id
35 | androidId: "2052358715215945",
36 | //ios广告id
37 | iosId: "8005078841637436",
38 | //广告宽 单位dp
39 | viewWidth: 400,
40 | //广告高 单位dp
41 | viewHeight: 300,
42 | //下载二次确认弹窗 默认false
43 | downloadConfirm: true,
44 | //回调事件
45 | callBack: FlutterTencentadExpressCallBack(
46 | onShow: () {
47 | print("动态信息流广告显示");
48 | },
49 | onFail: (code, message) {
50 | print("动态信息流广告错误 $code $message");
51 | },
52 | onClose: () {
53 | print("动态信息流广告关闭");
54 | },
55 | onExpose: () {
56 | print("动态信息流广告曝光");
57 | },
58 | onClick: () {
59 | print("动态信息流广告点击");
60 | },
61 | )),
62 | //视频贴片
63 | Text("视频贴片"),
64 | FlutterTencentad.expressAdView(
65 | //android广告id
66 | androidId: "4072918853903023",
67 | //ios广告id
68 | iosId: "5065041754863035",
69 | viewWidth: 400,
70 | viewHeight: 300,
71 | //下载二次确认弹窗 默认false
72 | downloadConfirm: true,
73 | ),
74 | //竞价信息流
75 | Text("动态信息流(竞价)"),
76 | FlutterTencentad.expressAdView(
77 | //android广告id
78 | androidId: "4072918853903023",
79 | //ios广告id
80 | iosId: "5065041754863035",
81 | viewWidth: 400,
82 | viewHeight: 300,
83 | //下载二次确认弹窗 默认false
84 | downloadConfirm: true,
85 | //是否开启竞价模式
86 | isBidding: true,
87 | bidding: _bidding,
88 | //回调事件
89 | callBack: FlutterTencentadExpressCallBack(onShow: () {
90 | print("动态信息流广告显示");
91 | }, onFail: (code, message) {
92 | print("动态信息流广告错误 $code $message");
93 | }, onClose: () {
94 | print("动态信息流广告关闭");
95 | }, onExpose: () {
96 | print("动态信息流广告曝光");
97 | }, onClick: () {
98 | print("动态信息流广告点击");
99 | }, onECPM: (ecpmLevel, ecpm) {
100 | print("动态信息流广告竞价 ecpmLevel=$ecpmLevel ecpm=$ecpm");
101 | //规则 自己根据业务处理
102 | if (ecpm > 0) {
103 | //竞胜出价,类型为Integer
104 | //最大竞败方出价,类型为Integer
105 | _bidding.biddingResult(
106 | FlutterTencentBiddingResult().success(ecpm, 0));
107 | } else {
108 | //竞胜方出价(单位:分),类型为Integer
109 | //优量汇广告竞败原因 FlutterTencentAdBiddingLossReason
110 | //竞胜方渠道ID FlutterTencentAdADNID
111 | _bidding.biddingResult(FlutterTencentBiddingResult().fail(
112 | 1000,
113 | FlutterTencentAdBiddingLossReason.LOW_PRICE,
114 | FlutterTencentAdADNID.othoerADN));
115 | }
116 | }),
117 | ),
118 | ],
119 | ),
120 | ),
121 | );
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/example/lib/splash_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tencentad/flutter_tencentad.dart';
3 |
4 | ///
5 | /// Description: 描述
6 | /// Author: Gstory
7 | /// Email: gstory0404@gmail.com
8 | /// CreateDate: 2021/8/7 18:09
9 | ///
10 |
11 | class SplashPage extends StatefulWidget {
12 | bool isBidding;
13 | String androidId;
14 | String iosId;
15 |
16 | SplashPage(
17 | {Key? key,
18 | required this.isBidding,
19 | required this.androidId,
20 | required this.iosId})
21 | : super(key: key);
22 |
23 | @override
24 | _SplashPageState createState() => _SplashPageState();
25 | }
26 |
27 | class _SplashPageState extends State {
28 | FlutterTencentAdBiddingController _bidding =
29 | new FlutterTencentAdBiddingController();
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | return Scaffold(
34 | body: Container(
35 | child: FlutterTencentad.splashAdView(
36 | //android广告id
37 | androidId: widget.androidId,
38 | //ios广告id
39 | iosId: widget.iosId,
40 | ////设置开屏广告从请求到展示所花的最大时长(并不是指广告曝光时长),取值范围为[1500, 5000]ms
41 | fetchDelay: 3000,
42 | //下载二次确认弹窗 默认false
43 | downloadConfirm: true,
44 | //是否开启竞价 默认不开启
45 | isBidding: widget.isBidding,
46 | //竞价结果回传
47 | bidding: _bidding,
48 | //广告回调
49 | callBack: FlutterTencentadSplashCallBack(onShow: () {
50 | print("开屏广告显示");
51 | }, onADTick: (time) {
52 | print("开屏广告倒计时剩余时间 $time");
53 | }, onClick: () {
54 | print("开屏广告点击");
55 | }, onClose: () {
56 | print("开屏广告关闭");
57 | Navigator.pop(context);
58 | }, onExpose: () {
59 | print("开屏广告曝光");
60 | }, onFail: (code, message) {
61 | print("开屏广告失败 $code $message");
62 | Navigator.pop(context);
63 | }, onECPM: (ecpmLevel, ecpm) {
64 | print("开屏广告竞价 ecpmLevel=$ecpmLevel ecpm=$ecpm");
65 | //规则 自己根据业务处理
66 | if (ecpm > 0) {
67 | //竞胜出价,类型为Integer
68 | //最大竞败方出价,类型为Integer
69 | _bidding.biddingResult(
70 | FlutterTencentBiddingResult().success(ecpm, 0));
71 | } else {
72 | //竞胜方出价(单位:分),类型为Integer
73 | //优量汇广告竞败原因 FlutterTencentAdBiddingLossReason
74 | //竞胜方渠道ID FlutterTencentAdADNID
75 | _bidding.biddingResult(FlutterTencentBiddingResult().fail(
76 | 1000,
77 | FlutterTencentAdBiddingLossReason.LOW_PRICE,
78 | FlutterTencentAdADNID.othoerADN));
79 | }
80 | }),
81 | ),
82 | ),
83 | );
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "2.12.0"
12 | boolean_selector:
13 | dependency: transitive
14 | description:
15 | name: boolean_selector
16 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.1.2"
20 | characters:
21 | dependency: transitive
22 | description:
23 | name: characters
24 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "1.4.0"
28 | clock:
29 | dependency: transitive
30 | description:
31 | name: clock
32 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.1.2"
36 | collection:
37 | dependency: transitive
38 | description:
39 | name: collection
40 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.19.1"
44 | cupertino_icons:
45 | dependency: "direct main"
46 | description:
47 | name: cupertino_icons
48 | sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.0.5"
52 | fake_async:
53 | dependency: transitive
54 | description:
55 | name: fake_async
56 | sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "1.3.2"
60 | flutter:
61 | dependency: "direct main"
62 | description: flutter
63 | source: sdk
64 | version: "0.0.0"
65 | flutter_tencentad:
66 | dependency: "direct main"
67 | description:
68 | path: ".."
69 | relative: true
70 | source: path
71 | version: "1.2.34"
72 | flutter_test:
73 | dependency: "direct dev"
74 | description: flutter
75 | source: sdk
76 | version: "0.0.0"
77 | leak_tracker:
78 | dependency: transitive
79 | description:
80 | name: leak_tracker
81 | sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
82 | url: "https://pub.dev"
83 | source: hosted
84 | version: "10.0.8"
85 | leak_tracker_flutter_testing:
86 | dependency: transitive
87 | description:
88 | name: leak_tracker_flutter_testing
89 | sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
90 | url: "https://pub.dev"
91 | source: hosted
92 | version: "3.0.9"
93 | leak_tracker_testing:
94 | dependency: transitive
95 | description:
96 | name: leak_tracker_testing
97 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
98 | url: "https://pub.dev"
99 | source: hosted
100 | version: "3.0.1"
101 | matcher:
102 | dependency: transitive
103 | description:
104 | name: matcher
105 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
106 | url: "https://pub.dev"
107 | source: hosted
108 | version: "0.12.17"
109 | material_color_utilities:
110 | dependency: transitive
111 | description:
112 | name: material_color_utilities
113 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
114 | url: "https://pub.dev"
115 | source: hosted
116 | version: "0.11.1"
117 | meta:
118 | dependency: transitive
119 | description:
120 | name: meta
121 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
122 | url: "https://pub.dev"
123 | source: hosted
124 | version: "1.16.0"
125 | path:
126 | dependency: transitive
127 | description:
128 | name: path
129 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
130 | url: "https://pub.dev"
131 | source: hosted
132 | version: "1.9.1"
133 | sky_engine:
134 | dependency: transitive
135 | description: flutter
136 | source: sdk
137 | version: "0.0.0"
138 | source_span:
139 | dependency: transitive
140 | description:
141 | name: source_span
142 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
143 | url: "https://pub.dev"
144 | source: hosted
145 | version: "1.10.1"
146 | stack_trace:
147 | dependency: transitive
148 | description:
149 | name: stack_trace
150 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
151 | url: "https://pub.dev"
152 | source: hosted
153 | version: "1.12.1"
154 | stream_channel:
155 | dependency: transitive
156 | description:
157 | name: stream_channel
158 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
159 | url: "https://pub.dev"
160 | source: hosted
161 | version: "2.1.4"
162 | string_scanner:
163 | dependency: transitive
164 | description:
165 | name: string_scanner
166 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
167 | url: "https://pub.dev"
168 | source: hosted
169 | version: "1.4.1"
170 | term_glyph:
171 | dependency: transitive
172 | description:
173 | name: term_glyph
174 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
175 | url: "https://pub.dev"
176 | source: hosted
177 | version: "1.2.2"
178 | test_api:
179 | dependency: transitive
180 | description:
181 | name: test_api
182 | sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
183 | url: "https://pub.dev"
184 | source: hosted
185 | version: "0.7.4"
186 | vector_math:
187 | dependency: transitive
188 | description:
189 | name: vector_math
190 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
191 | url: "https://pub.dev"
192 | source: hosted
193 | version: "2.1.4"
194 | vm_service:
195 | dependency: transitive
196 | description:
197 | name: vm_service
198 | sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
199 | url: "https://pub.dev"
200 | source: hosted
201 | version: "14.3.1"
202 | sdks:
203 | dart: ">=3.7.0-0 <4.0.0"
204 | flutter: ">=3.18.0-18.0.pre.54"
205 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_tencentad_example
2 | description: Demonstrates how to use the flutter_tencentad plugin.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | environment:
9 | sdk: ">=2.12.0 <3.0.0"
10 |
11 | dependencies:
12 | flutter:
13 | sdk: flutter
14 |
15 | flutter_tencentad:
16 | # When depending on this package from a real application you should use:
17 | # flutter_tencentad: ^x.y.z
18 | # See https://dart.dev/tools/pub/dependencies#version-constraints
19 | # The example app is bundled with the plugin so we use a path dependency on
20 | # the parent directory to use the current plugin's version.
21 | path: ../
22 |
23 | # The following adds the Cupertino Icons font to your application.
24 | # Use with the CupertinoIcons class for iOS style icons.
25 | cupertino_icons: ^1.0.2
26 |
27 | dev_dependencies:
28 | flutter_test:
29 | sdk: flutter
30 |
31 | # For information on the generic Dart part of this file, see the
32 | # following page: https://dart.dev/tools/pub/pubspec
33 |
34 | # The following section is specific to Flutter.
35 | flutter:
36 |
37 | # The following line ensures that the Material Icons font is
38 | # included with your application, so that you can use the icons in
39 | # the material Icons class.
40 | uses-material-design: true
41 |
42 | # To add assets to your application, add an assets section, like this:
43 | # assets:
44 | # - images/a_dot_burr.jpeg
45 | # - images/a_dot_ham.jpeg
46 |
47 | # An image asset can refer to one or more resolution-specific "variants", see
48 | # https://flutter.dev/assets-and-images/#resolution-aware.
49 |
50 | # For details regarding adding assets from package dependencies, see
51 | # https://flutter.dev/assets-and-images/#from-packages
52 |
53 | # To add custom fonts to your application, add a fonts section here,
54 | # in this "flutter" section. Each entry in this list should have a
55 | # "family" key with the font family name, and a "fonts" key with a
56 | # list giving the asset and other descriptors for the font. For
57 | # example:
58 | # fonts:
59 | # - family: Schyler
60 | # fonts:
61 | # - asset: fonts/Schyler-Regular.ttf
62 | # - asset: fonts/Schyler-Italic.ttf
63 | # style: italic
64 | # - family: Trajan Pro
65 | # fonts:
66 | # - asset: fonts/TrajanPro.ttf
67 | # - asset: fonts/TrajanPro_Bold.ttf
68 | # weight: 700
69 | #
70 | # For details regarding fonts from package dependencies,
71 | # see https://flutter.dev/custom-fonts/#from-packages
72 |
--------------------------------------------------------------------------------
/example/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:flutter_tencentad_example/main.dart';
12 |
13 | void main() {
14 | testWidgets('Verify Platform version', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that platform version is retrieved.
19 | expect(
20 | find.byWidgetPredicate(
21 | (Widget widget) => widget is Text &&
22 | widget.data!.startsWith('Running on:'),
23 | ),
24 | findsOneWidget,
25 | );
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/images/tencentad.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/images/tencentad.gif
--------------------------------------------------------------------------------
/images/weixin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/images/weixin.jpg
--------------------------------------------------------------------------------
/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/ephemeral/
38 | /Flutter/flutter_export_environment.sh
--------------------------------------------------------------------------------
/ios/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gstory0404/flutter_tencentad/c440bd67180ffec13a3a822ae8c18ee436f3a2d4/ios/Assets/.gitkeep
--------------------------------------------------------------------------------
/ios/Classes/FlutterTencentadPlugin.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface FlutterTencentadPlugin : NSObject
4 | @end
5 |
--------------------------------------------------------------------------------
/ios/Classes/FlutterTencentadPlugin.m:
--------------------------------------------------------------------------------
1 | #import "FlutterTencentadPlugin.h"
2 | #import "FlutterTencentAdEvent.h"
3 | #import "RewardAd.h"
4 | #import "TLogUtil.h"
5 | #import "InsertAd.h"
6 | #import "SplashAd.h"
7 | #import "BannerAd.h"
8 | #import "NativeAd.h"
9 | #import "GDTMobSDK/GDTSDKConfig.h"
10 |
11 | @implementation FlutterTencentadPlugin
12 | + (void)registerWithRegistrar:(NSObject*)registrar {
13 | FlutterMethodChannel* channel = [FlutterMethodChannel
14 | methodChannelWithName:@"flutter_tencentad"
15 | binaryMessenger:[registrar messenger]];
16 | FlutterTencentadPlugin* instance = [[FlutterTencentadPlugin alloc] init];
17 | [registrar addMethodCallDelegate:instance channel:channel];
18 | //注册event
19 | [[FlutterTencentAdEvent sharedInstance] initEvent:registrar];
20 | //注册splash
21 | [registrar registerViewFactory:[[SplashAdFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.gstory.flutter_tencentad/SplashAdView"];
22 | //注册banner
23 | [registrar registerViewFactory:[[BannerAdFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.gstory.flutter_tencentad/BannerAdView"];
24 | //注册native
25 | [registrar registerViewFactory:[[NaitveAdFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.gstory.flutter_tencentad/NativeExpressAdView"];
26 |
27 | }
28 |
29 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
30 | if ([@"register" isEqualToString:call.method]) {
31 | NSString *appId = call.arguments[@"iosId"];
32 | BOOL debug = [call.arguments[@"debug"] boolValue];
33 | BOOL isInit = [GDTSDKConfig registerAppId:appId];
34 | NSInteger personalized = [call.arguments[@"personalized"] intValue];
35 | NSInteger channelId = [call.arguments[@"channelId"] intValue];
36 | //关闭个性化推荐
37 | [GDTSDKConfig setPersonalizedState:personalized];
38 | //渠道id
39 | [GDTSDKConfig setChannel:channelId];
40 | [[TLogUtil sharedInstance] debug:debug];
41 | result([NSNumber numberWithBool:isInit]);
42 | }else if([@"getSDKVersion" isEqualToString:call.method]){
43 | NSString *version = [GDTSDKConfig sdkVersion];
44 | result(version);
45 | //预加载激励广告
46 | }else if([@"loadRewardVideoAd" isEqualToString:call.method]){
47 | [[RewardAd sharedInstance] initAd:call.arguments];
48 | result(@YES);
49 | //显示激励广告
50 | }else if([@"showRewardVideoAd" isEqualToString:call.method]){
51 | [[RewardAd sharedInstance] showAd:call.arguments];
52 | result(@YES);
53 | //预加载插屏广告
54 | }else if([@"loadInterstitialAD" isEqualToString:call.method]){
55 | [[InsertAd sharedInstance] initAd:call.arguments];
56 | result(@YES);
57 | ////展示插屏广告
58 | }else if([@"showInterstitialAD" isEqualToString:call.method]){
59 | [[InsertAd sharedInstance] showAd:call.arguments];
60 | result(@YES);
61 | } else {
62 | result(FlutterMethodNotImplemented);
63 | }
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/ios/Classes/banner/BannerAd.h:
--------------------------------------------------------------------------------
1 | //
2 | // BannerAd.h
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 | @interface BannerAdFactory : NSObject
14 |
15 | - (instancetype)initWithMessenger:(NSObject*)messager;
16 |
17 | @end
18 |
19 | @interface BannerAd : NSObject
20 |
21 | - (instancetype)initWithWithFrame:(CGRect)frame
22 | viewIdentifier:(int64_t)viewId
23 | arguments:(id _Nullable)args
24 | binaryMessenger:(NSObject*)messenger;
25 |
26 | @end
27 |
28 | NS_ASSUME_NONNULL_END
29 |
--------------------------------------------------------------------------------
/ios/Classes/banner/BannerAd.m:
--------------------------------------------------------------------------------
1 | //
2 | // BannerAd.m
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import "BannerAd.h"
9 | #import "GDTMobSDK/GDTUnifiedBannerView.h"
10 | #import "TLogUtil.h"
11 | #import "TUIViewController+getCurrentVC.h"
12 |
13 | #pragma mark - BannerAdFactory
14 |
15 | @implementation BannerAdFactory{
16 | NSObject*_messenger;
17 | }
18 |
19 | - (instancetype)initWithMessenger:(NSObject *)messager{
20 | self = [super init];
21 | if (self) {
22 | _messenger = messager;
23 | }
24 | return self;
25 | }
26 |
27 | -(NSObject *)createArgsCodec{
28 | return [FlutterStandardMessageCodec sharedInstance];
29 | }
30 |
31 | -(NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{
32 | BannerAd * bannerAd = [[BannerAd alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger];
33 | return bannerAd;
34 | }
35 |
36 | @end
37 |
38 | @interface BannerAd()
39 |
40 | @property (nonatomic, strong) GDTUnifiedBannerView *banner;
41 | @property(nonatomic,strong) UIView *container;
42 | @property(nonatomic,assign) CGRect frame;
43 | @property(nonatomic,assign) NSInteger viewId;
44 | @property(nonatomic,strong) FlutterMethodChannel *channel;
45 | @property(nonatomic,strong) NSString *codeId;
46 | @property(nonatomic,assign) NSInteger viewWidth;
47 | @property(nonatomic,assign) NSInteger viewHeight;
48 | @property(nonatomic,assign) BOOL isBidding;
49 | @end
50 |
51 |
52 | @implementation BannerAd
53 |
54 | - (instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject *)messenger{
55 | if ([super init]) {
56 | NSDictionary *dic = args;
57 | _frame = frame;
58 | _viewId = viewId;
59 | _codeId = dic[@"iosId"];
60 | _viewWidth =[dic[@"viewWidth"] intValue];
61 | _viewHeight =[dic[@"viewHeight"] intValue];
62 | self.isBidding =[dic[@"isBidding"] boolValue];
63 | NSString* channelName = [NSString stringWithFormat:@"com.gstory.flutter_tencentad/BannerAdView_%lld", viewId];
64 | _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
65 | [self.channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
66 | // 竞价成功
67 | if ([@"biddingSucceeded" isEqualToString:call.method]) {
68 | NSDictionary *dictionary = @{GDT_M_W_E_COST_PRICE:@([call.arguments[@"expectCostPrice"] intValue]),
69 | GDT_M_W_H_LOSS_PRICE:@([call.arguments[@"highestLossPrice"] intValue])
70 | };
71 | [_banner sendWinNotificationWithInfo:dictionary];
72 | NSDictionary *dictionary2 = @{@"width": @(self.banner.frame.size.width),@"height":@(self.banner.frame.size.height)};
73 | [_channel invokeMethod:@"onShow" arguments:dictionary2 result:nil];
74 | //竞价失败
75 | } else if([@"biddingFail" isEqualToString:call.method]) {
76 | NSDictionary *dictionary = @{GDT_M_L_WIN_PRICE:@([call.arguments[@"winPrice"] intValue]),
77 | GDT_M_L_LOSS_REASON:@([call.arguments[@"lossReason"] intValue]),
78 | GDT_M_ADNID: call.arguments[@"adnId"]};
79 | [self.banner sendWinNotificationWithInfo:dictionary];
80 | }
81 | }];
82 | [self loadBannerAd];
83 | }
84 | return self;
85 | }
86 |
87 | - (UIView*)view{
88 | return self.container;
89 | }
90 |
91 | -(void)loadBannerAd{
92 | [_container removeFromSuperview];
93 | CGRect rect = {CGPointZero, CGSizeMake(_viewWidth, _viewHeight)};
94 | if(self.banner == nil){
95 | self.banner = [[GDTUnifiedBannerView alloc] initWithFrame:rect placementId:_codeId viewController:[UIViewController jsd_getCurrentViewController]];
96 | self.banner.delegate = self;
97 | self.banner.autoSwitchInterval = 30;
98 | }
99 | self.container = self.banner;
100 | [self.banner loadAdAndShow];
101 | }
102 |
103 | /**
104 | * 请求广告条数据成功后调用
105 | * 当接收服务器返回的广告数据成功后调用该函数
106 | */
107 | - (void)unifiedBannerViewDidLoad:(GDTUnifiedBannerView *)unifiedBannerView{
108 | [[TLogUtil sharedInstance] print:@"Banner广告数据请求成功"];
109 | // [[TLogUtil sharedInstance] print:self.banner.eCPMLevel];
110 | // [[TLogUtil sharedInstance] print:@(self.banner.eCPM)];
111 | //是否开启竞价
112 | if(self.isBidding){
113 | NSDictionary *dictionary = @{@"ecpmLevel":self.banner.eCPMLevel == nil ? @"" : self.banner.eCPMLevel,@"ecpm":@(self.banner.eCPM)};
114 | [self.channel invokeMethod:@"onECPM" arguments:dictionary result:nil];
115 | }else{
116 | // [self.container addSubview:self.banner];
117 | NSDictionary *dictionary = @{@"width": @(unifiedBannerView.frame.size.width),@"height":@(unifiedBannerView.frame.size.height)};
118 | [self.channel invokeMethod:@"onShow" arguments:dictionary result:nil];
119 | }
120 | }
121 |
122 | /**
123 | * 请求广告条数据失败后调用
124 | * 当接收服务器返回的广告数据失败后调用该函数
125 | */
126 | - (void)unifiedBannerViewFailedToLoad:(GDTUnifiedBannerView *)unifiedBannerView error:(NSError *)error{
127 | [[TLogUtil sharedInstance] print:@"请求广告条数据失败后调用"];
128 | NSDictionary *dictionary = @{@"code":@(-1),@"message":error.description};
129 | [_channel invokeMethod:@"onFail" arguments:dictionary result:nil];
130 | }
131 |
132 | /**
133 | * banner2.0曝光回调
134 | */
135 | - (void)unifiedBannerViewWillExpose:(GDTUnifiedBannerView *)unifiedBannerView{
136 | [[TLogUtil sharedInstance] print:@"banner2.0曝光回调"];
137 | [_channel invokeMethod:@"onExpose" arguments:nil result:nil];
138 | }
139 |
140 | /**
141 | * banner2.0点击回调
142 | */
143 | - (void)unifiedBannerViewClicked:(GDTUnifiedBannerView *)unifiedBannerView{
144 | [[TLogUtil sharedInstance] print:@"banner2.0点击回调"];
145 | [_channel invokeMethod:@"onClick" arguments:nil result:nil];
146 | }
147 |
148 | /**
149 | * banner2.0广告点击以后即将弹出全屏广告页
150 | */
151 | - (void)unifiedBannerViewWillPresentFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView{
152 | [[TLogUtil sharedInstance] print:@"banner2.0广告点击以后即将弹出全屏广告页"];
153 | }
154 |
155 | /**
156 | * banner2.0广告点击以后弹出全屏广告页完毕
157 | */
158 | - (void)unifiedBannerViewDidPresentFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView{
159 | [[TLogUtil sharedInstance] print:@"banner2.0广告点击以后弹出全屏广告页完毕"];
160 | }
161 |
162 | /**
163 | * 全屏广告页即将被关闭
164 | */
165 | - (void)unifiedBannerViewWillDismissFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView{
166 | [[TLogUtil sharedInstance] print:@"全屏广告页即将被关闭"];
167 | }
168 |
169 | /**
170 | * 全屏广告页已经被关闭
171 | */
172 | - (void)unifiedBannerViewDidDismissFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView{
173 | [[TLogUtil sharedInstance] print:@"全屏广告页已经被关闭"];
174 | }
175 |
176 | /**
177 | * 当点击应用下载或者广告调用系统程序打开
178 | */
179 | - (void)unifiedBannerViewWillLeaveApplication:(GDTUnifiedBannerView *)unifiedBannerView{
180 | [[TLogUtil sharedInstance] print:@"当点击应用下载或者广告调用系统程序打开"];
181 | }
182 |
183 | /**
184 | * banner2.0被用户关闭时调用
185 | * 会立即关闭当前banner广告,若启用轮播,(刷新间隔 - 当前广告已展示时间)后会展示新的广告
186 | * 若未启用轮播或不需要再展示,需在回调中将unifiedBannerView从父view移除置nil
187 | */
188 | - (void)unifiedBannerViewWillClose:(GDTUnifiedBannerView *)unifiedBannerView{
189 | [[TLogUtil sharedInstance] print:@"banner2.0被用户关闭时调用"];
190 | [_channel invokeMethod:@"onClose" arguments:nil result:nil];
191 | }
192 |
193 |
194 | @end
195 |
--------------------------------------------------------------------------------
/ios/Classes/event/FlutterTencentAdEvent.h:
--------------------------------------------------------------------------------
1 | //
2 | // FlutterTencentAdEvent.h
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface FlutterTencentAdEvent : NSObject
14 | + (instancetype)sharedInstance;
15 | - (void)initEvent:(NSObject*)registrar;
16 | - (void)sentEvent:(NSDictionary*)arguments;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ios/Classes/event/FlutterTencentAdEvent.m:
--------------------------------------------------------------------------------
1 | //
2 | // FlutterTencentAdEvent.m
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import "FlutterTencentAdEvent.h"
9 | #import
10 |
11 | @interface FlutterTencentAdEvent()
12 | @property(nonatomic,strong) FlutterEventSink eventSink;
13 | @end
14 |
15 | @implementation FlutterTencentAdEvent
16 |
17 | + (instancetype)sharedInstance{
18 | static FlutterTencentAdEvent *myInstance = nil;
19 | if(myInstance == nil){
20 | myInstance = [[FlutterTencentAdEvent alloc]init];
21 | }
22 | return myInstance;
23 | }
24 |
25 |
26 | - (void)initEvent:(NSObject*)registrar{
27 | FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:@"com.gstory.flutter_tencentad/adevent" binaryMessenger:[registrar messenger]];
28 | [eventChannel setStreamHandler:self];
29 | }
30 |
31 | -(void)sentEvent:(NSDictionary*)arguments{
32 | if(self.eventSink != nil){
33 | self.eventSink(arguments);
34 | }
35 | }
36 |
37 |
38 |
39 | #pragma mark - FlutterStreamHandler
40 | - (FlutterError * _Nullable)onCancelWithArguments:(id _Nullable)arguments {
41 | self.eventSink = nil;
42 | return nil;
43 | }
44 |
45 | - (FlutterError * _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(nonnull FlutterEventSink)events {
46 | self.eventSink = events;
47 | return nil;
48 | }@end
49 |
--------------------------------------------------------------------------------
/ios/Classes/insert/InsertAd.h:
--------------------------------------------------------------------------------
1 | //
2 | // InsertAd.h
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface InsertAd : NSObject
13 | + (instancetype)sharedInstance;
14 | - (void)initAd:(NSDictionary *)arguments;
15 | - (void)showAd:(NSDictionary *)arguments;
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ios/Classes/native/NativeAd.h:
--------------------------------------------------------------------------------
1 | //
2 | // NativeAd.h
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 | @interface NaitveAdFactory : NSObject
13 |
14 | - (instancetype)initWithMessenger:(NSObject*)messager;
15 |
16 | @end
17 |
18 | @interface NativeAd : NSObject
19 |
20 | - (instancetype)initWithWithFrame:(CGRect)frame
21 | viewIdentifier:(int64_t)viewId
22 | arguments:(id _Nullable)args
23 | binaryMessenger:(NSObject*)messenger;
24 |
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/ios/Classes/reward/RewardAd.h:
--------------------------------------------------------------------------------
1 | //
2 | // RewardAd.h
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface RewardAd : NSObject
13 |
14 | + (instancetype)sharedInstance;
15 | - (void)initAd:(NSDictionary *)arguments;
16 | - (void)showAd:(NSDictionary *)arguments;
17 |
18 | @end
19 |
20 | NS_ASSUME_NONNULL_END
21 |
--------------------------------------------------------------------------------
/ios/Classes/reward/RewardAd.m:
--------------------------------------------------------------------------------
1 | //
2 | // RewardAd.m
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import "RewardAd.h"
9 | #import "GDTMobSDK/GDTRewardVideoAd.h"
10 | #import "FlutterTencentAdEvent.h"
11 | #import "TLogUtil.h"
12 | #import "TUIViewController+getCurrentVC.h"
13 |
14 | @interface RewardAd()
15 |
16 | @property(nonatomic,strong) GDTRewardVideoAd *reward;
17 | @property(nonatomic,strong) NSString *codeId;
18 | @property(nonatomic,strong) NSString *rewardName;
19 | @property(nonatomic,strong) NSString *rewardAmount;
20 | @property(nonatomic,strong) NSString *userID;
21 | @property(nonatomic,strong) NSString *customData;
22 | @property(nonatomic,assign) BOOL isBidding;
23 | @end
24 |
25 | @implementation RewardAd
26 |
27 | + (instancetype)sharedInstance{
28 | static RewardAd *myInstance = nil;
29 | if(myInstance == nil){
30 | myInstance = [[RewardAd alloc]init];
31 | }
32 | return myInstance;
33 | }
34 |
35 | //预加载激励广告
36 | -(void)initAd:(NSDictionary*)arguments{
37 | NSDictionary *dic = arguments;
38 | _codeId = dic[@"iosId"];
39 | _rewardName = dic[@"rewardName"];
40 | _rewardAmount = dic[@"rewardAmount"];
41 | _userID =dic[@"userID"];
42 | _customData = dic[@"customData"];
43 | _reward = [[GDTRewardVideoAd alloc] initWithPlacementId:_codeId];
44 | _reward.delegate = self;
45 | _reward.videoMuted = dic[@"videoMuted"];
46 | self.isBidding =[dic[@"isBidding"] boolValue];
47 | GDTServerSideVerificationOptions *options = [[GDTServerSideVerificationOptions alloc] init];
48 | options.userIdentifier = _userID;
49 | options.customRewardString = _customData;
50 | _reward.serverSideVerificationOptions = options;
51 | [_reward loadAd];
52 | }
53 |
54 | //展示广告
55 | -(void)showAd:(NSDictionary*)arguments{
56 | if (_reward.expiredTimestamp <= [[NSDate date] timeIntervalSince1970]) {
57 | [[TLogUtil sharedInstance] print:(@"广告已过期,请重新拉取")];
58 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onFail",@"code":@(-1),@"message":@"广告已过期,请重新拉取"};
59 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
60 | return;
61 | }
62 | if (!_reward.isAdValid) {
63 | [[TLogUtil sharedInstance] print:(@"广告失效,请重新拉取")];
64 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onFail",@"code":@(-1),@"message":@"广告失效,请重新拉取"};
65 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
66 | return;
67 | }
68 | if(self.isBidding){
69 | BOOL isSuccess = [arguments[@"isSuccess"] boolValue];
70 | if(isSuccess){
71 | NSDictionary *dictionary = @{GDT_M_W_E_COST_PRICE:@([arguments[@"expectCostPrice"] intValue]),
72 | GDT_M_W_H_LOSS_PRICE:@([arguments[@"highestLossPrice"] intValue])};
73 | [self.reward sendWinNotificationWithInfo:dictionary];
74 | [self.reward showAdFromRootViewController:[UIViewController jsd_getCurrentViewController]];
75 | }else{
76 | NSDictionary *dictionary = @{GDT_M_L_WIN_PRICE:@([arguments[@"winPrice"] intValue]),
77 | GDT_M_L_LOSS_REASON:@([arguments[@"lossReason"] intValue]),
78 | GDT_M_ADNID: arguments[@"adnId"]};
79 | [self.reward sendWinNotificationWithInfo:dictionary];
80 | }
81 | }else{
82 | [self.reward showAdFromRootViewController:[UIViewController jsd_getCurrentViewController]];
83 | }
84 |
85 | }
86 |
87 | #pragma mark - 广告请求delegate
88 |
89 | /**
90 | 广告数据加载成功回调
91 |
92 | @param rewardedVideoAd GDTRewardVideoAd 实例
93 | */
94 | - (void)gdt_rewardVideoAdDidLoad:(GDTRewardVideoAd *)rewardedVideoAd{
95 | [[TLogUtil sharedInstance] print:(@"激励广告数据加载成功")];
96 | //是否开启竞价
97 | if(self.isBidding){
98 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onECPM",@"ecpmLevel":self.reward.eCPMLevel == nil ? @"" : self.reward.eCPMLevel,@"ecpm":@(self.reward.eCPM)};
99 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
100 | }else{
101 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onReady"};
102 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
103 | }
104 |
105 | }
106 |
107 | /**
108 | 视频数据下载成功回调,已经下载过的视频会直接回调
109 |
110 | @param rewardedVideoAd GDTRewardVideoAd 实例
111 | */
112 | - (void)gdt_rewardVideoAdVideoDidLoad:(GDTRewardVideoAd *)rewardedVideoAd{
113 | [[TLogUtil sharedInstance] print:(@"激励广告视频数据下载成功")];
114 | }
115 |
116 | /**
117 | 视频播放页即将展示回调
118 |
119 | @param rewardedVideoAd GDTRewardVideoAd 实例
120 | */
121 | - (void)gdt_rewardVideoAdWillVisible:(GDTRewardVideoAd *)rewardedVideoAd{
122 | [[TLogUtil sharedInstance] print:(@"激励广告视频播放页即将展示回调")];
123 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onShow"};
124 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
125 | }
126 |
127 | /**
128 | 视频广告曝光回调
129 |
130 | @param rewardedVideoAd GDTRewardVideoAd 实例
131 | */
132 | - (void)gdt_rewardVideoAdDidExposed:(GDTRewardVideoAd *)rewardedVideoAd{
133 | [[TLogUtil sharedInstance] print:(@"激励广告曝光")];
134 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onExpose"};
135 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
136 | }
137 |
138 | /**
139 | 视频播放页关闭回调
140 |
141 | @param rewardedVideoAd GDTRewardVideoAd 实例
142 | */
143 | - (void)gdt_rewardVideoAdDidClose:(GDTRewardVideoAd *)rewardedVideoAd{
144 | [[TLogUtil sharedInstance] print:(@"激励广告关闭")];
145 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onClose"};
146 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
147 | }
148 |
149 | /**
150 | 视频广告信息点击回调
151 |
152 | @param rewardedVideoAd GDTRewardVideoAd 实例
153 | */
154 | - (void)gdt_rewardVideoAdDidClicked:(GDTRewardVideoAd *)rewardedVideoAd{
155 | [[TLogUtil sharedInstance] print:(@"激励广告点击")];
156 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onClick"};
157 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
158 | }
159 |
160 | /**
161 | 视频广告各种错误信息回调
162 |
163 | @param rewardedVideoAd GDTRewardVideoAd 实例
164 | @param error 具体错误信息
165 | */
166 | - (void)gdt_rewardVideoAd:(GDTRewardVideoAd *)rewardedVideoAd didFailWithError:(NSError *)error{
167 | [[TLogUtil sharedInstance] print:(@"激励广告错误,%@",error.description)];
168 | NSInteger code = error.code;
169 | NSString *message = error.description;
170 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onFail",@"code":@(code),@"message":message};
171 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
172 | }
173 |
174 | /**
175 | 视频广告播放达到激励条件回调
176 |
177 | @param rewardedVideoAd GDTRewardVideoAd 实例
178 | */
179 | - (void)gdt_rewardVideoAdDidRewardEffective:(GDTRewardVideoAd *)rewardedVideoAd GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请使用 gdt_rewardVideoAdDidRewardEffective:info:"){
180 |
181 | }
182 |
183 |
184 | /**
185 | 视频广告播放达到激励条件回调
186 |
187 | @param rewardedVideoAd GDTRewardVideoAd 实例
188 | @param info 包含此次广告行为的一些信息,例如 @{@"GDT_TRANS_ID":@"930f1fc8ac59983bbdf4548ee40ac353"}, 通过@“GDT_TRANS_ID”可获取此次广告行为的交易id
189 | */
190 | - (void)gdt_rewardVideoAdDidRewardEffective:(GDTRewardVideoAd *)rewardedVideoAd info:(NSDictionary *)info{
191 | [[TLogUtil sharedInstance] print:(@"激励广告视频广告播放达到激励条件")];
192 | NSString *transId = info[@"GDT_TRANS_ID"];
193 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onVerify",@"transId":transId,@"rewardAmount":_rewardAmount,@"rewardName":_rewardName};
194 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
195 | }
196 |
197 | /**
198 | 视频广告视频播放完成
199 |
200 | @param rewardedVideoAd GDTRewardVideoAd 实例
201 | */
202 | - (void)gdt_rewardVideoAdDidPlayFinish:(GDTRewardVideoAd *)rewardedVideoAd{
203 | [[TLogUtil sharedInstance] print:(@"激励广告视频广告视频播放完成")];
204 | NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onFinish"};
205 | [[FlutterTencentAdEvent sharedInstance] sentEvent:dictionary];
206 | }
207 |
208 | @end
209 |
--------------------------------------------------------------------------------
/ios/Classes/splash/SplashAd.h:
--------------------------------------------------------------------------------
1 | //
2 | // SplashAd.h
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 | @interface SplashAdFactory : NSObject
14 |
15 | - (instancetype)initWithMessenger:(NSObject*)messager;
16 |
17 | @end
18 |
19 | @interface SplashAd : NSObject
20 |
21 | - (instancetype)initWithWithFrame:(CGRect)frame
22 | viewIdentifier:(int64_t)viewId
23 | arguments:(id _Nullable)args
24 | binaryMessenger:(NSObject*)messenger;
25 |
26 | @end
27 |
28 | NS_ASSUME_NONNULL_END
29 |
30 |
--------------------------------------------------------------------------------
/ios/Classes/splash/SplashAd.m:
--------------------------------------------------------------------------------
1 | //
2 | // SplashAd.m
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import "SplashAd.h"
9 | #import "GDTMobSDK/GDTSplashAd.h"
10 | #import "TLogUtil.h"
11 |
12 | @implementation SplashAdFactory{
13 | NSObject*_messenger;
14 | }
15 |
16 | - (instancetype)initWithMessenger:(NSObject *)messager{
17 | self = [super init];
18 | if (self) {
19 | _messenger = messager;
20 | }
21 | return self;
22 | }
23 |
24 | -(NSObject *)createArgsCodec{
25 | return [FlutterStandardMessageCodec sharedInstance];
26 | }
27 |
28 | -(NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{
29 | SplashAd * splashAd = [[SplashAd alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger];
30 |
31 | return splashAd;
32 |
33 | }
34 |
35 | @end
36 |
37 |
38 | @interface SplashAd()
39 |
40 | @property (nonatomic, strong) GDTSplashAd *splash;
41 | @property(nonatomic,strong) UIView *container;
42 | @property(nonatomic,assign) CGRect frame;
43 | @property(nonatomic,assign) NSInteger viewId;
44 | @property(nonatomic,strong) FlutterMethodChannel *channel;
45 | @property(nonatomic,strong) NSString *codeId;
46 | @property(nonatomic,assign) NSInteger fetchDelay;
47 | @property(nonatomic,assign) BOOL isBidding;
48 | @end
49 |
50 | @implementation SplashAd
51 |
52 | - (instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject *)messenger{
53 | if ([super init]) {
54 | NSDictionary *dic = args;
55 | _frame = frame;
56 | _viewId = viewId;
57 | _codeId = dic[@"iosId"];
58 | _fetchDelay =[dic[@"_fetchDelay"] intValue];
59 | self.isBidding =[dic[@"isBidding"] boolValue];
60 | NSString* channelName = [NSString stringWithFormat:@"com.gstory.flutter_tencentad/SplashAdView_%lld", viewId];
61 | _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
62 | [self.channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
63 | // 竞价成功
64 | if ([@"biddingSucceeded" isEqualToString:call.method]) {
65 | NSDictionary *dictionary = @{GDT_M_W_E_COST_PRICE:@([call.arguments[@"expectCostPrice"] intValue]),
66 | GDT_M_W_H_LOSS_PRICE:@([call.arguments[@"highestLossPrice"] intValue])};
67 | [self.splash sendWinNotificationWithInfo:dictionary];
68 | //展示广告
69 | [self.splash showFullScreenAdInWindow:[UIApplication sharedApplication].keyWindow withLogoImage:nil skipView:nil];
70 | //竞价失败
71 | } else if([@"biddingFail" isEqualToString:call.method]) {
72 | NSDictionary *dictionary = @{GDT_M_L_WIN_PRICE:@([call.arguments[@"winPrice"] intValue]),
73 | GDT_M_L_LOSS_REASON:@([call.arguments[@"lossReason"] intValue]),
74 | GDT_M_ADNID: call.arguments[@"adnId"]};
75 | [self.splash sendWinNotificationWithInfo:dictionary];
76 | }
77 | }];
78 | [self loadSplashAd];
79 | }
80 | return self;
81 | }
82 |
83 | - (UIView*)view{
84 | return _container;
85 | }
86 |
87 | -(void)loadSplashAd{
88 | _splash = [[GDTSplashAd alloc] initWithPlacementId:_codeId];
89 | _splash.delegate = self;
90 | _splash.fetchDelay = _fetchDelay;
91 | [_splash loadFullScreenAd];
92 | }
93 |
94 | #pragma mark - 广告请求delegate
95 |
96 | /**
97 | * 开屏广告成功展示
98 | */
99 | - (void)splashAdSuccessPresentScreen:(GDTSplashAd *)splashAd{
100 | [[TLogUtil sharedInstance] print:@"开屏广告成功展示"];
101 | [_channel invokeMethod:@"onShow" arguments:nil result:nil];
102 | }
103 |
104 | /**
105 | * 开屏广告素材加载成功
106 | */
107 | - (void)splashAdDidLoad:(GDTSplashAd *)splashAd{
108 | [[TLogUtil sharedInstance] print:@"开屏广告素材加载成功"];
109 | if(!splashAd.isAdValid){
110 | [[TLogUtil sharedInstance] print:@"开屏广告展示失败"];
111 | NSDictionary *dictionary = @{@"code":@(-1),@"message":@"广告展示失败"};
112 | [_channel invokeMethod:@"onFail" arguments:dictionary result:nil];
113 | return;
114 | }
115 | //是否开启竞价
116 | if(self.isBidding){
117 | NSDictionary *dictionary = @{@"ecpmLevel":self.splash.eCPMLevel == nil ? @"" : self.splash.eCPMLevel,@"ecpm":@(self.splash.eCPM)};
118 | [_channel invokeMethod:@"onECPM" arguments:dictionary result:nil];
119 | }else{
120 | [self.splash showFullScreenAdInWindow:[UIApplication sharedApplication].keyWindow withLogoImage:nil skipView:nil];
121 | }
122 | }
123 |
124 | /**
125 | * 开屏广告展示失败
126 | */
127 | - (void)splashAdFailToPresent:(GDTSplashAd *)splashAd withError:(NSError *)error{
128 | [[TLogUtil sharedInstance] print:@"开屏广告展示失败"];
129 | NSDictionary *dictionary = @{@"code":@(-1),@"message":(@"广告展示失败%@",error.description)};
130 | [_channel invokeMethod:@"onFail" arguments:dictionary result:nil];
131 | }
132 |
133 | /**
134 | * 应用进入后台时回调
135 | * 详解: 当点击下载应用时会调用系统程序打开,应用切换到后台
136 | */
137 | - (void)splashAdApplicationWillEnterBackground:(GDTSplashAd *)splashAd{
138 | [[TLogUtil sharedInstance] print:@"应用进入后台时回调"];
139 | }
140 |
141 | /**
142 | * 开屏广告曝光回调
143 | */
144 | - (void)splashAdExposured:(GDTSplashAd *)splashAd{
145 | [[TLogUtil sharedInstance] print:@" 开屏广告曝光回调"];
146 | [_channel invokeMethod:@"onExpose" arguments:nil result:nil];
147 | }
148 |
149 | /**
150 | * 开屏广告点击回调
151 | */
152 | - (void)splashAdClicked:(GDTSplashAd *)splashAd{
153 | [[TLogUtil sharedInstance] print:@"开屏广告点击回调"];
154 | [_channel invokeMethod:@"onClick" arguments:nil result:nil];
155 | }
156 |
157 | /**
158 | * 开屏广告将要关闭回调
159 | */
160 | - (void)splashAdWillClosed:(GDTSplashAd *)splashAd{
161 | [[TLogUtil sharedInstance] print:@"开屏广告将要关闭回调"];
162 | [_channel invokeMethod:@"onClose" arguments:nil result:nil];
163 | }
164 |
165 | /**
166 | * 开屏广告关闭回调
167 | */
168 | - (void)splashAdClosed:(GDTSplashAd *)splashAd{
169 | [[TLogUtil sharedInstance] print:@"开屏广告关闭回调"];
170 | }
171 |
172 | /**
173 | * 开屏广告点击以后即将弹出全屏广告页
174 | */
175 | - (void)splashAdWillPresentFullScreenModal:(GDTSplashAd *)splashAd{
176 | [[TLogUtil sharedInstance] print:@"开屏广告点击以后即将弹出全屏广告页"];
177 | }
178 |
179 | /**
180 | * 开屏广告点击以后弹出全屏广告页
181 | */
182 | - (void)splashAdDidPresentFullScreenModal:(GDTSplashAd *)splashAd{
183 | [[TLogUtil sharedInstance] print:@"开屏广告点击以后弹出全屏广告页"];
184 | }
185 |
186 | /**
187 | * 点击以后全屏广告页将要关闭
188 | */
189 | - (void)splashAdWillDismissFullScreenModal:(GDTSplashAd *)splashAd{
190 | [[TLogUtil sharedInstance] print:@"点击以后全屏广告页将要关闭"];
191 | }
192 | /**
193 | * 点击以后全屏广告页已经关闭
194 | */
195 | - (void)splashAdDidDismissFullScreenModal:(GDTSplashAd *)splashAd{
196 | [[TLogUtil sharedInstance] print:@" 点击以后全屏广告页已经关闭"];
197 | }
198 |
199 | /**
200 | * 开屏广告剩余时间回调
201 | */
202 | - (void)splashAdLifeTime:(NSUInteger)time;{
203 | NSString *timeStr =[NSString stringWithFormat:@"开屏广告剩余时间回调%u",time];
204 | [[TLogUtil sharedInstance] print:timeStr];
205 | }
206 | @end
207 |
--------------------------------------------------------------------------------
/ios/Classes/utils/TLogUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // LogUtil.h
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #ifdef DEBUG
9 | #define GLog(...) NSLog(@"%s\n %@\n\n", __func__, [NSString stringWithFormat:__VA_ARGS__])
10 | #else
11 | #define GLog(...)
12 | #endif
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | @interface TLogUtil : NSObject
17 | + (instancetype)sharedInstance;
18 | - (void)debug:(BOOL)isDebug;
19 | - (void)print:(NSString *)message;
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/ios/Classes/utils/TLogUtil.m:
--------------------------------------------------------------------------------
1 | //
2 | // LogUtil.m
3 | // flutter_tencentad
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import
9 | #import "TLogUtil.h"
10 |
11 | @interface TLogUtil()
12 | @property(nonatomic,assign) BOOL isDebug;
13 | @end
14 |
15 |
16 | @implementation TLogUtil
17 |
18 | + (instancetype)sharedInstance{
19 | static TLogUtil *myInstance = nil;
20 | if(myInstance == nil){
21 | myInstance = [[TLogUtil alloc]init];
22 | }
23 | return myInstance;
24 | }
25 |
26 | - (void)debug:(BOOL)isDebug{
27 | _isDebug = isDebug;
28 | }
29 |
30 | - (void)print:(NSString *)message{
31 | if(_isDebug){
32 | GLog(@"%@", message);
33 | }
34 | }
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/ios/Classes/utils/TUIViewController+getCurrentVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // TUIViewController+getCurrentVC.h
3 | // ANChat
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface UIViewController (getCurrentVC)
13 |
14 | + (UIViewController *)jsd_getCurrentViewController;
15 |
16 | + (UIViewController *)jsd_getRootViewController;
17 |
18 | + (UIViewController *)getCurrentVCWithCurrentView:(UIView *)currentView;
19 |
20 | +(UITabBarController *)currentTtabarController;
21 |
22 | +(UINavigationController *)currentTabbarSelectedNavigationController;
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/ios/Classes/utils/TUIViewController+getCurrentVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+getCurrentVC.m
3 | // ANChat
4 | //
5 | // Created by gstory on 2021/12/1.
6 | //
7 |
8 | #import "TUIViewController+getCurrentVC.h"
9 | //#import "HNBasePresentationController.h"
10 |
11 | @implementation UIViewController (getCurrentVC)
12 |
13 |
14 | + (UIViewController *)jsd_getRootViewController{
15 |
16 | UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
17 | //NSAssert(window, @"The window is empty");
18 | return window.rootViewController;
19 | }
20 |
21 | + (UIViewController *)jsd_getCurrentViewController{
22 |
23 | UIViewController* currentViewController = [self jsd_getRootViewController];
24 | BOOL runLoopFind = YES;
25 | while (runLoopFind) {
26 | if (currentViewController.presentedViewController) {
27 |
28 | currentViewController = currentViewController.presentedViewController;
29 | } else if ([currentViewController isKindOfClass:[UINavigationController class]]) {
30 |
31 | UINavigationController* navigationController = (UINavigationController* )currentViewController;
32 | currentViewController = [navigationController.childViewControllers lastObject];
33 |
34 | } else if ([currentViewController isKindOfClass:[UITabBarController class]]) {
35 |
36 | UITabBarController* tabBarController = (UITabBarController* )currentViewController;
37 | currentViewController = tabBarController.selectedViewController;
38 | } else {
39 |
40 | NSUInteger childViewControllerCount = currentViewController.childViewControllers.count;
41 | if (childViewControllerCount > 0) {
42 |
43 | currentViewController = currentViewController.childViewControllers.lastObject;
44 |
45 | return currentViewController;
46 | } else {
47 |
48 | return currentViewController;
49 | }
50 | }
51 |
52 | }
53 | return currentViewController;
54 | }
55 |
56 | + (UIViewController *)getCurrentVCWithCurrentView:(UIView *)currentView
57 | {
58 | for (UIView *next = currentView ; next ; next = next.superview) {
59 | UIResponder *nextResponder = [next nextResponder];
60 | if ([nextResponder isKindOfClass:[UIViewController class]]) {
61 | return (UIViewController *)nextResponder;
62 | }
63 | }
64 | return nil;
65 | }
66 |
67 |
68 | +(UITabBarController *)currentTtabarController
69 | {
70 | UIWindow * window = [[UIApplication sharedApplication] keyWindow];
71 | UIViewController *tabbarController = window.rootViewController;
72 | if ([tabbarController isKindOfClass:[UITabBarController class]]) {
73 | return (UITabBarController *)tabbarController;
74 | }
75 | return nil;
76 | }
77 |
78 | +(UINavigationController *)currentTabbarSelectedNavigationController
79 | {
80 | UIWindow * window = [[UIApplication sharedApplication] keyWindow];
81 | UIViewController *rootVC = window.rootViewController;
82 | if ([rootVC isKindOfClass:[UINavigationController class]]) {
83 | return (UINavigationController *)rootVC;
84 | }else if([rootVC isKindOfClass:[UITabBarController class]]){
85 | UITabBarController *tabarController = [self currentTtabarController];
86 | UINavigationController *selectedNV = (UINavigationController *)tabarController.selectedViewController;
87 | if ([selectedNV isKindOfClass:[UINavigationController class]]) {
88 | return selectedNV;
89 | }
90 | }
91 |
92 | return nil;
93 | }
94 |
95 |
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/ios/flutter_tencentad.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
3 | # Run `pod lib lint flutter_tencentad.podspec` to validate before publishing.
4 | #
5 | Pod::Spec.new do |s|
6 | s.name = 'flutter_tencentad'
7 | s.version = '0.0.1'
8 | s.summary = 'A new flutter plugin project.'
9 | s.description = <<-DESC
10 | A new flutter plugin project.
11 | DESC
12 | s.homepage = 'http://example.com'
13 | s.license = { :file => '../LICENSE' }
14 | s.author = { 'Your Company' => 'email@example.com' }
15 | s.source = { :path => '.' }
16 | s.source_files = 'Classes/**/*'
17 | s.static_framework = true
18 | s.public_header_files = 'Classes/**/*.h'
19 | s.dependency 'Flutter'
20 | s.platform = :ios, '9.0'
21 | s.dependency 'GDTMobSDK', '4.15.40'
22 |
23 | # Flutter.framework does not contain a i386 slice.
24 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
25 | end
26 |
--------------------------------------------------------------------------------
/lib/banner/banner_ad_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/services.dart';
4 | import 'package:flutter_tencentad/flutter_tencentad.dart';
5 |
6 | ///
7 | /// Description: 描述
8 | /// Author: Gstory
9 | /// Email: gstory0404@gmail.com
10 | /// CreateDate: 2021/8/7 17:33
11 | ///
12 | class BannerAdView extends StatefulWidget {
13 | final String androidId;
14 | final String iosId;
15 | final double viewWidth;
16 | final double viewHeight;
17 | final FlutterTencentadBannerCallBack? callBack;
18 | final bool downloadConfirm;
19 | final bool isBidding;
20 | final FlutterTencentAdBiddingController? bidding;
21 |
22 | const BannerAdView({
23 | Key? key,
24 | required this.androidId,
25 | required this.iosId,
26 | required this.viewWidth,
27 | required this.viewHeight,
28 | this.callBack,
29 | required this.downloadConfirm,
30 | required this.isBidding,
31 | this.bidding,
32 | }) : super(key: key);
33 |
34 | @override
35 | _BannerAdViewState createState() => _BannerAdViewState();
36 | }
37 |
38 | class _BannerAdViewState extends State {
39 | String _viewType = "com.gstory.flutter_tencentad/BannerAdView";
40 |
41 | MethodChannel? _channel;
42 |
43 | //广告是否显示
44 | bool _isShowAd = true;
45 |
46 | double _width = 0;
47 | double _height = 0;
48 |
49 | @override
50 | void initState() {
51 | super.initState();
52 | _width = widget.viewWidth;
53 | _height = widget.viewHeight;
54 | }
55 |
56 | @override
57 | Widget build(BuildContext context) {
58 | if (!_isShowAd) {
59 | return Container();
60 | }
61 | if (defaultTargetPlatform == TargetPlatform.android) {
62 | return Container(
63 | width: _width,
64 | height: _height,
65 | child: AndroidView(
66 | viewType: _viewType,
67 | creationParams: {
68 | "androidId": widget.androidId,
69 | "viewWidth": widget.viewWidth,
70 | "viewHeight": widget.viewHeight,
71 | "downloadConfirm": widget.downloadConfirm,
72 | "isBidding": widget.isBidding,
73 | },
74 | onPlatformViewCreated: _registerChannel,
75 | creationParamsCodec: const StandardMessageCodec(),
76 | ),
77 | );
78 | } else if (defaultTargetPlatform == TargetPlatform.iOS) {
79 | return Container(
80 | width: _width,
81 | height: _height,
82 | child: UiKitView(
83 | viewType: _viewType,
84 | creationParams: {
85 | "iosId": widget.iosId,
86 | "viewWidth": widget.viewWidth,
87 | "viewHeight": widget.viewHeight,
88 | "isBidding": widget.isBidding,
89 | },
90 | onPlatformViewCreated: _registerChannel,
91 | creationParamsCodec: const StandardMessageCodec(),
92 | ),
93 | );
94 | } else {
95 | return Container();
96 | }
97 | }
98 |
99 | //注册cannel
100 | void _registerChannel(int id) {
101 | _channel = MethodChannel("${_viewType}_$id");
102 | _channel?.setMethodCallHandler(_platformCallHandler);
103 | widget.bidding?.init(_channel);
104 | }
105 |
106 | //监听原生view传值
107 | Future _platformCallHandler(MethodCall call) async {
108 | print("${call.method} ==== ${call.arguments}");
109 | switch (call.method) {
110 | //显示广告
111 | case FlutterTencentadMethod.onShow:
112 | Map map = call.arguments;
113 | if (mounted) {
114 | setState(() {
115 | _width = map["width"];
116 | _height = map["height"];
117 | _isShowAd = true;
118 | });
119 | }
120 | widget.callBack?.onShow!();
121 | break;
122 | //广告加载失败
123 | case FlutterTencentadMethod.onFail:
124 | if (mounted) {
125 | setState(() {
126 | _isShowAd = false;
127 | });
128 | }
129 | Map map = call.arguments;
130 | widget.callBack?.onFail!(map["code"], map["message"]);
131 | break;
132 | //点击
133 | case FlutterTencentadMethod.onClick:
134 | widget.callBack?.onClick!();
135 | break;
136 | //曝光
137 | case FlutterTencentadMethod.onExpose:
138 | widget.callBack?.onExpose!();
139 | break;
140 | //关闭
141 | case FlutterTencentadMethod.onClose:
142 | if (mounted) {
143 | setState(() {
144 | _isShowAd = false;
145 | });
146 | }
147 | widget.callBack?.onClose!();
148 | break;
149 | //竞价
150 | case FlutterTencentadMethod.onECPM:
151 | Map map = call.arguments;
152 | widget.callBack?.onECPM!(map["ecpmLevel"], map["ecpm"]);
153 | break;
154 | }
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/lib/express/express_ad_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/services.dart';
4 | import 'package:flutter_tencentad/flutter_tencentad.dart';
5 |
6 | ///
7 | /// Description: 描述
8 | /// Author: Gstory
9 | /// Email: gstory0404@gmail.com
10 | /// CreateDate: 2021/8/7 17:33
11 | ///
12 | class ExpressAdView extends StatefulWidget {
13 | final String androidId;
14 | final String iosId;
15 | final int viewWidth;
16 | final int viewHeight;
17 | final FlutterTencentadExpressCallBack? callBack;
18 | final bool downloadConfirm;
19 | final bool isBidding;
20 | final FlutterTencentAdBiddingController? bidding;
21 |
22 | const ExpressAdView({
23 | Key? key,
24 | required this.androidId,
25 | required this.iosId,
26 | required this.viewWidth,
27 | required this.viewHeight,
28 | this.callBack,
29 | required this.downloadConfirm,
30 | required this.isBidding,
31 | this.bidding,
32 | }) : super(key: key);
33 |
34 | @override
35 | _ExpressAdViewState createState() => _ExpressAdViewState();
36 | }
37 |
38 | class _ExpressAdViewState extends State {
39 | String _viewType = "com.gstory.flutter_tencentad/NativeExpressAdView";
40 |
41 | MethodChannel? _channel;
42 |
43 | //广告是否显示
44 | bool _isShowAd = true;
45 |
46 | double _width = 0;
47 | double _height = 0;
48 |
49 | @override
50 | void initState() {
51 | super.initState();
52 | _width = widget.viewWidth.toDouble();
53 | _height = widget.viewHeight.toDouble();
54 | setState(() {});
55 | }
56 |
57 | @override
58 | Widget build(BuildContext context) {
59 | if (!_isShowAd) {
60 | return Container();
61 | }
62 | if (defaultTargetPlatform == TargetPlatform.android) {
63 | return Container(
64 | width: _width,
65 | height: _height,
66 | child: AndroidView(
67 | viewType: _viewType,
68 | creationParams: {
69 | "androidId": widget.androidId,
70 | "viewWidth": widget.viewWidth,
71 | "viewHeight": widget.viewHeight,
72 | "downloadConfirm": widget.downloadConfirm,
73 | "isBidding": widget.isBidding,
74 | },
75 | onPlatformViewCreated: _registerChannel,
76 | creationParamsCodec: const StandardMessageCodec(),
77 | ),
78 | );
79 | } else if (defaultTargetPlatform == TargetPlatform.iOS) {
80 | return Container(
81 | width: _width,
82 | height: _height,
83 | child: UiKitView(
84 | viewType: _viewType,
85 | creationParams: {
86 | "iosId": widget.iosId,
87 | "viewWidth": widget.viewWidth,
88 | "viewHeight": widget.viewHeight,
89 | "isBidding": widget.isBidding,
90 | },
91 | onPlatformViewCreated: _registerChannel,
92 | creationParamsCodec: const StandardMessageCodec(),
93 | ),
94 | );
95 | } else {
96 | return Container();
97 | }
98 | }
99 |
100 | //注册cannel
101 | void _registerChannel(int id) {
102 | _channel = MethodChannel("${_viewType}_$id");
103 | _channel?.setMethodCallHandler(_platformCallHandler);
104 | widget.bidding?.init(_channel);
105 | }
106 |
107 | //监听原生view传值
108 | Future _platformCallHandler(MethodCall call) async {
109 | switch (call.method) {
110 | //显示广告
111 | case FlutterTencentadMethod.onShow:
112 | Map map = call.arguments;
113 | if (mounted) {
114 | setState(() {
115 | _width = map["width"];
116 | _height = map["height"];
117 | _isShowAd = true;
118 | });
119 | }
120 | widget.callBack?.onShow!();
121 | break;
122 | //广告加载失败
123 | case FlutterTencentadMethod.onFail:
124 | if (mounted) {
125 | setState(() {
126 | _isShowAd = false;
127 | });
128 | }
129 | Map map = call.arguments;
130 | widget.callBack?.onFail!(map["code"], map["message"]);
131 | break;
132 | //点击
133 | case FlutterTencentadMethod.onClick:
134 | widget.callBack?.onClick!();
135 | break;
136 | //曝光
137 | case FlutterTencentadMethod.onExpose:
138 | widget.callBack?.onExpose!();
139 | break;
140 | //关闭
141 | case FlutterTencentadMethod.onClose:
142 | if (mounted) {
143 | setState(() {
144 | _isShowAd = false;
145 | });
146 | }
147 | widget.callBack?.onClose!();
148 | break;
149 | //竞价
150 | case FlutterTencentadMethod.onECPM:
151 | Map map = call.arguments;
152 | widget.callBack?.onECPM!(map["ecpmLevel"], map["ecpm"]);
153 | break;
154 | case FlutterTencentadMethod.onVideoPlay:
155 | widget.callBack?.onVideoPlay?.call();
156 | break;
157 | case FlutterTencentadMethod.onVideoPause:
158 | widget.callBack?.onVideoPause?.call();
159 | break;
160 | case FlutterTencentadMethod.onVideoStop:
161 | widget.callBack?.onVideoStop?.call();
162 | break;
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/lib/flutter_tencentad.dart:
--------------------------------------------------------------------------------
1 | export 'flutter_tencentad_stream.dart';
2 | export 'flutter_tencentad_code.dart.dart';
3 |
4 | import 'dart:async';
5 |
6 | import 'package:flutter/material.dart';
7 | import 'package:flutter/services.dart';
8 | import 'package:flutter_tencentad/banner/banner_ad_view.dart';
9 | import 'package:flutter_tencentad/splash/splash_ad_view.dart';
10 | import 'flutter_tencentad_code.dart.dart';
11 |
12 | import 'express/express_ad_view.dart';
13 |
14 | part 'flutter_tencentad_callback.dart';
15 |
16 | part 'flutter_tencentad_bidding_controller.dart';
17 |
18 | class FlutterTencentad {
19 | static const MethodChannel _channel =
20 | const MethodChannel('flutter_tencentad');
21 |
22 | ///
23 | /// # SDK注册初始化
24 | ///
25 | /// [androidId] androidId 必填
26 | ///
27 | /// [iosId] iosId 必填
28 | ///
29 | /// [channelId] channelId 渠道id [FlutterTencentadChannel]
30 | ///
31 | /// [personalized] personalized 是否开启个性化广告 [FlutterTencentadPersonalized]
32 | ///
33 | /// [enableCollectAppInstallStatus] 安卓隐私合规 是否开启收集应用安装状态
34 | ///
35 | static Future register({
36 | required String androidId,
37 | required String iosId,
38 | int? personalized,
39 | bool? debug,
40 | int? channelId,
41 | Map? androidPrivacy,
42 | Map? convOptimizelnfo,
43 | bool? enableCollectAppInstallStatus,
44 | }) async {
45 | return await _channel.invokeMethod("register", {
46 | "androidId": androidId,
47 | "iosId": iosId,
48 | "debug": debug ?? false,
49 | "channelId": channelId ?? FlutterTencentadChannel.other,
50 | "personalized": personalized ?? FlutterTencentadPersonalized.show,
51 | "androidPrivacy": androidPrivacy ?? {},
52 | "convOptimizelnfo": convOptimizelnfo ?? {},
53 | "enableCollectAppInstallStatus": enableCollectAppInstallStatus
54 | });
55 | }
56 |
57 | ///
58 | /// # 获取SDK版本号
59 | ///
60 | static Future getSDKVersion() async {
61 | return await _channel.invokeMethod("getSDKVersion");
62 | }
63 |
64 | ///
65 | /// # 激励视频广告预加载
66 | ///
67 | /// [androidId] android广告ID
68 | ///
69 | /// [iosId] ios广告ID
70 | ///
71 | /// [rewardName] 奖励名称
72 | ///
73 | /// [rewardAmount] 奖励金额
74 | ///
75 | /// [userID] 用户id
76 | ///
77 | /// [customData] 扩展参数,服务器回调使用
78 | ///
79 | /// [downloadConfirm] 下载二次确认弹窗 默认false
80 | ///
81 | /// [videoMuted] 是否静音 默认false
82 | ///
83 | /// [isBidding] 是否开启竞价模式 默认false
84 | static Future loadRewardVideoAd({
85 | required String androidId,
86 | required String iosId,
87 | required String rewardName,
88 | required int rewardAmount,
89 | required String userID,
90 | String? customData,
91 | bool? downloadConfirm,
92 | bool? videoMuted,
93 | bool? isBidding,
94 | }) async {
95 | return await _channel.invokeMethod("loadRewardVideoAd", {
96 | "androidId": androidId,
97 | "iosId": iosId,
98 | "rewardName": rewardName,
99 | "rewardAmount": rewardAmount,
100 | "userID": userID,
101 | "customData": customData ?? "",
102 | "videoMuted": videoMuted ?? false,
103 | "downloadConfirm": downloadConfirm ?? false,
104 | "isBidding": isBidding ?? false,
105 | });
106 | }
107 |
108 | ///
109 | /// # 显示激励广告
110 | ///
111 | /// [result] 竞价成功、失败后调用 [FlutterTencentBiddingResult] ,isBidding = true时必传
112 | static Future showRewardVideoAd(
113 | {FlutterTencentBiddingResult? result}) async {
114 | return await _channel.invokeMethod("showRewardVideoAd", result?.toJson() ?? {});
115 | }
116 |
117 | ///
118 | /// # 预加载插屏广告
119 | ///
120 | /// [androidId] android广告ID
121 | ///
122 | /// [iosId] ios广告ID
123 | ///
124 | /// [isFullScreen] 是否全屏
125 | ///
126 | /// [downloadConfirm] 下载二次确认弹窗 默认false
127 | ///
128 | /// [isBidding] 是否开启竞价模式 默认false
129 | ///
130 | static Future loadUnifiedInterstitialAD({
131 | required String androidId,
132 | required String iosId,
133 | required bool isFullScreen,
134 | bool? downloadConfirm,
135 | bool? isBidding,
136 | }) async {
137 | return await _channel.invokeMethod("loadInterstitialAD", {
138 | "androidId": androidId,
139 | "iosId": iosId,
140 | "isFullScreen": isFullScreen,
141 | "downloadConfirm": downloadConfirm ?? false,
142 | "isBidding": isBidding ?? false,
143 | });
144 | }
145 |
146 | ///
147 | /// # 显示新模板渲染插屏
148 | ///
149 | ///
150 | /// [result] 竞价成功、失败后调用 [FlutterTencentBiddingResult] ,isBidding = true时必传
151 | ///
152 | static Future showUnifiedInterstitialAD(
153 | {FlutterTencentBiddingResult? result}) async {
154 | return await _channel.invokeMethod("showInterstitialAD", result?.toJson() ?? {});
155 | }
156 |
157 | ///
158 | /// # banner广告
159 | ///
160 | /// [androidId] android广告ID
161 | ///
162 | /// [iosId] ios广告ID
163 | ///
164 | /// [viewWidth] 广告宽 单位dp
165 | ///
166 | /// [viewHeight] 广告高 单位dp 宽高比应该为6.4:1
167 | ///
168 | /// [FlutterTencentAdBannerCallBack] 广告回调
169 | ///
170 | /// [downloadConfirm] 下载二次确认弹窗 默认false
171 | ///
172 | /// [isBidding] 是否开启竞价模式 默认false
173 | ///
174 | /// [bidding] 竞价成功、失败后调用 [FlutterTencentAdBiddingController] ,isBidding = true时必传
175 | ///
176 | static Widget bannerAdView(
177 | {required String androidId,
178 | required String iosId,
179 | required double viewWidth,
180 | required double viewHeight,
181 | bool? downloadConfirm,
182 | bool? isBidding,
183 | FlutterTencentAdBiddingController? bidding,
184 | FlutterTencentadBannerCallBack? callBack}) {
185 | return BannerAdView(
186 | androidId: androidId,
187 | iosId: iosId,
188 | viewWidth: viewWidth,
189 | viewHeight: viewHeight,
190 | callBack: callBack,
191 | downloadConfirm: downloadConfirm ?? false,
192 | isBidding: isBidding ?? false,
193 | bidding: bidding,
194 | );
195 | }
196 |
197 | ///
198 | /// # 开屏广告
199 | ///
200 | /// [androidId] android广告ID
201 | ///
202 | /// [iosId] ios广告ID
203 | ///
204 | /// [fetchDelay] 设置开屏广告从请求到展示所花的最大时长(并不是指广告曝光时长),
205 | /// 取值范围为[1500, 5000]ms。如果需要使用默认值,可以调用上一个构造方法,
206 | /// 或者给 fetchDelay 设为0。
207 | ///
208 | /// [FlutterTencentAdSplashCallBack] 广告回调
209 | ///
210 | /// [downloadConfirm] 下载二次确认弹窗 默认false
211 | ///
212 | /// [isBidding] 是否开启竞价模式 默认false
213 | ///
214 | /// [bidding] 竞价成功、失败后调用 [FlutterTencentAdBiddingController] ,isBidding = true时必传
215 | ///
216 | static Widget splashAdView(
217 | {required String androidId,
218 | required String iosId,
219 | required int fetchDelay,
220 | bool? downloadConfirm,
221 | bool? isBidding,
222 | FlutterTencentAdBiddingController? bidding,
223 | FlutterTencentadSplashCallBack? callBack}) {
224 | return SplashAdView(
225 | androidId: androidId,
226 | iosId: iosId,
227 | fetchDelay: fetchDelay,
228 | callBack: callBack,
229 | downloadConfirm: downloadConfirm ?? false,
230 | isBidding: isBidding ?? false,
231 | bidding: bidding,
232 | );
233 | }
234 |
235 | ///
236 | /// # 动态信息流/横幅/视频贴片广告
237 | ///
238 | /// [androidId] android广告ID
239 | ///
240 | /// [iosId] ios广告ID
241 | ///
242 | /// [viewWidth] 广告宽 单位dp
243 | ///
244 | /// [viewHeight] 广告高 单位dp
245 | ///
246 | /// [FlutterTencentAdExpressCallBack] 回调事件
247 | ///
248 | /// [downloadConfirm] 下载二次确认弹窗 默认false
249 | ///
250 | /// [isBidding] 是否开启竞价模式 默认false
251 | ///
252 | /// [bidding] 竞价成功、失败后调用 [FlutterTencentAdBiddingController] ,isBidding = true时必传
253 | ///
254 | static Widget expressAdView(
255 | {required String androidId,
256 | required String iosId,
257 | required int viewWidth,
258 | required int viewHeight,
259 | bool? downloadConfirm,
260 | bool? isBidding,
261 | FlutterTencentAdBiddingController? bidding,
262 | FlutterTencentadExpressCallBack? callBack}) {
263 | return ExpressAdView(
264 | androidId: androidId,
265 | iosId: iosId,
266 | viewWidth: viewWidth,
267 | viewHeight: viewHeight,
268 | callBack: callBack,
269 | downloadConfirm: downloadConfirm ?? false,
270 | isBidding: isBidding ?? false,
271 | bidding: bidding,
272 | );
273 | }
274 |
275 | ///进入APP下载列表页
276 | static Future enterAPPDownloadListPage() async {
277 | return await _channel.invokeMethod("enterAPPDownloadListPage", {});
278 | }
279 |
280 | ///进入广告助手页
281 | static Future enterADTools() async {
282 | return await _channel.invokeMethod("enterADTools", {});
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/lib/flutter_tencentad_bidding_controller.dart:
--------------------------------------------------------------------------------
1 | part of 'flutter_tencentad.dart';
2 |
3 | /// @Author: gstory
4 | /// @CreateDate: 2022/9/2 14:39
5 | /// @Email gstory0404@gmail.com
6 | /// @Description: 优量汇竞价
7 |
8 | class FlutterTencentAdBiddingController {
9 | late MethodChannel? _methodChannel;
10 |
11 | init(MethodChannel? method) {
12 | _methodChannel = method;
13 | }
14 |
15 | //回传竞价结果
16 | void biddingResult(FlutterTencentBiddingResult result){
17 | //竞价成功
18 | if(result.isSuccess){
19 | _methodChannel?.invokeMethod('biddingSucceeded', {
20 | 'expectCostPrice': result.expectCostPrice,
21 | 'highestLossPrice': result.highestLossPrice,
22 | });
23 | //竞价失败
24 | }else{
25 | _methodChannel?.invokeMethod('biddingSucceeded', {
26 | 'winPrice': result.winPrice,
27 | 'lossReason': result.lossReason,
28 | 'adnId': result.adnId,
29 | });
30 | }
31 | }
32 | }
33 |
34 | class FlutterTencentBiddingResult {
35 | int? expectCostPrice;
36 | int? highestLossPrice;
37 | int? winPrice;
38 | int? lossReason;
39 | String? adnId;
40 |
41 | bool isSuccess = true;
42 |
43 | FlutterTencentBiddingResult();
44 |
45 | ///竞价成功
46 | ///
47 | ///[expectCostPrice] 竞胜出价,类型为Integer
48 | ///
49 | ///[highestLossPrice] 最大竞败方出价,类型为Integer
50 | FlutterTencentBiddingResult success(int expectCostPrice,int highestLossPrice) {
51 | this.isSuccess = true;
52 | this.expectCostPrice = expectCostPrice;
53 | this.highestLossPrice = highestLossPrice;
54 | return this;
55 | }
56 |
57 | ///竞价失败
58 | ///
59 | /// [winPrice] 本次竞胜方出价(单位:分),类型为Integer。选填
60 | ///
61 | /// [lossReason] 优量汇广告竞败原因,类型为Integer。必填 [FlutterTencentAdBiddingLossReason]
62 | ///
63 | /// [adnId] 本次竞胜方渠道ID,类型为Integer。必填。 [FlutterTencentAdADNID]
64 | FlutterTencentBiddingResult fail(int winPrice, int lossReason, String adnId) {
65 | this.isSuccess = false;
66 | this.winPrice = winPrice;
67 | this.lossReason = lossReason;
68 | this.adnId = adnId;
69 | return this;
70 | }
71 |
72 | FlutterTencentBiddingResult.fromJson(Map json) {
73 | expectCostPrice = json['expectCostPrice'];
74 | highestLossPrice = json['highestLossPrice'];
75 | winPrice = json['winPrice'];
76 | lossReason = json['lossReason'];
77 | adnId = json['adnId'];
78 | }
79 |
80 | Map toJson() {
81 | final Map data = new Map();
82 | data['isSuccess'] = this.isSuccess;
83 | data['expectCostPrice'] = this.expectCostPrice;
84 | data['highestLossPrice'] = this.highestLossPrice;
85 | data['winPrice'] = this.winPrice;
86 | data['lossReason'] = this.lossReason;
87 | data['adnId'] = this.adnId;
88 | return data;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/lib/flutter_tencentad_callback.dart:
--------------------------------------------------------------------------------
1 | part of 'flutter_tencentad.dart';
2 |
3 | /// @Author: gstory
4 | /// @CreateDate: 2021/5/24 6:47 下午
5 | /// @Description: dart类作用描述
6 |
7 | ///显示
8 | typedef TOnShow = void Function();
9 |
10 | ///曝光
11 | typedef TOnExpose = void Function();
12 |
13 | ///失败
14 | typedef TOnFail = void Function(int code, dynamic message);
15 |
16 | ///点击
17 | typedef TOnClick = void Function();
18 |
19 | ///视频播放
20 | typedef TOnVideoPlay = void Function();
21 |
22 | ///视频暂停
23 | typedef TOnVideoPause = void Function();
24 |
25 | ///视频播放结束
26 | typedef TOnVideoStop = void Function();
27 |
28 | ///跳过
29 | typedef TOnSkip = void Function();
30 |
31 | ///倒计时结束
32 | typedef TOnFinish = void Function();
33 |
34 | ///加载超时
35 | typedef TOnTimeOut = void Function();
36 |
37 | ///关闭
38 | typedef TOnClose = void Function();
39 |
40 | ///广告预加载完成
41 | typedef TOnReady = void Function();
42 |
43 | ///广告预加载未完成
44 | typedef TOnUnReady = void Function();
45 |
46 | ///广告奖励验证
47 | typedef TOnVerify = void Function(
48 | String transId, String rewardName, int rewardAmount);
49 |
50 | ///倒计时
51 | typedef TOnADTick = void Function(int time);
52 |
53 | ///竞价回调
54 | typedef TOnECPM = void Function(String ecpmLevel, int ecpm);
55 |
56 | ///banner广告回调
57 | class FlutterTencentadBannerCallBack {
58 | TOnShow? onShow;
59 | TOnFail? onFail;
60 | TOnClick? onClick;
61 | TOnExpose? onExpose;
62 | TOnClose? onClose;
63 | TOnECPM? onECPM;
64 |
65 | FlutterTencentadBannerCallBack(
66 | {this.onShow,
67 | this.onFail,
68 | this.onClick,
69 | this.onExpose,
70 | this.onClose,
71 | this.onECPM});
72 | }
73 |
74 | ///动态信息流/横幅/视频贴片广告回调
75 | class FlutterTencentadExpressCallBack {
76 | TOnShow? onShow;
77 | TOnFail? onFail;
78 | TOnClick? onClick;
79 | TOnExpose? onExpose;
80 | TOnClose? onClose;
81 | TOnECPM? onECPM;
82 | TOnVideoPlay? onVideoPlay;
83 | TOnVideoPause? onVideoPause;
84 | TOnVideoStop? onVideoStop;
85 |
86 | FlutterTencentadExpressCallBack({
87 | this.onShow,
88 | this.onFail,
89 | this.onClick,
90 | this.onExpose,
91 | this.onClose,
92 | this.onECPM,
93 | this.onVideoPlay,
94 | this.onVideoPause,
95 | this.onVideoStop,
96 | });
97 | }
98 |
99 | ///开屏广告回调
100 | class FlutterTencentadSplashCallBack {
101 | TOnClose? onClose;
102 | TOnShow? onShow;
103 | TOnFail? onFail;
104 | TOnClick? onClick;
105 | TOnExpose? onExpose;
106 | TOnADTick? onADTick;
107 | TOnECPM? onECPM;
108 |
109 | FlutterTencentadSplashCallBack(
110 | {this.onShow,
111 | this.onFail,
112 | this.onClick,
113 | this.onClose,
114 | this.onExpose,
115 | this.onADTick,
116 | this.onECPM});
117 | }
118 |
119 | ///插屏广告回调
120 | class FlutterTencentadInteractionCallBack {
121 | TOnShow? onShow;
122 | TOnClick? onClick;
123 | TOnClose? onClose;
124 | TOnFail? onFail;
125 | TOnReady? onReady;
126 | TOnUnReady? onUnReady;
127 | TOnExpose? onExpose;
128 | TOnVerify? onVerify;
129 | TOnECPM? onECPM;
130 |
131 | FlutterTencentadInteractionCallBack(
132 | {this.onShow,
133 | this.onClick,
134 | this.onClose,
135 | this.onFail,
136 | this.onExpose,
137 | this.onReady,
138 | this.onUnReady,
139 | this.onVerify,
140 | this.onECPM});
141 | }
142 |
143 | ///激励广告回调
144 | class FlutterTencentadRewardCallBack {
145 | TOnShow? onShow;
146 | TOnClose? onClose;
147 | TOnExpose? onExpose;
148 | TOnFail? onFail;
149 | TOnClick? onClick;
150 | TOnVerify? onVerify;
151 | TOnReady? onReady;
152 | TOnFinish? onFinish;
153 | TOnUnReady? onUnReady;
154 | TOnECPM? onECPM;
155 |
156 | FlutterTencentadRewardCallBack(
157 | {this.onShow,
158 | this.onClick,
159 | this.onExpose,
160 | this.onClose,
161 | this.onFail,
162 | this.onVerify,
163 | this.onReady,
164 | this.onFinish,
165 | this.onUnReady,
166 | this.onECPM});
167 | }
168 |
--------------------------------------------------------------------------------
/lib/flutter_tencentad_code.dart.dart:
--------------------------------------------------------------------------------
1 | /// 描述:
2 | /// @author guozi
3 | /// @e-mail gstory0404@gmail.com
4 | /// @time 2020/3/11
5 |
6 | ///数据类型
7 | class FlutterTencentadType {
8 | static const String adType = "adType";
9 |
10 | ///激励广告
11 | static const String rewardAd = "rewardAd";
12 |
13 | ///插屏广告
14 | static const String interactAd = "interactAd";
15 | }
16 |
17 | class FlutterTencentadMethod {
18 | ///stream中 广告方法
19 | static const String onAdMethod = "onAdMethod";
20 |
21 | ///广告加载状态 view使用
22 | ///显示view
23 | static const String onShow = "onShow";
24 |
25 | ///广告曝光
26 | static const String onExpose = "onExpose";
27 |
28 | ///加载失败
29 | static const String onFail = "onFail";
30 |
31 | ///点击
32 | static const String onClick = "onClick";
33 |
34 | ///视频播放
35 | static const String onVideoPlay = "onVideoPlay";
36 |
37 | ///视频暂停
38 | static const String onVideoPause = "onVideoPause";
39 |
40 | ///视频结束
41 | static const String onVideoStop = "onVideoStop";
42 |
43 | ///倒计时结束
44 | static const String onFinish = "onFinish";
45 |
46 | ///加载超时
47 | static const String onTimeOut = "onTimeOut";
48 |
49 | ///广告关闭
50 | static const String onClose = "onClose";
51 |
52 | ///广告奖励校验
53 | static const String onVerify = "onVerify";
54 |
55 | ///广告预加载完成
56 | static const String onReady = "onReady";
57 |
58 | ///广告未预加载
59 | static const String onUnReady = "onUnReady";
60 |
61 | ///倒计时
62 | static const String onADTick = "onADTick";
63 | ///竞价
64 | static const String onECPM = "onECPM";
65 | }
66 |
67 | ///渠道id
68 | class FlutterTencentadChannel {
69 | ///百度
70 | static const int baidu = 1;
71 | ///头条
72 | static const int toutiao = 2;
73 | ///优量汇
74 | static const int tencent = 3;
75 | ///搜狗
76 | static const int sougou = 4;
77 | ///其他网盟
78 | static const int otherAd = 5;
79 | ///oppe
80 | static const int oppo = 6;
81 | ///vivo
82 | static const int vivo = 7;
83 | ///huawei
84 | static const int huawei = 8;
85 | ///应用宝
86 | static const int yinyongbao = 9;
87 | ///小米
88 | static const int xiaomi = 10;
89 | ///金立
90 | static const int jinli = 11;
91 | ///百度手机助手
92 | static const int baiduMobile = 12;
93 | ///魅族
94 | static const int meizu = 13;
95 | ///App Store
96 | static const int AppStore = 14;
97 | ///其他
98 | static const int other = 999;
99 | }
100 |
101 | ///个性化广告
102 | class FlutterTencentadPersonalized {
103 | ///屏蔽个性化推荐广告
104 | static const int close = 1;
105 |
106 | ///不屏蔽个性化推荐广告
107 | static const int show = 0;
108 | }
109 |
110 |
111 | ///竞价失败原因
112 | class FlutterTencentAdBiddingLossReason {
113 | /// 竞争力不足,如优量汇不是本次竞价的最高出价方,可上报此竞败原因
114 | static const int LOW_PRICE = 1;
115 | /// 返回超时,如优量汇在本次竞价中未返回广告,可上报此竞败原因
116 | static const int TIME_OUT = 2;
117 | ///其他
118 | static const int OTHER = 10001;
119 | }
120 |
121 | ///本次竞胜方渠道ID
122 | class FlutterTencentAdADNID {
123 | ///1 - 输给优量汇其它广告,当优量汇目标价报价为本次竞价的最高报价时,可上报此值,仅对混合比价类型的开发者适用
124 | static const String tencentADN = "1";
125 | /// 2 - 输给第三方ADN,当其它ADN报价为本次竞价的最高报价时,可上报此值,您无需回传具体竞胜方渠道;
126 | static const String othoerADN = "2";
127 | /// 3 - 输给自售广告主,当自售广告源报价为本次竞价的最高报价时,可上报此值,仅对有自售广告源的开发者使用
128 | static const String appADN = "3";
129 | }
130 |
--------------------------------------------------------------------------------
/lib/flutter_tencentad_stream.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/services.dart';
4 |
5 | import 'flutter_tencentad.dart';
6 |
7 | /// @Author: gstory
8 | /// @CreateDate: 2021/8/9 9:30 下午
9 | /// @Description: dart类作用描述
10 |
11 | const EventChannel tencentAdEventEvent =
12 | EventChannel("com.gstory.flutter_tencentad/adevent");
13 |
14 | class FlutterTencentAdStream {
15 | ///
16 | /// # 注册stream监听原生返回的信息
17 | ///
18 | /// [rewardAdCallBack] 激励广告回调
19 | ///
20 | /// [interactionAdCallBack] 插屏广告回调
21 | ///
22 | static StreamSubscription initAdStream(
23 | {FlutterTencentadRewardCallBack? flutterTencentadRewardCallBack,
24 | FlutterTencentadInteractionCallBack?
25 | flutterTencentadInteractionCallBack}) {
26 | StreamSubscription _adStream =
27 | tencentAdEventEvent.receiveBroadcastStream().listen((data) {
28 | switch (data[FlutterTencentadType.adType]) {
29 |
30 | ///激励广告
31 | case FlutterTencentadType.rewardAd:
32 | switch (data[FlutterTencentadMethod.onAdMethod]) {
33 | case FlutterTencentadMethod.onShow:
34 | if (flutterTencentadRewardCallBack?.onShow != null) {
35 | flutterTencentadRewardCallBack?.onShow!();
36 | }
37 | break;
38 | case FlutterTencentadMethod.onClose:
39 | if (flutterTencentadRewardCallBack?.onClose != null) {
40 | flutterTencentadRewardCallBack?.onClose!();
41 | }
42 | break;
43 | case FlutterTencentadMethod.onFail:
44 | if (flutterTencentadRewardCallBack?.onFail != null) {
45 | flutterTencentadRewardCallBack?.onFail!(
46 | data["code"], data["message"]);
47 | }
48 | break;
49 | case FlutterTencentadMethod.onClick:
50 | if (flutterTencentadRewardCallBack?.onClick != null) {
51 | flutterTencentadRewardCallBack?.onClick!();
52 | }
53 | break;
54 | case FlutterTencentadMethod.onVerify:
55 | if (flutterTencentadRewardCallBack?.onVerify != null) {
56 | flutterTencentadRewardCallBack?.onVerify!(
57 | data["transId"], data["rewardName"], data["rewardAmount"]);
58 | }
59 | break;
60 | case FlutterTencentadMethod.onFinish:
61 | if (flutterTencentadRewardCallBack?.onFinish != null) {
62 | flutterTencentadRewardCallBack?.onFinish!();
63 | }
64 | break;
65 | case FlutterTencentadMethod.onReady:
66 | if (flutterTencentadRewardCallBack?.onReady != null) {
67 | flutterTencentadRewardCallBack?.onReady!();
68 | }
69 | break;
70 | case FlutterTencentadMethod.onUnReady:
71 | if (flutterTencentadRewardCallBack?.onUnReady != null) {
72 | flutterTencentadRewardCallBack?.onUnReady!();
73 | }
74 | break;
75 | case FlutterTencentadMethod.onExpose:
76 | if (flutterTencentadRewardCallBack?.onExpose != null) {
77 | flutterTencentadRewardCallBack?.onExpose!();
78 | }
79 | break;
80 | case FlutterTencentadMethod.onECPM:
81 | if (flutterTencentadRewardCallBack?.onECPM != null) {
82 | flutterTencentadRewardCallBack?.onECPM!(
83 | data["ecpmLevel"], data["ecpm"]);
84 | }
85 | break;
86 | }
87 | break;
88 |
89 | ///插屏广告
90 | case FlutterTencentadType.interactAd:
91 | switch (data[FlutterTencentadMethod.onAdMethod]) {
92 | case FlutterTencentadMethod.onShow:
93 | if (flutterTencentadInteractionCallBack?.onShow != null) {
94 | flutterTencentadInteractionCallBack?.onShow!();
95 | }
96 | break;
97 | case FlutterTencentadMethod.onClose:
98 | if (flutterTencentadInteractionCallBack?.onClose != null) {
99 | flutterTencentadInteractionCallBack?.onClose!();
100 | }
101 | break;
102 | case FlutterTencentadMethod.onFail:
103 | if (flutterTencentadInteractionCallBack?.onFail != null) {
104 | flutterTencentadInteractionCallBack?.onFail!(
105 | data["code"], data["message"]);
106 | }
107 | break;
108 | case FlutterTencentadMethod.onClick:
109 | if (flutterTencentadInteractionCallBack?.onClick != null) {
110 | flutterTencentadInteractionCallBack?.onClick!();
111 | }
112 | break;
113 | case FlutterTencentadMethod.onExpose:
114 | if (flutterTencentadInteractionCallBack?.onExpose != null) {
115 | flutterTencentadInteractionCallBack?.onExpose!();
116 | }
117 | break;
118 | case FlutterTencentadMethod.onReady:
119 | if (flutterTencentadInteractionCallBack?.onReady != null) {
120 | flutterTencentadInteractionCallBack?.onReady!();
121 | }
122 | break;
123 | case FlutterTencentadMethod.onUnReady:
124 | if (flutterTencentadInteractionCallBack?.onUnReady != null) {
125 | flutterTencentadInteractionCallBack?.onUnReady!();
126 | }
127 | break;
128 | case FlutterTencentadMethod.onVerify:
129 | if (flutterTencentadInteractionCallBack?.onVerify != null) {
130 | flutterTencentadInteractionCallBack?.onVerify!(
131 | data["transId"], "", 0);
132 | }
133 | break;
134 | case FlutterTencentadMethod.onECPM:
135 | if (flutterTencentadInteractionCallBack?.onECPM != null) {
136 | flutterTencentadInteractionCallBack?.onECPM!(
137 | data["ecpmLevel"], data["ecpm"]);
138 | }
139 | break;
140 | }
141 | break;
142 | }
143 | });
144 | return _adStream;
145 | }
146 |
147 | static void deleteAdStream(StreamSubscription stream) {
148 | stream.cancel();
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/lib/splash/splash_ad_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/services.dart';
4 | import 'package:flutter_tencentad/flutter_tencentad.dart';
5 |
6 | ///
7 | /// Description: 描述
8 | /// Author: Gstory
9 | /// Email: gstory0404@gmail.com
10 | /// CreateDate: 2021/8/7 17:33
11 | ///
12 | class SplashAdView extends StatefulWidget {
13 | final String androidId;
14 | final String iosId;
15 | final int fetchDelay;
16 | final FlutterTencentadSplashCallBack? callBack;
17 | final bool downloadConfirm;
18 | final bool isBidding;
19 | final FlutterTencentAdBiddingController? bidding;
20 |
21 | const SplashAdView({
22 | Key? key,
23 | required this.androidId,
24 | required this.iosId,
25 | required this.fetchDelay,
26 | this.callBack,
27 | required this.downloadConfirm,
28 | required this.isBidding,
29 | this.bidding,
30 | }) : super(key: key);
31 |
32 | @override
33 | _SplashAdViewState createState() => _SplashAdViewState();
34 | }
35 |
36 | class _SplashAdViewState extends State {
37 | String _viewType = "com.gstory.flutter_tencentad/SplashAdView";
38 |
39 | MethodChannel? _channel;
40 |
41 | //广告是否显示
42 | bool _isShowAd = true;
43 |
44 | @override
45 | void initState() {
46 | super.initState();
47 | _isShowAd = true;
48 | }
49 |
50 | @override
51 | Widget build(BuildContext context) {
52 | if (!_isShowAd) {
53 | return Container();
54 | }
55 | if (defaultTargetPlatform == TargetPlatform.android) {
56 | return Container(
57 | width: MediaQuery.of(context).size.width,
58 | height: MediaQuery.of(context).size.height,
59 | child: AndroidView(
60 | viewType: _viewType,
61 | creationParams: {
62 | "androidId": widget.androidId,
63 | "fetchDelay": widget.fetchDelay,
64 | "downloadConfirm": widget.downloadConfirm,
65 | "isBidding": widget.isBidding,
66 | },
67 | onPlatformViewCreated: _registerChannel,
68 | creationParamsCodec: const StandardMessageCodec(),
69 | ),
70 | );
71 | } else if (defaultTargetPlatform == TargetPlatform.iOS) {
72 | return Container(
73 | width: MediaQuery.of(context).size.width,
74 | height: MediaQuery.of(context).size.height,
75 | child: UiKitView(
76 | viewType: _viewType,
77 | creationParams: {
78 | "iosId": widget.iosId,
79 | "fetchDelay": widget.fetchDelay,
80 | "isBidding": widget.isBidding,
81 | },
82 | onPlatformViewCreated: _registerChannel,
83 | creationParamsCodec: const StandardMessageCodec(),
84 | ),
85 | );
86 | } else {
87 | return Container();
88 | }
89 | }
90 |
91 | //注册cannel
92 | void _registerChannel(int id) {
93 | _channel = MethodChannel("${_viewType}_$id");
94 | _channel?.setMethodCallHandler(_platformCallHandler);
95 | widget.bidding?.init(_channel);
96 | }
97 |
98 | //监听原生view传值
99 | Future _platformCallHandler(MethodCall call) async {
100 | switch (call.method) {
101 | //显示广告
102 | case FlutterTencentadMethod.onShow:
103 | widget.callBack?.onShow!();
104 | if (mounted) {
105 | setState(() {
106 | _isShowAd = true;
107 | });
108 | }
109 | break;
110 | //关闭
111 | case FlutterTencentadMethod.onClose:
112 | widget.callBack?.onClose!();
113 | break;
114 | //广告加载失败
115 | case FlutterTencentadMethod.onFail:
116 | if (mounted) {
117 | setState(() {
118 | _isShowAd = false;
119 | });
120 | }
121 | Map map = call.arguments;
122 | widget.callBack?.onFail!(map["code"], map["message"]);
123 | break;
124 | //点击
125 | case FlutterTencentadMethod.onClick:
126 | widget.callBack?.onClick!();
127 | break;
128 | //曝光
129 | case FlutterTencentadMethod.onExpose:
130 | widget.callBack?.onExpose!();
131 | break;
132 | //倒计时
133 | case FlutterTencentadMethod.onADTick:
134 | widget.callBack?.onADTick!(call.arguments);
135 | break;
136 | //竞价
137 | case FlutterTencentadMethod.onECPM:
138 | Map map = call.arguments;
139 | widget.callBack?.onECPM!(map["ecpmLevel"], map["ecpm"]);
140 | break;
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "2.13.0"
12 | boolean_selector:
13 | dependency: transitive
14 | description:
15 | name: boolean_selector
16 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.1.2"
20 | characters:
21 | dependency: transitive
22 | description:
23 | name: characters
24 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "1.4.0"
28 | clock:
29 | dependency: transitive
30 | description:
31 | name: clock
32 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.1.2"
36 | collection:
37 | dependency: transitive
38 | description:
39 | name: collection
40 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.19.1"
44 | fake_async:
45 | dependency: transitive
46 | description:
47 | name: fake_async
48 | sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.3.3"
52 | flutter:
53 | dependency: "direct main"
54 | description: flutter
55 | source: sdk
56 | version: "0.0.0"
57 | flutter_test:
58 | dependency: "direct dev"
59 | description: flutter
60 | source: sdk
61 | version: "0.0.0"
62 | leak_tracker:
63 | dependency: transitive
64 | description:
65 | name: leak_tracker
66 | sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
67 | url: "https://pub.dev"
68 | source: hosted
69 | version: "10.0.9"
70 | leak_tracker_flutter_testing:
71 | dependency: transitive
72 | description:
73 | name: leak_tracker_flutter_testing
74 | sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
75 | url: "https://pub.dev"
76 | source: hosted
77 | version: "3.0.9"
78 | leak_tracker_testing:
79 | dependency: transitive
80 | description:
81 | name: leak_tracker_testing
82 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
83 | url: "https://pub.dev"
84 | source: hosted
85 | version: "3.0.1"
86 | matcher:
87 | dependency: transitive
88 | description:
89 | name: matcher
90 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
91 | url: "https://pub.dev"
92 | source: hosted
93 | version: "0.12.17"
94 | material_color_utilities:
95 | dependency: transitive
96 | description:
97 | name: material_color_utilities
98 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
99 | url: "https://pub.dev"
100 | source: hosted
101 | version: "0.11.1"
102 | meta:
103 | dependency: transitive
104 | description:
105 | name: meta
106 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
107 | url: "https://pub.dev"
108 | source: hosted
109 | version: "1.16.0"
110 | path:
111 | dependency: transitive
112 | description:
113 | name: path
114 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
115 | url: "https://pub.dev"
116 | source: hosted
117 | version: "1.9.1"
118 | sky_engine:
119 | dependency: transitive
120 | description: flutter
121 | source: sdk
122 | version: "0.0.0"
123 | source_span:
124 | dependency: transitive
125 | description:
126 | name: source_span
127 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
128 | url: "https://pub.dev"
129 | source: hosted
130 | version: "1.10.1"
131 | stack_trace:
132 | dependency: transitive
133 | description:
134 | name: stack_trace
135 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
136 | url: "https://pub.dev"
137 | source: hosted
138 | version: "1.12.1"
139 | stream_channel:
140 | dependency: transitive
141 | description:
142 | name: stream_channel
143 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
144 | url: "https://pub.dev"
145 | source: hosted
146 | version: "2.1.4"
147 | string_scanner:
148 | dependency: transitive
149 | description:
150 | name: string_scanner
151 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
152 | url: "https://pub.dev"
153 | source: hosted
154 | version: "1.4.1"
155 | term_glyph:
156 | dependency: transitive
157 | description:
158 | name: term_glyph
159 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
160 | url: "https://pub.dev"
161 | source: hosted
162 | version: "1.2.2"
163 | test_api:
164 | dependency: transitive
165 | description:
166 | name: test_api
167 | sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
168 | url: "https://pub.dev"
169 | source: hosted
170 | version: "0.7.4"
171 | vector_math:
172 | dependency: transitive
173 | description:
174 | name: vector_math
175 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
176 | url: "https://pub.dev"
177 | source: hosted
178 | version: "2.1.4"
179 | vm_service:
180 | dependency: transitive
181 | description:
182 | name: vm_service
183 | sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
184 | url: "https://pub.dev"
185 | source: hosted
186 | version: "15.0.0"
187 | sdks:
188 | dart: ">=3.7.0-0 <4.0.0"
189 | flutter: ">=3.18.0-18.0.pre.54"
190 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_tencentad
2 | description: A flutter plugin for TencentAD.It is convenient for Android and IOS to directly call the method and native view of advertisement SDK.
3 | version: 1.2.35
4 | homepage: https://github.com/gstory0404/flutter_tencentad
5 |
6 | environment:
7 | sdk: ">=2.12.0 <4.0.0"
8 | flutter: ">=1.20.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 |
14 | dev_dependencies:
15 | flutter_test:
16 | sdk: flutter
17 |
18 | flutter:
19 |
20 | plugin:
21 | platforms:
22 | android:
23 | package: com.gstory.flutter_tencentad
24 | pluginClass: FlutterTencentadPlugin
25 | ios:
26 | pluginClass: FlutterTencentadPlugin
27 |
28 |
--------------------------------------------------------------------------------
/test/flutter_tencentad_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/services.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 | import 'package:flutter_tencentad/flutter_tencentad.dart';
4 |
5 | void main() {
6 | const MethodChannel channel = MethodChannel('flutter_tencentad');
7 |
8 | TestWidgetsFlutterBinding.ensureInitialized();
9 |
10 | setUp(() {
11 | channel.setMockMethodCallHandler((MethodCall methodCall) async {
12 | return '42';
13 | });
14 | });
15 |
16 | tearDown(() {
17 | channel.setMockMethodCallHandler(null);
18 | });
19 | }
20 |
--------------------------------------------------------------------------------