Commit 191187b2 authored by wanglei's avatar wanglei

[同步]广告的问题

parent c069ba6c
...@@ -3,6 +3,9 @@ package com.dumpster.cleaner.business.ads ...@@ -3,6 +3,9 @@ package com.dumpster.cleaner.business.ads
import com.dumpster.cleaner.MyApplication import com.dumpster.cleaner.MyApplication
import com.dumpster.cleaner.business.helper.EventUtils import com.dumpster.cleaner.business.helper.EventUtils
import com.dumpster.cleaner.utils.LogEx import com.dumpster.cleaner.utils.LogEx
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import org.json.JSONObject import org.json.JSONObject
import java.util.UUID import java.util.UUID
...@@ -22,7 +25,10 @@ abstract class AdEvent { ...@@ -22,7 +25,10 @@ abstract class AdEvent {
var adUnit: String = "" var adUnit: String = ""
var from: String = "" var from: String = ""
val reqId = UUID.randomUUID().toString() var reqId = UUID.randomUUID().toString()
var isUnLimit: Boolean = false
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
fun adPrepareShow() { fun adPrepareShow() {
val obj1 = JSONObject() val obj1 = JSONObject()
...@@ -37,8 +43,8 @@ abstract class AdEvent { ...@@ -37,8 +43,8 @@ abstract class AdEvent {
val obj = JSONObject() val obj = JSONObject()
obj.put("req_id", reqId) obj.put("req_id", reqId)
obj.put("ad_unit", adUnit) obj.put("ad_unit", adUnit)
obj.put("ad_type", adUnit)
obj.put("from", from) obj.put("from", from)
obj.put("ad_type", adUnit)
EventUtils.event("ad_pull_start", ext = obj) EventUtils.event("ad_pull_start", ext = obj)
LogEx.logDebug(TAG, "ad_pull_start_$adUnit $obj") LogEx.logDebug(TAG, "ad_pull_start_$adUnit $obj")
} }
......
package com.dumpster.cleaner.business.ads package com.dumpster.cleaner.business.ads
import android.app.Activity
import android.app.Dialog import android.app.Dialog
import com.dumpster.cleaner.business.ads.LimitUtils.openInterLastShowTime import com.dumpster.cleaner.business.ads.LimitUtils.openInterLastShowTime
import java.lang.ref.WeakReference
class AdState<T>() { class AdState<T>() {
var adDialog: Dialog? = null var adDialog: Dialog? = null
...@@ -17,33 +16,27 @@ class AdState<T>() { ...@@ -17,33 +16,27 @@ class AdState<T>() {
var currentAd: T? = null var currentAd: T? = null
/** /**
* 是否正在缓存加载广告 * 当前缓存广告对应的event
*/ */
var loadingAd: Boolean = false var currentAdEvent: AdEvent? = null
/** /**
* 用于保存引用现有页面,在此页面显示广告(因为要等待广告加载完毕) * 是否正在缓存加载广告
*/ */
var activityRef: WeakReference<Activity>? = null var loadingAd: Boolean = false
/** /**
* 上一次的缓存成功时间 * 上一次的缓存成功时间
*/ */
var lastLoadTime: Long = 0 var lastLoadTime: Long = 0
/**
* 上次展示时间
*/
// var lastShowTime: Long = 0
/** /**
* 广告已经展示 * 广告已经展示
*/ */
fun onAdDisplayed() { fun onAdDisplayed() {
currentAd = null currentAd = null
activityRef = null currentAdEvent = null
adDialog?.dismiss() adDialog?.dismiss()
adDialog = null adDialog = null
...@@ -63,14 +56,17 @@ class AdState<T>() { ...@@ -63,14 +56,17 @@ class AdState<T>() {
adDialog = null adDialog = null
currentAd = null currentAd = null
activityRef = null currentAdEvent = null
} }
fun onAdLoaded(ad: T?) { fun onAdLoaded(ad: T?, adEvent: AdEvent?) {
//这里可能提前设置,所有可以不设置,max回调的类型可能不同 //这里可能提前设置,所有可以不设置,max回调的类型可能不同
if (ad != null) { if (ad != null) {
currentAd = ad currentAd = ad
} }
if (adEvent != null) {
currentAdEvent = adEvent
}
loadingAd = false loadingAd = false
lastLoadTime = System.currentTimeMillis() lastLoadTime = System.currentTimeMillis()
} }
...@@ -82,4 +78,7 @@ class AdState<T>() { ...@@ -82,4 +78,7 @@ class AdState<T>() {
} }
fun adAvailable() =
currentAd != null || ((System.currentTimeMillis() - lastLoadTime) / 1000 / 60).toInt() < 30
} }
...@@ -7,6 +7,7 @@ import com.dumpster.cleaner.GlobalConfig ...@@ -7,6 +7,7 @@ import com.dumpster.cleaner.GlobalConfig
import com.dumpster.cleaner.bean.config.AdConfigBean import com.dumpster.cleaner.bean.config.AdConfigBean
import com.dumpster.cleaner.business.ads.AdsType import com.dumpster.cleaner.business.ads.AdsType
import com.dumpster.cleaner.business.ads.LimitUtils import com.dumpster.cleaner.business.ads.LimitUtils
import com.dumpster.cleaner.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
import com.google.ads.mediation.admob.AdMobAdapter import com.google.ads.mediation.admob.AdMobAdapter
import com.google.android.gms.ads.AdListener import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.AdRequest
...@@ -42,7 +43,7 @@ class AdBannerMgr { ...@@ -42,7 +43,7 @@ class AdBannerMgr {
adView = AdView(parent.context) adView = AdView(parent.context)
parent.addView(adView) parent.addView(adView)
adView?.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(adView) adView?.let { it.onPaidEventListener = AdmobOnPaidEventListener(it, admobEvent.scope) }
listener = ViewTreeObserver.OnGlobalLayoutListener { listener = ViewTreeObserver.OnGlobalLayoutListener {
val screenPixelDensity = parent.context.resources.displayMetrics.density val screenPixelDensity = parent.context.resources.displayMetrics.density
......
...@@ -4,6 +4,7 @@ import android.app.Activity ...@@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Context import android.content.Context
import com.dumpster.cleaner.GlobalConfig import com.dumpster.cleaner.GlobalConfig
import com.dumpster.cleaner.MyApplication import com.dumpster.cleaner.MyApplication
import com.dumpster.cleaner.bean.config.AdConfigBean
import com.dumpster.cleaner.business.ads.AdCountDownDialog.createUICountdownTimer import com.dumpster.cleaner.business.ads.AdCountDownDialog.createUICountdownTimer
import com.dumpster.cleaner.business.ads.AdCountDownDialog.showAdCountDownDialog import com.dumpster.cleaner.business.ads.AdCountDownDialog.showAdCountDownDialog
import com.dumpster.cleaner.business.ads.AdEvent import com.dumpster.cleaner.business.ads.AdEvent
...@@ -11,13 +12,14 @@ import com.dumpster.cleaner.business.ads.AdState ...@@ -11,13 +12,14 @@ import com.dumpster.cleaner.business.ads.AdState
import com.dumpster.cleaner.business.ads.AdsShowCallBack import com.dumpster.cleaner.business.ads.AdsShowCallBack
import com.dumpster.cleaner.business.ads.AdsType import com.dumpster.cleaner.business.ads.AdsType
import com.dumpster.cleaner.business.ads.LimitUtils import com.dumpster.cleaner.business.ads.LimitUtils
import com.dumpster.cleaner.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
import com.dumpster.cleaner.utils.LogEx
import com.google.android.gms.ads.AdError import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.interstitial.InterstitialAd import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import java.lang.ref.WeakReference
/** /**
...@@ -28,58 +30,88 @@ class AdInterMgr { ...@@ -28,58 +30,88 @@ class AdInterMgr {
private var adState = AdState<InterstitialAd>() private var adState = AdState<InterstitialAd>()
private var showCallBack: AdsShowCallBack? = null private var showCallBack: AdsShowCallBack? = null
//正在加载回调
private var loadingCallBack: (() -> Unit)? = null
fun show( fun show(
activity: Activity, activity: Activity,
isUnLimit: Boolean,
adEvent: AdEvent, adEvent: AdEvent,
showCallBack: AdsShowCallBack? = null showCallBack: AdsShowCallBack? = null
) { ) {
if (activity.isFinishing || activity.isDestroyed) { if (activity.isFinishing || activity.isDestroyed) {
showCallBack?.failed(0)
adState.onAdDisplayFailed()
return return
} }
if (!isUnLimit) { val nowAdEvent = adEvent
if (!LimitUtils.isAdShow(AdsType.INSERT, adEvent)) { //currentAdEvent!=null 表示有缓存广告,关联reqId
adState.currentAdEvent?.let { nowAdEvent.reqId = it.reqId }
if (!nowAdEvent.isUnLimit) {
if (!LimitUtils.isAdShow(AdsType.INSERT, nowAdEvent)) {
showCallBack?.failed(2) showCallBack?.failed(2)
return return
} }
if (LimitUtils.isIntervalLimited(adEvent)) { if (LimitUtils.isIntervalLimited(nowAdEvent)) {
showCallBack?.failed(3) showCallBack?.failed(3)
return return
} }
} }
adEvent.adPrepareShow()
adState.activityRef = WeakReference(activity) val needLoad = !adState.adAvailable()
this.showCallBack = showCallBack this.showCallBack = showCallBack
if (adState.adDialog == null) { if (adState.adDialog == null) {
adState.adDialog = activity.showAdCountDownDialog() adState.adDialog = activity.showAdCountDownDialog()
} else { } else {
adState.adDialog?.dismiss() adState.adDialog?.dismiss()
} }
val needLoad = adState.currentAd == null || !adAvailable()
nowAdEvent.adPrepareShow()
LogEx.logDebug(adEvent.TAG, "needLoad=$needLoad")
if (needLoad) { if (needLoad) {
if (!adState.loadingAd) { if (!adState.loadingAd) {
loadAd(activity, adEvent, isUnLimit, true) LogEx.logDebug(adEvent.TAG, "inter adState !loadingAd")
loadAd(activity, nowAdEvent) {
showReadyAd(activity, nowAdEvent)
}
} else {
LogEx.logDebug(adEvent.TAG, "inter adState is loadingAd")
loadingCallBack = {
showReadyAd(activity, nowAdEvent)
}
} }
} else { } else {
showReadyAd(adEvent) LogEx.logDebug(adEvent.TAG, "inter ad ready")
showReadyAd(activity, nowAdEvent)
} }
} }
private fun showReadyAd(adEvent: AdEvent) {
private fun showReadyAd(ac: Activity, adEvent: AdEvent) {
val admobEvent = (adEvent as AdmobEvent)
val tag = adEvent.TAG
LogEx.logDebug(tag, "showReadyAd ac=$ac currentAd=${adState.currentAd}")
if (ac.isFinishing || ac.isDestroyed || adState.currentAd == null) {
LogEx.logDebug(tag, "showReadyAd ac=null isFinishing isDestroyed")
showCallBack?.failed()
adState.onAdDisplayFailed()
return
}
adState.currentAd?.run { adState.currentAd?.run {
fullScreenContentCallback = object : FullScreenContentCallback() { fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdShowedFullScreenContent() { override fun onAdShowedFullScreenContent() {
super.onAdShowedFullScreenContent() super.onAdShowedFullScreenContent()
val ac = adState.activityRef?.get() admobEvent.showAd(responseInfo, ac)
(adEvent as AdmobEvent).showAd(responseInfo, ac)
adState.onAdDisplayed() adState.onAdDisplayed()
showCallBack?.show() showCallBack?.show()
...@@ -94,7 +126,7 @@ class AdInterMgr { ...@@ -94,7 +126,7 @@ class AdInterMgr {
showCallBack?.adFailed() showCallBack?.adFailed()
showCallBack = null showCallBack = null
adEvent.adShowError(adError) admobEvent.adShowError(adError)
} }
override fun onAdDismissedFullScreenContent() { override fun onAdDismissedFullScreenContent() {
...@@ -109,27 +141,28 @@ class AdInterMgr { ...@@ -109,27 +141,28 @@ class AdInterMgr {
override fun onAdClicked() { override fun onAdClicked() {
super.onAdClicked() super.onAdClicked()
(adEvent as AdmobEvent).clickAd(responseInfo) admobEvent.clickAd(responseInfo)
//计数 //计数
LimitUtils.addClickNum() LimitUtils.addClickNum()
} }
} }
val activity = adState.activityRef?.get() if (AdConfigBean.adsConfigBean.showCountdown) {
activity?.let {
createUICountdownTimer(adState.adDialog) { createUICountdownTimer(adState.adDialog) {
show(it) show(ac)
} }
} else {
show(ac)
} }
} }
} }
fun loadAd( fun loadAd(
context: Context, context: Context,
adEvent: AdEvent, adEvent: AdEvent,
isUnLimit: Boolean = false, loadCallBack: (() -> Unit)? = null
isShow: Boolean = false,
) { ) {
if (!isUnLimit) { if (!adEvent.isUnLimit) {
if (!LimitUtils.isAdShow(AdsType.INSERT, adEvent)) { if (!LimitUtils.isAdShow(AdsType.INSERT, adEvent)) {
this.showCallBack?.close(4) this.showCallBack?.close(4)
this.showCallBack = null this.showCallBack = null
...@@ -138,26 +171,41 @@ class AdInterMgr { ...@@ -138,26 +171,41 @@ class AdInterMgr {
} }
} }
//避免无效预加载
if (adState.loadingAd && loadCallBack == null && loadingCallBack == null) {
//容错机制
adState.loadingAd = false
return
}
adState.loadingAd = true
adEvent.adPulStart() adEvent.adPulStart()
InterstitialAd.load( InterstitialAd.load(
context, GlobalConfig.ID_ADMOB_INTER, AdRequest.Builder().build(), context, GlobalConfig.ID_ADMOB_INTER, AdRequest.Builder().build(),
object : InterstitialAdLoadCallback() { object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) { override fun onAdLoaded(ad: InterstitialAd) {
adState.onAdLoaded(ad) val event = (adEvent as AdmobEvent)
if (this@AdInterMgr.showCallBack != null || isShow) { ad.onPaidEventListener = AdmobOnPaidEventListener(ad, adEvent.scope)
showReadyAd(adEvent) adState.onAdLoaded(ad, adEvent)
}
(adEvent as AdmobEvent).pullAd(ad.responseInfo) loadCallBack?.invoke()
loadingCallBack?.invoke()
loadingCallBack = null
LimitUtils.addRequestNum() LimitUtils.addRequestNum()
ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad) event.pullAd(ad.responseInfo)
} }
override fun onAdFailedToLoad(loadAdError: LoadAdError) { override fun onAdFailedToLoad(loadAdError: LoadAdError) {
adState.onAdLoadFailed() adState.onAdLoadFailed()
(adEvent as AdmobEvent).pullAd(loadAdError.responseInfo, loadAdError) if (loadCallBack != null) {
adState.onAdDisplayFailed()
}
showCallBack?.adFailed() showCallBack?.adFailed()
showCallBack = null showCallBack = null
(adEvent as AdmobEvent).pullAd(loadAdError.responseInfo, loadAdError)
} }
} }
) )
...@@ -165,5 +213,4 @@ class AdInterMgr { ...@@ -165,5 +213,4 @@ class AdInterMgr {
} }
private fun adAvailable() = ((System.currentTimeMillis() - adState.lastLoadTime) / 1000 / 60).toInt() < 30
} }
\ No newline at end of file
...@@ -7,6 +7,7 @@ import com.dumpster.cleaner.MyApplication ...@@ -7,6 +7,7 @@ import com.dumpster.cleaner.MyApplication
import com.dumpster.cleaner.business.ads.AdsType import com.dumpster.cleaner.business.ads.AdsType
import com.dumpster.cleaner.business.ads.LimitUtils import com.dumpster.cleaner.business.ads.LimitUtils
import com.dumpster.cleaner.business.ads.NativeParentView import com.dumpster.cleaner.business.ads.NativeParentView
import com.dumpster.cleaner.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
import com.google.android.gms.ads.AdListener import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdLoader import com.google.android.gms.ads.AdLoader
import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.AdRequest
...@@ -19,7 +20,6 @@ import java.util.concurrent.ConcurrentLinkedDeque ...@@ -19,7 +20,6 @@ import java.util.concurrent.ConcurrentLinkedDeque
*原生广告加载显示管理类 *原生广告加载显示管理类
*/ */
class AdNativeMgr { class AdNativeMgr {
private val TAG = "AdNativeMgr" private val TAG = "AdNativeMgr"
/** /**
...@@ -52,7 +52,7 @@ class AdNativeMgr { ...@@ -52,7 +52,7 @@ class AdNativeMgr {
).forNativeAd { nativeAd -> ).forNativeAd { nativeAd ->
lastTime = System.currentTimeMillis() lastTime = System.currentTimeMillis()
nativeAd.setOnPaidEventListener(AdmobEvent.EventOnPaidEventListener(nativeAd)) nativeAd.setOnPaidEventListener(AdmobOnPaidEventListener(nativeAd, admobEvent.scope))
currentNativeAd = nativeAd currentNativeAd = nativeAd
admobEvent.pullAd(nativeAd.responseInfo) admobEvent.pullAd(nativeAd.responseInfo)
...@@ -101,6 +101,7 @@ class AdNativeMgr { ...@@ -101,6 +101,7 @@ class AdNativeMgr {
if (!LimitUtils.isShowNative(AdsType.NATIVE, admobEvent)) { if (!LimitUtils.isShowNative(AdsType.NATIVE, admobEvent)) {
return return
} }
Log.e(TAG, "adNative can show") Log.e(TAG, "adNative can show")
if (!adAvailable()) { if (!adAvailable()) {
...@@ -109,29 +110,28 @@ class AdNativeMgr { ...@@ -109,29 +110,28 @@ class AdNativeMgr {
cacheItems.clear() cacheItems.clear()
} }
parent.isAdShowed = true
val nativeAd = cacheItems.peek() val nativeAd = cacheItems.peek()
var showAction: (ad: NativeAd) -> Unit = { ad ->
parent.isAdShowed = true
nativeCallBack?.invoke(ad)
parent.setNativeAd(ad, layout)
admobEvent.showAd(ad.responseInfo)
//添加原生数量
LimitUtils.addNativeDisplayNum()
loadAd(MyApplication.appContext, AdmobEvent("nativeAd", "preload"), null)
}
if (nativeAd == null) { if (nativeAd == null) {
loadAd(parent.context, admobEvent) { ad -> loadAd(parent.context, admobEvent) { ad ->
Log.e(TAG, "load show") Log.e(TAG, "load show")
nativeCallBack?.invoke(ad) showAction.invoke(ad)
parent.setNativeAd(ad, layout)
admobEvent.showAd(ad.responseInfo)
loadAd(MyApplication.appContext, AdmobEvent("nativeAd", "preload"), null)
} }
} else { } else {
val flag = cacheItems.remove(nativeAd) val flag = cacheItems.remove(nativeAd)
Log.e(TAG, "ready show remove=$flag size=${cacheItems.size}") Log.e(TAG, "ready show remove=$flag size=${cacheItems.size}")
showAction.invoke(nativeAd)
nativeCallBack?.invoke(nativeAd)
parent.setNativeAd(nativeAd, layout)
admobEvent.showAd(nativeAd.responseInfo)
loadAd(MyApplication.appContext, AdmobEvent("nativeAd", "preload"), null)
} }
} }
...@@ -139,4 +139,5 @@ class AdNativeMgr { ...@@ -139,4 +139,5 @@ class AdNativeMgr {
private fun adAvailable(): Boolean { private fun adAvailable(): Boolean {
return (lastTime == 0L) || ((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < 30 return (lastTime == 0L) || ((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < 30
} }
} }
\ No newline at end of file
...@@ -9,13 +9,13 @@ import com.dumpster.cleaner.business.ads.AdState ...@@ -9,13 +9,13 @@ import com.dumpster.cleaner.business.ads.AdState
import com.dumpster.cleaner.business.ads.AdsShowCallBack import com.dumpster.cleaner.business.ads.AdsShowCallBack
import com.dumpster.cleaner.business.ads.AdsType import com.dumpster.cleaner.business.ads.AdsType
import com.dumpster.cleaner.business.ads.LimitUtils import com.dumpster.cleaner.business.ads.LimitUtils
import com.dumpster.cleaner.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
import com.dumpster.cleaner.utils.LogEx
import com.google.android.gms.ads.AdError import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.appopen.AppOpenAd import com.google.android.gms.ads.appopen.AppOpenAd
import java.lang.ref.WeakReference
/** /**
* 开屏广告加载显示管理类 * 开屏广告加载显示管理类
...@@ -26,47 +26,69 @@ class AdOpenMgr { ...@@ -26,47 +26,69 @@ class AdOpenMgr {
private val adState = AdState<AppOpenAd>() private val adState = AdState<AppOpenAd>()
private var showCallBack: AdsShowCallBack? = null private var showCallBack: AdsShowCallBack? = null
//正在加载回调
private var loadingCallBack: (() -> Unit)? = null
fun show(activity: Activity, isUnLimit: Boolean, adEvent: AdEvent, showCallBack: AdsShowCallBack?) { fun show(
activity: Activity,
adEvent: AdEvent,
showCallBack: AdsShowCallBack?
) {
if (activity.isFinishing || activity.isDestroyed) { if (activity.isFinishing || activity.isDestroyed) {
return return
} }
if (!isUnLimit) {
if (!LimitUtils.isAdShow(AdsType.OPEN, adEvent)) { val nowAdEvent = adEvent
adState.currentAdEvent?.let { nowAdEvent.reqId = it.reqId }
if (!nowAdEvent.isUnLimit) {
if (!LimitUtils.isAdShow(AdsType.OPEN, nowAdEvent)) {
showCallBack?.failed() showCallBack?.failed()
return return
} }
if (LimitUtils.isIntervalLimited(adEvent)) { if (LimitUtils.isIntervalLimited(nowAdEvent)) {
showCallBack?.failed() showCallBack?.failed()
return return
} }
} }
adEvent.adPrepareShow() val needLoad = !adState.adAvailable()
adState.activityRef = WeakReference(activity)
this.showCallBack = showCallBack this.showCallBack = showCallBack
// if (adState.adDialog == null) {
// adState.adDialog = activity.showAdPreparingDialog(1) nowAdEvent.adPrepareShow()
// } else {
// adState.adDialog?.dismiss()
// }
val needLoad = adState.currentAd == null || !adAvailable()
if (needLoad) { if (needLoad) {
if (!adState.loadingAd) { if (!adState.loadingAd) {
loadAd(activity, adEvent, isUnLimit, true) LogEx.logDebug(adEvent.TAG, "open adState !loadingAd")
loadAd(activity, adEvent) {
showReadyAd(activity)
}
} else {
LogEx.logDebug(adEvent.TAG, "open adState is loadingAd")
loadingCallBack = {
showReadyAd(activity)
}
} }
} else { } else {
showReadyAd(adEvent) LogEx.logDebug(adEvent.TAG, "open ad ready")
showReadyAd(activity)
} }
} }
private fun showReadyAd(adEvent: AdEvent) { private fun showReadyAd(ac: Activity) {
if (ac.isFinishing || ac.isDestroyed || adState.currentAd == null) {
LogEx.logDebug(TAG, "showReadyAd ac=null isFinishing isDestroyed")
return
}
adState.currentAd?.run { adState.currentAd?.run {
val adEvent = adState.currentAdEvent as AdmobEvent?
fullScreenContentCallback = object : FullScreenContentCallback() { fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdShowedFullScreenContent() { override fun onAdShowedFullScreenContent() {
val ac = adState.activityRef?.get()
(adEvent as AdmobEvent).showAd(this@run.responseInfo, ac) adEvent?.showAd(this@run.responseInfo, ac)
showCallBack?.show() showCallBack?.show()
...@@ -83,7 +105,7 @@ class AdOpenMgr { ...@@ -83,7 +105,7 @@ class AdOpenMgr {
showCallBack = null showCallBack = null
adState.onAdDisplayFailed() adState.onAdDisplayFailed()
(adEvent as AdmobEvent).adShowError(adError) adEvent?.adShowError(adError)
} }
...@@ -101,33 +123,38 @@ class AdOpenMgr { ...@@ -101,33 +123,38 @@ class AdOpenMgr {
} }
override fun onAdClicked() { override fun onAdClicked() {
(adEvent as AdmobEvent).clickAd(this@run.responseInfo) adEvent?.clickAd(this@run.responseInfo)
//计数 //计数
LimitUtils.addClickNum() LimitUtils.addClickNum()
} }
} }
val activity = adState.activityRef?.get() show(ac)
activity?.let { show(it) }
} }
} }
fun loadAd( fun loadAd(
context: Context, context: Context,
adEvent: AdEvent, adEvent: AdEvent,
isUnLimit: Boolean = false, loadCallBack: (() -> Unit)? = null
isShow: Boolean = false,
) { ) {
if (!isUnLimit) { if (!adEvent.isUnLimit) {
if (!LimitUtils.isAdShow(AdsType.OPEN, adEvent)) { if (!LimitUtils.isAdShow(AdsType.OPEN, adEvent)) {
this.showCallBack?.close() this.showCallBack?.failed()
this.showCallBack = null this.showCallBack = null
adState.onAdLoadFailed() adState.onAdLoadFailed()
return return
} }
} }
//避免无效预加载
if (adState.loadingAd && loadCallBack == null && loadingCallBack == null) {
//容错机制
adState.loadingAd = false
return
}
adState.loadingAd = true
adEvent.adPulStart() adEvent.adPulStart()
AppOpenAd.load( AppOpenAd.load(
...@@ -136,14 +163,15 @@ class AdOpenMgr { ...@@ -136,14 +163,15 @@ class AdOpenMgr {
AdRequest.Builder().build(), AdRequest.Builder().build(),
object : AppOpenAd.AppOpenAdLoadCallback() { object : AppOpenAd.AppOpenAdLoadCallback() {
override fun onAdLoaded(appOpenAd: AppOpenAd) { override fun onAdLoaded(appOpenAd: AppOpenAd) {
adState.onAdLoaded(appOpenAd) adState.onAdLoaded(appOpenAd, adEvent)
if (this@AdOpenMgr.showCallBack != null || isShow) {
showReadyAd(adEvent) loadCallBack?.invoke()
} loadingCallBack?.invoke()
loadingCallBack = null
(adEvent as AdmobEvent).pullAd(appOpenAd.responseInfo) (adEvent as AdmobEvent).pullAd(appOpenAd.responseInfo)
appOpenAd.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(appOpenAd) appOpenAd.onPaidEventListener = AdmobOnPaidEventListener(appOpenAd, adEvent.scope)
LimitUtils.addRequestNum() LimitUtils.addRequestNum()
} }
override fun onAdFailedToLoad(loadAdError: LoadAdError) { override fun onAdFailedToLoad(loadAdError: LoadAdError) {
...@@ -156,5 +184,4 @@ class AdOpenMgr { ...@@ -156,5 +184,4 @@ class AdOpenMgr {
) )
} }
private fun adAvailable() = ((System.currentTimeMillis() - adState.lastLoadTime) / 1000 / 60).toInt() < 30
} }
\ No newline at end of file
...@@ -25,6 +25,9 @@ import com.google.android.gms.ads.rewarded.RewardedAd ...@@ -25,6 +25,9 @@ import com.google.android.gms.ads.rewarded.RewardedAd
import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import org.json.JSONObject import org.json.JSONObject
import java.math.BigDecimal import java.math.BigDecimal
import java.util.Currency import java.util.Currency
...@@ -123,37 +126,74 @@ class AdmobEvent : AdEvent { ...@@ -123,37 +126,74 @@ class AdmobEvent : AdEvent {
LogEx.logDebug(TAG, "ad_show $obj") LogEx.logDebug(TAG, "ad_show $obj")
} }
class EventOnPaidEventListener(private val ad: Any?) : OnPaidEventListener { fun adShowError(adError: AdError) {
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("reason", adError.message)
obj.put("code", adError.code)
obj.put("from", from)
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
LogEx.logDebug(TAG, "ad_show_error $obj")
}
class AdmobOnPaidEventListener(
private val ad: Any,
private val coroutineScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
) : OnPaidEventListener {
override fun onPaidEvent(adValue: AdValue) { override fun onPaidEvent(adValue: AdValue) {
ad ?: return onPaidEvent2(ad, adValue)
SolarEngineEvent.eventSolar(ad, adValue.valueMicros) }
val adRatio = AdConfigBean.adsConfigBean.adRatio
fun onPaidEvent2(ad: Any, adValue: AdValue) {
// coroutineScope.launch {
try {
val flag = eventAdRatio()
val valueS = adValue.valueMicros > 0
if (flag && valueS) {
SolarEngineEvent.eventSolar(ad, adValue.valueMicros)
eventFireBase(adValue)
eventEvent(adValue)
}
} catch (e: Exception) {
EventUtils.event("onPaidEvent_Error")
}
// }
}
fun eventAdRatio(): Boolean {
val adRatio = AdConfigBean.Companion.adsConfigBean.adRatio
val random = Random.Default.nextInt(1, 100) val random = Random.Default.nextInt(1, 100)
if (random > adRatio) { if (random > adRatio) {
taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", 0f) taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", 0f)
taichiSharedPreferencesEditor.commit() taichiSharedPreferencesEditor.commit()
EventUtils.event("ad_price_limit") EventUtils.event("ad_price_limit")
return return false
} }
return true
}
/**
* 上报给firebase
*/
fun eventFireBase(adValue: AdValue) {
val valueMicros = adValue.valueMicros val valueMicros = adValue.valueMicros
val currencyCode = adValue.currencyCode val currencyCode = adValue.currencyCode
val precision = adValue.precisionType val currentImpressionRevenue = adValue.valueMicros.toDouble() / 1000000.0
val fbLogger = AppEventsLogger.newLogger(MyApplication.appContext) //sp里面的价格值
fbLogger.logPurchase(BigDecimal.valueOf(valueMicros / 1000000), Currency.getInstance(currencyCode)) val previousTaichiTroasCache = taichiPref.getFloat("TaichiTroasCache", 0f)
val obj = JSONObject() //当前缓存加个值
obj.put("valueMicros", valueMicros) val currentTaichiTroasCache = (previousTaichiTroasCache + currentImpressionRevenue).toFloat()
obj.put("currencyCode", currencyCode)
obj.put("precision", precision)
Firebase.analytics.logEvent("ad_price", Bundle().apply { //价值上报阀值
putDouble("valueMicros", valueMicros / 1000000.0) val taichiAdValue = AdConfigBean.Companion.adsConfigBean.taichiAdValue / 100f
})
val params = Bundle() val params = Bundle()
val currentImpressionRevenue = adValue.valueMicros.toDouble() / 1000000.0
params.putDouble(FirebaseAnalytics.Param.VALUE, currentImpressionRevenue) params.putDouble(FirebaseAnalytics.Param.VALUE, currentImpressionRevenue)
params.putString(FirebaseAnalytics.Param.CURRENCY, "USD") params.putString(FirebaseAnalytics.Param.CURRENCY, "USD")
LogEx.logDebug("EventOnPaidEventListener", "precisionType=${adValue.precisionType}") LogEx.logDebug("EventOnPaidEventListener", "precisionType=${adValue.precisionType}")
...@@ -165,31 +205,51 @@ class AdmobEvent : AdEvent { ...@@ -165,31 +205,51 @@ class AdmobEvent : AdEvent {
else -> "Invalid" else -> "Invalid"
} }
params.putString("precisionType", precisionType) params.putString("precisionType", precisionType)
Firebase.analytics.logEvent("Ad_Impression_Revenue", params)
val previousTaichiTroasCache = taichiPref.getFloat("TaichiTroasCache", 0f)
val currentTaichiTroasCache = (previousTaichiTroasCache +
currentImpressionRevenue).toFloat()
val taichiAdValue = AdConfigBean.adsConfigBean.taichiAdValue / 100f val fbLogger = AppEventsLogger.newLogger(MyApplication.Companion.appContext)
//上报
fbLogger.logPurchase(BigDecimal.valueOf(currentImpressionRevenue), Currency.getInstance(currencyCode))
//上报ad_price
Firebase.analytics.logEvent("ad_price", Bundle().apply {
putDouble("valueMicros", currentImpressionRevenue)
})
//上报Ad_Impression_Revenue
Firebase.analytics.logEvent("Ad_Impression_Revenue", params)
//上报Total_Ads_Revenue_001
if (currentTaichiTroasCache >= taichiAdValue) {//如果超过0.01就触发一次tROAS taichi事件 if (currentTaichiTroasCache >= taichiAdValue) {//如果超过0.01就触发一次tROAS taichi事件
val roasbundle = Bundle() val roasbundle = Bundle()
roasbundle.putDouble( roasbundle.putDouble(FirebaseAnalytics.Param.VALUE, currentTaichiTroasCache.toDouble())
FirebaseAnalytics.Param.VALUE,
currentTaichiTroasCache.toDouble()
)
roasbundle.putString(FirebaseAnalytics.Param.CURRENCY, "USD") roasbundle.putString(FirebaseAnalytics.Param.CURRENCY, "USD")
Firebase.analytics.logEvent("Total_Ads_Revenue_001", roasbundle) Firebase.analytics.logEvent("Total_Ads_Revenue_001", roasbundle)
taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", 0f)//重新清零,开始计算 taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", 0f)//重新清零,开始计算
val logger = AppEventsLogger.newLogger(MyApplication.appContext)
val parameters = Bundle() val parameters = Bundle()
parameters.putString(AppEventsConstants.EVENT_PARAM_CURRENCY, "USD") parameters.putString(AppEventsConstants.EVENT_PARAM_CURRENCY, "USD")
logger.logEvent("ad_value", currentTaichiTroasCache.toDouble(), parameters) fbLogger.logEvent("ad_value", currentTaichiTroasCache.toDouble(), parameters)
} else { } else {
taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", currentTaichiTroasCache) taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", currentTaichiTroasCache)
} }
taichiSharedPreferencesEditor.commit() taichiSharedPreferencesEditor.commit()
}
/**
* 上报给服务器
*/
fun eventEvent(adValue: AdValue) {
val valueMicros = adValue.valueMicros
val currencyCode = adValue.currencyCode
val precision = adValue.precisionType
val obj = JSONObject()
obj.put("valueMicros", valueMicros)
obj.put("currencyCode", currencyCode)
obj.put("precision", precision)
var key = "ad_price" var key = "ad_price"
when (ad) { when (ad) {
...@@ -313,17 +373,8 @@ class AdmobEvent : AdEvent { ...@@ -313,17 +373,8 @@ class AdmobEvent : AdEvent {
} }
} }
EventUtils.event(key, ext = obj) EventUtils.event(key, ext = obj)
} }
}
fun adShowError(adError: AdError) {
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("reason", adError.message)
obj.put("code", adError.code)
obj.put("from", from)
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
LogEx.logDebug(TAG, "ad_show_error $obj")
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment