初步添加 开屏广告

This commit is contained in:
Jin857 2024-10-16 10:52:08 +08:00
parent 34f73d5c45
commit 1f412ec18f
12 changed files with 570 additions and 59 deletions

View File

@ -7,21 +7,21 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- <application>-->
<!-- <activity android:name=".page.AdSplashActivity"-->
<!-- android:configChanges="keyboard|orientation|screenSize"-->
<!-- android:screenOrientation="portrait"-->
<!-- android:theme="@style/SplashTheme"/>-->
<!-- &lt;!&ndash; 文件兼容 &ndash;&gt;-->
<!-- <provider-->
<!-- android:name="com.qq.e.comm.GDTFileProvider"-->
<!-- android:authorities="${applicationId}.gdt.fileprovider"-->
<!-- android:exported="false"-->
<!-- android:grantUriPermissions="true">-->
<!-- <meta-data-->
<!-- android:name="android.support.FILE_PROVIDER_PATHS"-->
<!-- android:resource="@xml/gdt_file_path" />-->
<!-- </provider>-->
<!-- </application>-->
<application>
<activity android:name=".page.AdSplashActivity"
android:configChanges="keyboard|orientation|screenSize"
android:screenOrientation="portrait"
android:theme="@style/SplashTheme"/>
<!-- 文件兼容 -->
<provider
android:name="com.qq.e.comm.GDTFileProvider"
android:authorities="${applicationId}.gdt.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/gdt_file_path" />
</provider>
</application>
</manifest>

View File

@ -2,8 +2,10 @@ package com.example.union_ad_ssgf
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.util.Log
import com.example.union_ad_ssgf.config.UnionADConfig
import com.example.union_ad_ssgf.page.AdSplashActivity
import com.qq.e.comm.managers.GDTAdSdk
import com.qq.e.comm.managers.setting.GlobalSetting.setPersonalizedState
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding
@ -135,14 +137,13 @@ class PluginDelegate(var activity: Activity, pluginBinding: FlutterPluginBinding
private fun showSplashAd(call: MethodCall, result: MethodChannel.Result) {
val posId: String? = call.argument(UnionADConfig.KEY_POSID)
val logo: String? = call.argument(UnionADConfig.KEY_LOGO)
val fetchDelay: Double = call.argument(UnionADConfig.KEY_FETCH_DELAY)!!
// val intent = Intent(activity, AdSplashActivity::class.java)
// intent.putExtra(UnionADConfig.KEY_POSID, posId)
// intent.putExtra(UnionADConfig.KEY_LOGO, logo)
// intent.putExtra(UnionADConfig.KEY_FETCH_DELAY, fetchDelay)
// activity.startActivity(intent)
// result.success(true)
val intent = Intent(activity, AdSplashActivity::class.java)
intent.putExtra(UnionADConfig.KEY_POSID, posId)
intent.putExtra(UnionADConfig.KEY_LOGO, logo)
intent.putExtra(UnionADConfig.KEY_FETCH_DELAY, fetchDelay)
activity.startActivity(intent)
result.success(true)
}
}

View File

@ -31,7 +31,7 @@ class UnionAdSsgfPlugin : FlutterPlugin, ActivityAware {
/**
* 插件代理
*/
var delegate: PluginDelegate? = null
var delegate: PluginDelegate? = null
/**
@ -67,7 +67,7 @@ class UnionAdSsgfPlugin : FlutterPlugin, ActivityAware {
* 绑定activity
*/
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
delegate = PluginDelegate(binding.getActivity(), bind)
delegate = PluginDelegate(binding.activity, bind)
methodChannel.setMethodCallHandler(delegate)
eventChannel.setStreamHandler(delegate)
}

View File

@ -0,0 +1,82 @@
import 'dart:io';
/// 广
class AdsConfig {
/// Logo
static String get logo {
if (Platform.isAndroid) {
return 'flutterads_logo';
} else {
return 'LaunchImage';
}
}
/// Logo 2
static String get logo2 {
if (Platform.isAndroid) {
return 'flutterads_logo2';
} else {
return 'LaunchImage2';
}
}
/// App id
static String get appId {
return Platform.isAndroid ? '1204814627' : '1204814641';
}
/// 广id
static String get splashId {
return Platform.isAndroid ? '4046660274345204' : '1046662224832381';
}
/// 广id
static String get interstitialId {
return Platform.isAndroid ? '1066865274941328' : '7046066294830767';
}
/// 广id
static String get interstitialFullScreenVideoId {
if (Platform.isAndroid) {
return '3012521499614895';
} else {
return '3092322459911886';
}
}
/// 广id
static String get interstitialRewardVideoId {
if (Platform.isAndroid) {
return '2052820580637311';
} else {
return '9022927550132316';
}
}
/// 广id
static String get rewardVideoId {
if (Platform.isAndroid) {
return '6086667264144219';
} else {
return '3066367234238599';
}
}
/// Banner 广id
static String get bannerId {
if (Platform.isAndroid) {
return '5086068204047616';
} else {
return '7026465284342149';
}
}
/// 广id
static String get feedId {
if (Platform.isAndroid) {
return '7036167274246466';
} else {
return '8076264204347078';
}
}
}

245
example/lib/home_page.dart Normal file
View File

@ -0,0 +1,245 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:union_ad_ssgf/event/ad_event_handler.dart';
import 'package:union_ad_ssgf_example/ads_config.dart';
import 'package:union_ad_ssgf/union_ad_ssgf.dart';
//
String _result = '';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String _adEvent = '';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Union AD plugin'),
),
body: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(10),
child: Column(
children: [
SizedBox(height: 10),
Text('Result: $_result'),
SizedBox(height: 10),
Text('onAdEvent: $_adEvent'),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
child: Text('初始化'),
onPressed: () {},
),
SizedBox(height: 20),
ElevatedButton(
child: Text('请求跟踪授权'),
onPressed: () {
requestIDFA();
},
),
SizedBox(height: 20),
ElevatedButton(
child: Text('个性化广告'),
onPressed: () {
setPersonalizedAd(1);
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
child: Text('开屏(Logo2)'),
onPressed: () {
showSplashAd(AdsConfig.logo2);
},
),
SizedBox(height: 20),
ElevatedButton(
child: Text('开屏(全屏)'),
onPressed: () {
showSplashAd();
setState(() {});
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
child: Text('插屏广告'),
onPressed: () {
showInterstitialAd(AdsConfig.interstitialId);
},
),
SizedBox(height: 20),
ElevatedButton(
child: Text('插全屏广告'),
onPressed: () {
showInterstitialAd(
AdsConfig.interstitialFullScreenVideoId,
showFullScreenVideo: true,
);
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
child: Text('插屏激励'),
onPressed: () {
showInterstitialAd(
AdsConfig.interstitialRewardVideoId,
showFullScreenVideo: true,
showRewardVideo: true,
);
},
),
SizedBox(height: 20),
ElevatedButton(
child: Text('激励视频'),
onPressed: () {
showRewardVideoAd();
},
),
],
),
SizedBox(height: 20),
ElevatedButton(
child: Text('信息流'),
onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => FeedPage(),
// ));
},
),
SizedBox(height: 20),
const Center(child: Text('👇🏻 Banner 广告 👇🏻')),
const SizedBox(height: 10),
// AdBannerWidget(
// posId: AdsConfig.bannerId,
// width: 300,
// height: 80,
// interval: 0,
// show: true,
// ),
SizedBox(height: 10),
],
),
),
),
);
}
/// 广
Future<void> setAdEvent() async {
setState(() {
_adEvent = '设置成功';
});
UnionAdSsgf.onEventListener((event) {
_adEvent = 'adId:${event.adId} action:${event.action}';
if (event is AdErrorEvent) {
//
_adEvent += ' errCode:${event.errCode} errMsg:${event.errMsg}';
} else if (event is AdRewardEvent) {
//
_adEvent +=
' transId:${event.transId} customData:${event.customData} userId:${event.userId}';
}
print('onEventListener:$_adEvent');
setState(() {});
});
}
///
Future<void> requestIDFA() async {
bool result = await UnionAdSsgf.requestIDFA;
_adEvent = '请求广告标识符:$result';
setState(() {});
}
/// 广
/// [state] 0: 1:
Future<void> setPersonalizedAd(int state) async {
bool result = await UnionAdSsgf.setPersonalizedState(state);
_adEvent = '设置个性化广告:$result';
setState(() {});
}
/// 广
Future<void> showInterstitialAd(
String posId, {
bool showFullScreenVideo = false,
bool showRewardVideo = false,
}) async {
// try {
// bool result = await UnionAdSsgf.showInterstitialAd(
// posId,
// showPopup: false,
// showFullScreenVideo: showFullScreenVideo,
// showRewardVideo: showRewardVideo,
// autoPlayMuted: false,
// autoPlayOnWifi: false,
// userId: 'userId',
// customData: 'showInterstitialAd customData',
// );
// _result = "展示插屏广告${result ? '成功' : '失败'}";
// } on PlatformException catch (e) {
// _result = "展示插屏广告失败 code:${e.code} msg:${e.message} details:${e.details}";
// }
setState(() {});
}
/// 广
Future<void> showRewardVideoAd() async {
// try {
// bool result = await UnionAdSsgf.showRewardVideoAd(
// AdsConfig.rewardVideoId,
// playMuted: false,
// customData: 'showRewardVideoAd customData',
// userId: 'userId',
// );
// _result = "展示激励视频广告${result ? '成功' : '失败'}";
// } on PlatformException catch (e) {
// _result =
// "展示激励视频广告失败 code:${e.code} msg:${e.message} details:${e.details}";
// }
setState(() {});
}
}
/// 广
/// [logo] logo
Future<void> showSplashAd([String? logo]) async {
try {
bool result = await UnionAdSsgf.showSplashAd(
AdsConfig.splashId,
logo: logo,
fetchDelay: 3,
);
_result = "展示开屏广告${result ? '成功' : '失败'}";
} on PlatformException catch (e) {
_result = "展示开屏广告失败 code:${e.code} msg:${e.message} details:${e.details}";
}
}

View File

@ -1,10 +1,14 @@
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:union_ad_ssgf/union_ad_ssgf.dart';
import 'package:union_ad_ssgf/event/ad_error_event.dart';
import 'package:union_ad_ssgf/event/ad_reward_event.dart';
import 'package:union_ad_ssgf_example/ads_config.dart';
import 'package:union_ad_ssgf_example/home_page.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
@ -16,48 +20,44 @@ class MyApp extends StatefulWidget {
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
final _unionAdSsgfPlugin = UnionAdSsgf();
@override
void initState() {
super.initState();
initPlatformState();
}
setAdEvent();
init().then((value) {
if (value) {
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion =
await _unionAdSsgfPlugin.getPlatformVersion() ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
),
home: HomePage(),
);
}
/// 广 SDK
Future<bool> init() async {
bool result = await UnionAdSsgf.initAd(AdsConfig.appId);
print("----->> result: $result");
debugPrint("广告SDK 初始化${result ? '成功' : '失败'}");
return result;
}
/// 广
Future<void> setAdEvent() async {
UnionAdSsgf.onEventListener((event) {
debugPrint('adId:${event.adId} action:${event.action}');
if (event is AdErrorEvent) {
//
debugPrint(' errCode:${event.errCode} errMsg:${event.errMsg}');
} else if (event is AdRewardEvent) {
//
debugPrint(
' transId:${event.transId} userId:${event.userId} customData:${event.customData}');
}
});
}
}

View File

@ -0,0 +1,24 @@
import 'ad_event.dart';
/// 广
class AdErrorEvent extends AdEvent {
AdErrorEvent(
{required this.errCode,
required this.errMsg,
required String adId,
required String action})
: super(adId: adId, action: action);
//
final int errCode;
//
final String errMsg;
// json
factory AdErrorEvent.fromJson(Map<dynamic, dynamic> json) {
return AdErrorEvent(
errCode: json['errCode'],
errMsg: json['errMsg'],
adId: json['adId'],
action: json['action'],
);
}
}

30
lib/event/ad_event.dart Normal file
View File

@ -0,0 +1,30 @@
import 'ad_error_event.dart';
import 'ad_event_action.dart';
import 'ad_reward_event.dart';
export 'ad_error_event.dart';
export 'ad_event_action.dart';
export 'ad_reward_event.dart';
/// 广
class AdEvent {
AdEvent({required this.adId, required this.action});
// 广 id
final String adId;
//
final String action;
/// AdEvent
factory AdEvent.fromJson(Map<dynamic, dynamic> json) {
String action = json['action'];
if (action == AdEventAction.onAdError) {
return AdErrorEvent.fromJson(json);
} else if (action == AdEventAction.onAdReward) {
return AdRewardEvent.fromJson(json);
} else {
return AdEvent(
adId: json['adId'],
action: action,
);
}
}
}

View File

@ -0,0 +1,21 @@
/// 广
class AdEventAction {
// 广
static final String onAdError = "onAdError";
// 广
static final String onAdLoaded = "onAdLoaded";
// 广
static final String onAdPresent = "onAdPresent";
// 广
static final String onAdExposure = "onAdExposure";
// 广
static final String onAdClosed = "onAdClosed";
// 广
static final String onAdClicked = "onAdClicked";
// 广
static final String onAdSkip = "onAdSkip";
// 广
static final String onAdComplete = "onAdComplete";
// 广
static final String onAdReward = "onAdReward";
}

View File

@ -0,0 +1,13 @@
import 'ad_event.dart';
export 'ad_event.dart';
/// 广
typedef OnAdEventListener = void Function(AdEvent event);
/// 广
void hanleAdEvent(dynamic data, OnAdEventListener listener) {
if (data != null) {
AdEvent adEvent = AdEvent.fromJson(data);
listener.call(adEvent);
}
}

View File

@ -0,0 +1,28 @@
import 'ad_event.dart';
/// 广
class AdRewardEvent extends AdEvent {
AdRewardEvent(
{required this.transId,
this.customData,
this.userId,
required String adId,
required String action})
: super(adId: adId, action: action);
// ID
final String transId;
//
final String? customData;
//
final String? userId;
// json
factory AdRewardEvent.fromJson(Map<dynamic, dynamic> json) {
return AdRewardEvent(
adId: json['adId'],
action: json['action'],
transId: json['transId'],
customData: json['customData'],
userId: json['userId'],
);
}
}

View File

@ -1,7 +1,74 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:union_ad_ssgf/event/ad_event_handler.dart';
import 'union_ad_ssgf_platform_interface.dart';
/// Flutter 广
class UnionAdSsgf {
///
static const MethodChannel _methodChannel =
MethodChannel('union_ad_ssgf_method');
///
static const EventChannel _eventChannel = EventChannel('union_ad_ssgf_event');
///
static Future<bool> get requestIDFA async {
if (Platform.isIOS) {
final bool result = await _methodChannel.invokeMethod('requestIDFA');
return result;
}
return true;
}
/// 广
/// [appId] ID
static Future<bool> initAd(String appId) async {
final bool result = await _methodChannel.invokeMethod(
'initAd',
{'appId': appId},
);
print("🎉🎉🎉 UnionAd ==> 初始化完成");
return result;
}
/// 广
/// 0广1广
static Future<bool> setPersonalizedState(int state) async {
final bool result = await _methodChannel.invokeMethod(
'setPersonalizedState',
{'state': state},
);
return result;
}
/// 广
/// [posId] 广 id
/// [logo] logo
/// [fetchDelay] 广 3 [1.5~5]
static Future<bool> showSplashAd(String posId,
{String? logo, double fetchDelay = 3}) async {
final bool result = await _methodChannel.invokeMethod(
'showSplashAd',
{
'posId': posId,
'logo': logo,
'fetchDelay': fetchDelay,
},
);
return result;
}
///
///@params onData
static Future<void> onEventListener(OnAdEventListener onAdEventListener) async {
_eventChannel.receiveBroadcastStream().listen((data) {
hanleAdEvent(data, onAdEventListener);
});
}
Future<String?> getPlatformVersion() {
return UnionAdSsgfPlatform.instance.getPlatformVersion();
}