Flutter广告管理插件bidmad_plugin的使用
Flutter广告管理插件bidmad_plugin的使用
简介
BidmadPlugin 是一个用于在 Flutter 应用程序中使用 Bidmad 广告 SDK 的插件。通过该插件,你可以在 Flutter 移动应用中展示横幅广告、插屏广告和激励视频广告。
开发指南
1. 安卓设置
1.1 gradle.properties 设置
在 gradle.properties
文件中添加以下选项:
android.enableDexingArtifactTransform=false
1.2 Proguard 设置
如果使用 Proguard,请添加以下规则:
-keep class com.adop.sdk.** { *; }
-keep class ad.helper.openbidding.** { *; }
-keep class com.adop.sdk.adapter.**{ *; }
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
# Pangle
-keep class com.bytedance.sdk.** { *; }
-keep class com.bykv.vk.openvk.component.video.api.** { *; }
# Tapjoy
-keep class com.tapjoy.** { *; }
-keep class com.moat.** { *; }
-keepattributes JavascriptInterface
-keepattributes *Annotation*
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keep class com.google.android.gms.ads.identifier.** { *; }
-dontwarn com.tapjoy.**
1.3 Admob 应用程序 ID 设置
在 AndroidManifest.xml
文件中的 <application>
标签下声明以下代码(参考 Admob 应用 ID 指南):
<application>
...
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="YOUR_AD_APPLICATION_ID"/>
...
</application>
2. iOS 设置
2.1 Xcode 版本和隐私清单
- 请使用 Xcode 15.3 或更高版本进行应用程序构建和分发。
- 当将应用程序提交到 App Store 时,请使用以下指南正确设置您的隐私调查:隐私清单与隐私调查指南
2.2 导入 BidmadSDK-iOS CocoaPods
在将我们的插件拉取到你的项目后,会在项目的 iOS 文件夹中生成一个 Podfile
。
- 在
Podfile
中设置平台需求为 iOS 12。 - 使用命令
pod install
安装我们的 CocoaPods iOS 框架。 - 现在,打开名为
Runner.xcworkspace
的 Xcode 工作区文件并继续执行步骤 2.2。
2.3 Xcode 构建设置
在构建设置中选择“否”以禁用 Bitcode。
2.4 Info.plist 设置
- 为了使广告网络能够正确控制用户界面,请在
Info.plist
设置中添加以下键/值对:
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
- 要使用 BidmadSDK 提供的广告网络,请将
SKAdNetworkIdentifier
添加到Info.plist
。请将以下SKAdNetworkItems
添加到info.plist
。
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>22mmun2rn5.skadnetwork</string>
</dict>
<!-- 更多 SKAdNetworkItems -->
</array>
- 同时,请添加
NSUserTrackingUsageDescription
键,并附上自己的描述,例如 “App 需要访问 IDFA 以便进行跟踪目的”。
<key>NSUserTrackingUsageDescription</key>
<string>App 需要访问 IDFA 以便进行跟踪目的</string>
3. 使用插件
3.1 初始化 BidmadSDK
执行必要的任务来运行 BidmadSDK。除非调用 initializeSdk
方法,否则 SDK 不会允许加载广告。
initializeSdk
方法接收 App 域作为参数。
在加载广告之前,请在应用程序启动时调用 initializeSdk
方法,如以下示例所示:
if (foundation.defaultTargetPlatform == foundation.TargetPlatform.android) {
FlutterBidmadCommon().initializeSdk("ANDROID_APP_DOMAIN");
} else if (foundation.defaultTargetPlatform == foundation.TargetPlatform.iOS) {
FlutterBidmadCommon().initializeSdk("IOS_APP_DOMAIN");
}
对于 v1.6.0 或更高版本,可以接收一个回调,指示初始化是否成功完成。
FlutterBidmadCommon common = FlutterBidmadCommon();
if (foundation.defaultTargetPlatform == foundation.TargetPlatform.android) {
common.setInitializeCallbackListener(onInitialized: (bool isInitialized) {
print("Android Initialization Done: $isInitialized");
});
common.initializeSdkWithCallback("ANDROID_APP_DOMAIN");
} else if (foundation.defaultTargetPlatform == foundation.TargetPlatform.iOS) {
common.setInitializeCallbackListener(onInitialized: (bool isInitialized) {
print("IOS Initialization Done: $isInitialized");
});
common.initializeSdkWithCallback("IOS_APP_DOMAIN");
}
3.1 横幅广告
以下是请求横幅广告的示例。
3.1.1 横幅广告基于位置放置
// 横幅广告初始化
FlutterBidmadCommon common = FlutterBidmadCommon();
FlutterBaseBanner banner;
common.initBannerChannel().then((value) {
String _channelNm = value;
banner = FlutterBaseBanner(
channelName: _channelNm
);
banner.setAdInfo("YOUR_ZONE_ID");
banner.setCallbackListener(
onLoadAd: (BidmadInfo? info){
print("banner onLoadAd");
},
onFailAd: (String error){
print("banner onFailAd");
}
);
// 选项
// banner.setInterval(120); // 横幅广告刷新时间(60s~120s)
});
// 横幅广告加载
banner.load(300); // 设置位置 Y(高度)
// 横幅广告移除
banner.removeAdView();
3.1.2 横幅广告小部件
// 横幅广告小部件初始化
Container(
child: BidmadBannerWidget(
onBidmadBannerWidgetCreated: _onWidgetTestCreated,
),
height: 50.0, // 横幅高度(50, 100, 250)
),
// onBidmadBannerWidgetCreated
void _onWidgetTestCreated(FlutterBaseBanner controller){
controller.setAdInfo("YOUR_ZONE_ID");
controller.setCallbackListener(
onLoadAd: (BidmadInfo? info){
print("banner onLoadAd");
},
onFailAd: (String error){
print("banner onFailAd");
}
);
controller.loadWidget();
}
3.1.3 先加载广告,稍后再显示横幅广告小部件(仅支持 v1.6.0 或更高版本)
// 先加载横幅广告
FlutterBidmadCommon common = FlutterBidmadCommon();
FlutterBaseBannerRefined bannerAd;
common.initBannerRefinedChannel().then((chanNm) {
FlutterBaseBannerRefined.create(channelNm: chanNm, zoneId: "YOUR_ZONE_ID").then((ad) {
bannerAd = ad;
bannerAd.setCallbackListener(
onLoadAd: (BidmadInfo? info) {
print("bannerAdWidget onLoad");
textView.text = "onLoadAd";
setState(() {
isLoaded = true;
});
},
onFailAd: (String error) {
print("bannerAdWidget onFailAd : "+error);
textView.text = "onFailAd";
},
onClickAd: (BidmadInfo? info) {
print("bannerAdWidget onClickAd");
textView.text = "onClickAd";
});
bannerAd.load();
});
});
// 稍后通过添加 Bidmad 显示横幅广告小部件
Container(
child: isLoaded ? BidmadBannerRefinedWidget(ad: bannerAd) : Text("isLoading..."),
height: 50, // 横幅可以有 50, 100, 250 的高度
),
3.2 插屏广告
以下是请求插屏广告的示例。
// 插屏广告初始化
FlutterBidmadCommon common = FlutterBidmadCommon();
FlutterBaseInterstitial interstitial;
common.initInterstitialChannel().then((value) {
String _channelNm = value;
interstitial = FlutterBaseInterstitial(
channelName: _channelNm
);
interstitial.setAdInfo("YOUR_ZONE_ID");
interstitial.setCallbackListener(
onLoadAd: (BidmadInfo? info){
print("interstitial onLoadAd");
},
onShowAd: (BidmadInfo? info){
print("interstitial onShowAd" );
interstitial.load(); // 广告重新加载
},
onClickAd: (BidmadInfo? info){
print("interstitial onClickAd");
},
onCloseAd: (BidmadInfo? info){
print("interstitial onCloseAd");
},
onFailAd: (String error){
print("interstitial onFailAd");
}
);
});
// 插屏广告加载
interstitial.load();
// 插屏广告显示
interstitial.isLoaded().then((value){
if(value){
interstitial.show();
}
});
3.3 激励视频广告
以下是请求激励视频广告的示例。
// 激励视频广告初始化
FlutterBidmadCommon common = FlutterBidmadCommon();
FlutterBaseReward reward;
common.initRewardChannel().then((value) {
String _channelNm = value;
reward = FlutterBaseReward(
channelName: _channelNm
);
reward.setAdInfo("YOUR_ZONE_ID");
reward.setCallbackListener(
onLoadAd: (BidmadInfo? info){
print("reward onLoadAd");
},
onShowAd: (BidmadInfo? info){
print("reward onShowAd");
reward.load();
},
onCompleteAd: (BidmadInfo? info){
print("reward onCompleteAd");
},
onSkipAd: (BidmadInfo? info){
print("reward onSkippedAd");
},
onCloseAd: (BidmadInfo? info){
print("reward onCloseAd");
},
onClickAd: (BidmadInfo? info){
print("reward onClickAd");
},
onFailAd: (String error){
print("reward onFailAd");
}
);
});
// 激励视频广告加载
reward.load();
// 激励视频广告显示
reward.isLoaded().then((value){
if(value){
reward.show();
}
});
3.4 原生广告小部件
原生广告是以特定于应用程序的用户界面组件的形式向用户展示的广告格式。由于需要独特的内部应用程序设计来显示原生广告,因此在 Android 和 iOS 上使用此功能需要额外的设置。
Android 设置
- 参考 Android 原生广告布局示例 创建 XML 文件。
- 在资源文件中创建一个 layout 文件夹并将 XML 文件放入其中。
- 将创建的 XML 文件名(不包括扩展名)复制并传递给
BidmadNativeAdWidget
构造函数的layoutName
参数。
BidmadNativeAdWidget(
onBidmadNativeAdWidgetCreated: _onBidmadNativeAdWidgetCreated,
layoutName: "nativead_layout",
width: 400,
height: 400
),
iOS 设置
- 参考 iOS 原生广告布局设置指南 创建 XIB 文件。
- 打开
Runner.xcworkspace
。 - 将创建的 XIB 文件放入项目 Runner 文件夹内的导航区域。
- 将创建的 XIB 文件名(不包括扩展名)复制并传递给
BidmadNativeAdWidget
构造函数的layoutName
参数。
BidmadNativeAdWidget(
onBidmadNativeAdWidgetCreated: _onBidmadNativeAdWidgetCreated,
layoutName: "IOSNativeAd",
width: 400,
height: 400
),
以下是请求原生广告的示例:
// 横幅广告小部件初始化
Container(
child: BidmadNativeAdWidget(
onBidmadNativeAdWidgetCreated: _onBidmadNativeAdWidgetCreated,
layoutName:"YOUR_XML_OR_XIB_FILE_NAME", // 请输入 XIB 或 XML 文件名
width: 400,
height: 400
),
),
// 在横幅广告小部件完全创建后,_onBidmadNativeAdWidgetCreated 回调将被调用
void _onBidmadNativeAdWidgetCreated(FlutterBaseNativeAd controller) {
controller.setAdInfo("YOUR_ZONE_ID");
controller.setCallbackListener(
onLoadAd: (BidmadInfo? info) {
print("NativeAd onLoadAd");
},
onFailAd: (String error) {
print("NativeAd onFailAd" + error);
},
onClickAd: (BidmadInfo? info) {
print("NativeAd onClickAd");
}
);
controller.loadWidget();
}
3.5 ATT 功能
reqAdTrackingAuthorization()
显示一个弹出窗口,请求用户授权应用跟踪。该函数将返回一组数字字符串值,表示结果。
FlutterBidmadCommon common = FlutterBidmadCommon();
common.reqAdTrackingAuthorization().then(
(value) {
switch (value) {
case "0":
print("App Tracking Not Determined");
break;
case "1":
print("App Tracking Restricted Authoriziation Status");
break;
case "2":
print("App Tracking Denied Authorization Status");
break;
case "3":
print("App Tracking Authorized Authorization Status");
break;
case "4":
print("user is on lower version than iOS 14");
break;
}
}
);
- 对于 App 跟踪未确定,函数将返回 0,
- 对于应用跟踪受限制授权状态,函数将返回 1,
- 对于应用跟踪拒绝授权状态,函数将返回 2,
- 对于应用跟踪授权授权状态,函数将返回 3,
- 最后,如果用户低于 iOS 14,则返回 4。
如果你希望通过插件以外的方法获得应用跟踪同意,请将 setAdvertiserTrackingEnabled
的值设为 True(用户同意),False(用户拒绝)。
common.setAdvertiserTrackingEnabled(false);
print(common.getAdvertiserTrackingEnabled());
更多关于Flutter广告管理插件bidmad_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter广告管理插件bidmad_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter广告管理插件bidmad_plugin
的示例代码。请注意,为了运行以下代码,你需要确保已经在你的Flutter项目中添加了bidmad_plugin
依赖,并且已经按照插件的官方文档完成了必要的配置。
首先,在你的pubspec.yaml
文件中添加bidmad_plugin
依赖:
dependencies:
flutter:
sdk: flutter
bidmad_plugin: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来获取依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤使用bidmad_plugin
来加载和显示广告。
1. 初始化插件
在你的应用的主入口文件(通常是main.dart
)中,初始化bidmad_plugin
。
import 'package:flutter/material.dart';
import 'package:bidmad_plugin/bidmad_plugin.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
BidmadPlugin.init(
appId: '你的App ID', // 替换为你的Bidmad App ID
adUnitId: '你的Ad Unit ID', // 替换为你的Ad Unit ID
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
2. 显示广告
在你的主页面或其他需要显示广告的页面中,使用BidmadPlugin
来加载和显示广告。例如,我们可以在一个按钮点击事件中加载一个横幅广告:
import 'package:flutter/material.dart';
import 'package:bidmad_plugin/bidmad_plugin.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
BannerAd? _bannerAd;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Ad Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _loadAndShowBannerAd,
child: Text('Show Banner Ad'),
),
SizedBox(height: 50),
if (_bannerAd != null)
Container(
height: 50,
child: AdWidget(ad: _bannerAd!),
),
],
),
),
);
}
Future<void> _loadAndShowBannerAd() async {
// 加载横幅广告
final BannerAd bannerAd = BannerAd(
adUnitId: '你的Banner Ad Unit ID', // 替换为你的Banner Ad Unit ID
size: AdSize.banner,
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
print('Banner Ad loaded.');
setState(() {
_bannerAd = ad as BannerAd;
});
},
onAdFailedToLoad: (Ad ad, LoadAdError error) {
print('Banner Ad failed to load: ${error.message}');
_bannerAd = null;
},
onAdOpened: (Ad ad) => print('Banner Ad opened.'),
onAdClosed: (Ad ad) {
print('Banner Ad closed.');
_bannerAd = null;
},
onAdImpression: (Ad ad) => print('Banner Ad impression.'),
),
);
// 显示横幅广告
bannerAd.load();
}
}
注意事项
- 配置权限:确保在
AndroidManifest.xml
和Info.plist
中配置了必要的广告权限和设置。 - 测试广告:在开发阶段,使用测试广告单元ID来避免违反广告网络的使用政策。
- 错误处理:添加适当的错误处理逻辑,以处理广告加载失败的情况。
这个示例展示了如何使用bidmad_plugin
在Flutter应用中加载和显示横幅广告。你可以根据插件的官方文档进一步探索其他类型的广告(如插屏广告、视频广告等)的实现方法。