添加 激励视频 - 初步添加

This commit is contained in:
Jin857 2024-10-16 17:35:13 +08:00
parent 1f412ec18f
commit 578c1974c5
7 changed files with 272 additions and 47 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"cmake.sourceDirectory": "/Users/jin/dev/ssgf/union_ad_ssgf/linux"
}

View File

@ -6,6 +6,7 @@ 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.example.union_ad_ssgf.page.RewardVideoPage
import com.qq.e.comm.managers.GDTAdSdk
import com.qq.e.comm.managers.setting.GlobalSetting.setPersonalizedState
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding
@ -15,24 +16,30 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
class PluginDelegate(var activity: Activity, pluginBinding: FlutterPluginBinding) :
/**
* 插件代理中心
*
* @param activity 当前 Activity
* @param bind Flutter 插件绑定对象
*/
class PluginDelegate(var activity: Activity, bind: FlutterPluginBinding) :
MethodChannel.MethodCallHandler, EventChannel.StreamHandler {
private val TAG = PluginDelegate::class.java.getSimpleName()
// Flutter 插件绑定对象
private var bind = pluginBinding
private val s = PluginDelegate::class.java.getSimpleName();
// 事件通道
private var eventSink: EventSink? = null
/*初始化代码块*/
/**
* 初始化代码块
*/
init {
_instance = this
}
companion object {
// 插件代理对象
/**
* 插件代理对象
*/
@SuppressLint("StaticFieldLeak")
private lateinit var _instance: PluginDelegate
fun getInstance(): PluginDelegate {
@ -42,37 +49,49 @@ class PluginDelegate(var activity: Activity, pluginBinding: FlutterPluginBinding
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
val method = call.method
Log.d(TAG, "MethodChannel onMethodCall method:" + method + " arguments:" + call.arguments)
Log.d(s, "MethodChannel onMethodCall method:" + method + " arguments:" + call.arguments)
when (method) {
// 获取当前版本
/**
* 获取当前版本
*/
"getPlatformVersion" -> {
getPlatformVersion(call, result)
}
// 初始化
/**
* 初始化
*/
"initAd" -> {
initAd(call, result)
}
// 设置广告个性化
/**
* 设置广告个性化
*/
"setPersonalizedState" -> {
setPersonalizedState(call, result)
}
// 开屏广告
/**
* 开屏广告
*/
"showSplashAd" -> {
showSplashAd(call, result)
}
// 激励广告
/**
* 激励广告
*/
"showRewardVideoAd" -> {
showRewardVideoAd(call, result);
}
// 错误桥接
/**
* 错误桥接
*/
else -> {
result.notImplemented()
}
}
}
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
Log.d(TAG, "EventChannel onListen arguments:" + arguments)
override fun onListen(arguments: Any, events: EventChannel.EventSink) {
Log.d(s, "EventChannel onListen arguments:$arguments")
eventSink = events
}
@ -81,7 +100,7 @@ class PluginDelegate(var activity: Activity, pluginBinding: FlutterPluginBinding
* @param arguments 参数
*/
override fun onCancel(arguments: Any?) {
Log.d(TAG, "EventChannel onCancel")
Log.d(s, "EventChannel onCancel")
eventSink = null
}
@ -101,20 +120,25 @@ class PluginDelegate(var activity: Activity, pluginBinding: FlutterPluginBinding
*/
private fun initAd(call: MethodCall, result: MethodChannel.Result) {
val appId = call.argument<String>("appId")
GDTAdSdk.initWithoutStart(activity.applicationContext, appId) // 该接口不会采集用户信息
// 调用initWithoutStart后请尽快调用start否则可能影响广告填充造成收入下降
GDTAdSdk.start(
object : GDTAdSdk.OnStartListener {
/**
* 该接口不会采集用户信息
*/
GDTAdSdk.initWithoutStart(activity.applicationContext, appId)
/**
* 调用initWithoutStart后请尽快调用start否则可能影响广告填充造成收入下降
*/
GDTAdSdk.start(object : GDTAdSdk.OnStartListener {
/**
* 推荐开发者在 onStartSuccess 回调后开始拉广告
*/
override fun onStartSuccess() {
// 推荐开发者在 onStartSuccess 回调后开始拉广告
Log.e("gdt onStartSuccess", "加载成功")
}
override fun onStartFailed(e: Exception) {
Log.e("gdt onStartFailed:", e.toString())
}
}
)
})
result.success(true)
}
@ -146,4 +170,15 @@ class PluginDelegate(var activity: Activity, pluginBinding: FlutterPluginBinding
result.success(true)
}
/**
* 显示激励视频广告
* @param call MethodCall
* @param result Result
*/
private fun showRewardVideoAd(call: MethodCall, result: MethodChannel.Result) {
val iad = RewardVideoPage()
iad.showAd(activity, 1, call)
result.success(true)
}
}

View File

@ -0,0 +1,25 @@
package com.example.union_ad_ssgf.event
/**
* @param transId 服务端验证唯一id
* @param customData 服务端验证的自定义信息
* @param userId 服务端验证的用户信息
*/
class AdRewardEvent(
posId: String?,
adId: String?,
viewId: Int?,
action: String?,
var transId: String,
var customData: String,
var userId: String,
) : AdEvent(posId, adId, viewId, action) {
override fun toMap(): HashMap<String, Any?> {
val newMap = super.toMap()
newMap["transId"] = transId
newMap["customData"] = customData
newMap["userId"] = userId
return newMap
}
}

View File

@ -7,9 +7,12 @@ import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformView
import io.flutter.plugin.platform.PlatformViewFactory
/// View 名字
/**
* View 名字
* @param viewName: 插件代理类
*/
class NativeViewFactory(
private val viewName: String, // 插件代理类
private val viewName: String,
private val pluginDelegate: PluginDelegate
) :
PlatformViewFactory(StandardMessageCodec.INSTANCE) {

View File

@ -0,0 +1,135 @@
package com.example.union_ad_ssgf.page
import android.util.Log
import com.example.union_ad_ssgf.event.AdEventAction
import com.example.union_ad_ssgf.event.AdRewardEvent
import com.qq.e.ads.rewardvideo.RewardVideoAD
import com.qq.e.ads.rewardvideo.RewardVideoADListener
import com.qq.e.ads.rewardvideo.ServerSideVerificationOptions
import com.qq.e.comm.util.AdError
import io.flutter.plugin.common.MethodCall
import java.util.Locale
/**
* 激励视频页面
*/
class RewardVideoPage() : BaseAdPage(), RewardVideoADListener {
private val TAG = RewardVideoPage::class.java.getSimpleName()
/**
* 激励广告对象
*/
private lateinit var rewardVideoAD: RewardVideoAD
/**
* 设置激励视频服务端验证的自定义信息
*/
private lateinit var customData: String
/**
* 设置服务端验证的用户信息
*/
private lateinit var userId: String
override fun loadAd(call: MethodCall?) {
/**
* 获取对应参数
*/
val playMuted: Boolean = call!!.argument("playMuted")!!
customData = call.argument("customData")!!
userId = call.argument("userId")!!
// 1. 初始化激励视频广告
rewardVideoAD = RewardVideoAD(activity, posId, this, !playMuted)
// 2. 设置服务端验证信息
val options = ServerSideVerificationOptions.Builder()
.setCustomData(customData)
.setUserId(userId) // 设置服务端验证的用户信息
.build()
// 3. 服务端验证信息
rewardVideoAD.setServerSideVerificationOptions(options)
// 4. 加载激励视频广告
rewardVideoAD.loadAD()
}
/**
* 广告加载成功可在此回调后进行广告展示
**/
override fun onADLoad() {
Log.i(TAG, "onADLoad");
rewardVideoAD.showAD();
sendEvent(AdEventAction.onAdLoaded);
}
/**
* 视频素材缓存成功可在此回调后进行广告展示
*/
override fun onVideoCached() {
Log.i(TAG, "onVideoCached")
}
/**
* 激励视频广告页面展示
*/
override fun onADShow() {
Log.i(TAG, "onADShow")
sendEvent(AdEventAction.onAdPresent)
}
/**
* 激励视频广告曝光
*/
override fun onADExpose() {
Log.i(TAG, "onADExpose")
sendEvent(AdEventAction.onAdExposure)
}
/**
* 激励视频触发激励观看视频大于一定时长或者视频播放完毕
* @param map 若选择了服务端验证可以通过 ServerSideVerificationOptions#TRANS_ID 键从 map 中获取此次交易的 id若未选择服务端验证则不需关注 map 参数
*/
override fun onReward(map: MutableMap<String, Any>?) {
val transId = map!![ServerSideVerificationOptions.TRANS_ID] as String?
Log.i(TAG, "onReward $transId") // 获取服务端验证的唯一 ID
sendEvent(AdRewardEvent(posId,"",1,AdEventAction.onAdReward, transId!!, customData, userId))
}
/**
* 激励视频广告被点击
*/
override fun onADClick() {
Log.i(TAG, "onADClick");
sendEvent(AdEventAction.onAdClicked);
}
/**
* 激励视频广告被关闭
*/
override fun onVideoComplete() {
Log.i(TAG, "onVideoComplete");
}
/**
* 激励视频广告被关闭
*/
override fun onADClose() {
Log.i(TAG, "onADClose");
sendEvent(AdEventAction.onAdClosed);
}
/**
* 广告流程出错
*/
override fun onError(error: AdError) {
val msg = java.lang.String.format(
Locale.getDefault(),
"onError, error code: %d, error msg: %s",
error.errorCode, error.errorMsg,
)
Log.i(TAG, "onError, adError=$msg")
sendErrorEvent(error.errorCode, error.errorMsg)
}
}

View File

@ -213,18 +213,18 @@ class _HomePageState extends State<HomePage> {
/// 广
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}";
// }
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(() {});
}
}

View File

@ -61,9 +61,33 @@ class UnionAdSsgf {
return result;
}
/// 广
/// [posId] 广 id
/// [playMuted]
/// [customData]
/// [userId]
static Future<bool> showRewardVideoAd(
String posId, {
bool playMuted = false,
String? customData,
String? userId,
}) async {
final bool result = await _methodChannel.invokeMethod(
'showRewardVideoAd',
{
'posId': posId,
'playMuted': playMuted,
'customData': customData,
'userId': userId,
},
);
return result;
}
///
///@params onData
static Future<void> onEventListener(OnAdEventListener onAdEventListener) async {
static Future<void> onEventListener(
OnAdEventListener onAdEventListener) async {
_eventChannel.receiveBroadcastStream().listen((data) {
hanleAdEvent(data, onAdEventListener);
});