Commit 415b15ef authored by wanglei's avatar wanglei

[迭代]广告和多语言字符串

parent 8714dc91
...@@ -176,19 +176,26 @@ dependencies { ...@@ -176,19 +176,26 @@ dependencies {
//广告 //广告
//admob渠道 //admob渠道
implementation(libs.vungle) // implementation(libs.vungle)
implementation(libs.facebook) // implementation(libs.facebook)
implementation(libs.mintegral) // implementation(libs.mintegral)
implementation(libs.pangle) // implementation(libs.pangle)
//applovin sdk // //applovin sdk
implementation(libs.applovin) // implementation(libs.applovin)
//applovin渠道 // //applovin渠道
implementation(libs.applovin.google) // implementation(libs.applovin.google)
implementation(libs.applovin.admob) // implementation(libs.applovin.admob)
implementation(libs.applovin.facebook) //meta // implementation(libs.applovin.facebook) //meta
implementation(libs.applovin.mintegral)//mintegral // implementation(libs.applovin.mintegral)//mintegral
implementation(libs.applovin.pangle) //pangle // implementation(libs.applovin.pangle) //pangle
implementation(libs.applovin.vungle) //vungle // implementation(libs.applovin.vungle) //vungle
implementation("com.google.android.gms:play-services-ads:23.5.0")
implementation("com.google.ads.mediation:applovin:13.0.1.0")
implementation("com.google.ads.mediation:facebook:6.18.0.0")
implementation("com.google.ads.mediation:mintegral:16.8.61.0")
implementation("com.google.ads.mediation:pangle:6.3.0.4.0")
implementation("com.google.ads.mediation:vungle:7.4.2.0")
val work_version = "2.8.1" val work_version = "2.8.1"
implementation("androidx.work:work-runtime-ktx:$work_version") implementation("androidx.work:work-runtime-ktx:$work_version")
......
...@@ -195,7 +195,7 @@ class MyApplication : Application() { ...@@ -195,7 +195,7 @@ class MyApplication : Application() {
private var lastTimePause = 0L private var lastTimePause = 0L
private var lastTimeResume = 0L private var lastTimeResume = 0L
private fun isHotLaunch(): Boolean { private fun isHotLaunch(): Boolean {
if ((lastTimeResume - lastTimePause) > 5000) { if ((lastTimeResume - lastTimePause) > 3500) {
return true return true
} }
return false return false
......
...@@ -4,7 +4,6 @@ package com.simplecleaner.app.bean.config ...@@ -4,7 +4,6 @@ package com.simplecleaner.app.bean.config
class AdConfigBean( class AdConfigBean(
var isAdShow: Boolean = true,//广告开关 var isAdShow: Boolean = true,//广告开关
var adSwitch: Boolean = true,//true 走admob,false走max
var taichiAdValue: Int = 1,//价值上报阀值 var taichiAdValue: Int = 1,//价值上报阀值
var adRatio: Int = 100,//价值上报随机控制 var adRatio: Int = 100,//价值上报随机控制
...@@ -12,6 +11,7 @@ class AdConfigBean( ...@@ -12,6 +11,7 @@ class AdConfigBean(
var numRequestLimit: Int = -1,//请求次数限制 var numRequestLimit: Int = -1,//请求次数限制
var numClickLimit: Int = -1,//点击次数限制 var numClickLimit: Int = -1,//点击次数限制
var timeInterval: Int = 10,//广告间隔秒 var timeInterval: Int = 10,//广告间隔秒
var timeIntervalOpen: Int = 0,//开屏广告间隔
var openAdLoading: Int = 15,//开屏广告拉取时间 var openAdLoading: Int = 15,//开屏广告拉取时间
var numNativeDisplayLimit: Int = -1,//原生展示次数限制 var numNativeDisplayLimit: Int = -1,//原生展示次数限制
......
...@@ -3,6 +3,9 @@ package com.simplecleaner.app.business.ads ...@@ -3,6 +3,9 @@ package com.simplecleaner.app.business.ads
import com.simplecleaner.app.MyApplication import com.simplecleaner.app.MyApplication
import com.simplecleaner.app.business.helper.EventUtils import com.simplecleaner.app.business.helper.EventUtils
import com.simplecleaner.app.utils.LogEx import com.simplecleaner.app.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
...@@ -25,7 +28,7 @@ abstract class AdEvent { ...@@ -25,7 +28,7 @@ abstract class AdEvent {
var from: String = "" var from: String = ""
var reqId = UUID.randomUUID().toString() var reqId = UUID.randomUUID().toString()
var isUnLimit: Boolean = false var isUnLimit: Boolean = false
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
fun adPrepareShow() { fun adPrepareShow() {
val obj1 = JSONObject() val obj1 = JSONObject()
...@@ -49,8 +52,8 @@ abstract class AdEvent { ...@@ -49,8 +52,8 @@ abstract class AdEvent {
fun adShowError(reason: Any) { fun adShowError(reason: Any) {
val obj = JSONObject() val obj = JSONObject()
obj.put("ad_unit", adUnit) obj.put("ad_unit", adUnit)
obj.put("req_id", reqId)
obj.put("from", from) obj.put("from", from)
obj.put("req_id", reqId)
obj.put("reason", reason.toString()) obj.put("reason", reason.toString())
EventUtils.event("ad_show_error", ext = obj) EventUtils.event("ad_show_error", ext = obj)
LogEx.logDebug(TAG, "ad_show_error_$adUnit $obj") LogEx.logDebug(TAG, "ad_show_error_$adUnit $obj")
...@@ -59,11 +62,10 @@ abstract class AdEvent { ...@@ -59,11 +62,10 @@ abstract class AdEvent {
fun adLimited(value: String) { fun adLimited(value: String) {
val obj = JSONObject() val obj = JSONObject()
obj.put("ad_unit", adUnit) obj.put("ad_unit", adUnit)
obj.put("req_id", reqId)
obj.put("from", from) obj.put("from", from)
obj.put("req_id", reqId)
EventUtils.event("ad_limit", value, obj) EventUtils.event("ad_limit", value, obj)
LogEx.logDebug(TAG, "ad_limit_$adUnit $obj") LogEx.logDebug(TAG, "ad_limit_$adUnit $obj")
} }
} }
\ No newline at end of file
package com.simplecleaner.app.business.ads package com.simplecleaner.app.business.ads
import android.app.Dialog import android.app.Dialog
import com.simplecleaner.app.business.ads.LimitUtils.openInterLastShowTime import com.simplecleaner.app.business.ads.LimitUtils.interLastShowTime
import com.simplecleaner.app.business.ads.LimitUtils.openLastShowTime
class AdState<T>() { class AdState<T>() {
var adDialog: Dialog? = null var adDialog: Dialog? = null
...@@ -24,41 +26,41 @@ class AdState<T>() { ...@@ -24,41 +26,41 @@ class AdState<T>() {
*/ */
var loadingAd: Boolean = false var loadingAd: Boolean = false
/**
* 用于保存引用现有页面,在此页面显示广告(因为要等待广告加载完毕)
*/
// var activityRef: WeakReference<Activity>? = null
/** /**
* 上一次的缓存成功时间 * 上一次的缓存成功时间
*/ */
var lastLoadTime: Long = 0 var lastLoadTime: Long = 0
/**
* 上次展示时间
*/
// var lastShowTime: Long = 0
/** /**
* 广告已经展示 * 广告已经展示
*/ */
fun onAdDisplayed() { fun onAdDisplayed(adsType: AdsType) {
currentAd = null currentAd = null
currentAdEvent = null currentAdEvent = null
// activityRef = null
adDialog?.dismiss() adDialog?.dismiss()
adDialog = null adDialog = null
openInterLastShowTime = System.currentTimeMillis() if (adsType == AdsType.OPEN) {
openLastShowTime = System.currentTimeMillis()
}
if (adsType == AdsType.INSERT) {
interLastShowTime = System.currentTimeMillis()
}
} }
fun onAdHidden() { fun onAdHidden(adsType: AdsType) {
//重置下上次展示的时间,避免看广告的时间算入间隔 //重置下上次展示的时间,避免看广告的时间算入间隔
openInterLastShowTime = System.currentTimeMillis() if (adsType == AdsType.OPEN) {
openLastShowTime = System.currentTimeMillis()
}
if (adsType == AdsType.INSERT) {
interLastShowTime = System.currentTimeMillis()
}
} }
...@@ -68,17 +70,16 @@ class AdState<T>() { ...@@ -68,17 +70,16 @@ class AdState<T>() {
currentAd = null currentAd = null
currentAdEvent = null currentAdEvent = null
// activityRef = null
} }
fun onAdLoaded(ad: T?, adEvent: AdEvent?) { fun loadStart(adEvent: AdEvent) {
//这里可能提前设置,所有可以不设置,max回调的类型可能不同 loadingAd = true
if (ad != null) { currentAdEvent = adEvent
currentAd = ad }
}
if (adEvent != null) { fun onAdLoaded(ad: T?) {
currentAdEvent = adEvent currentAd = ad
}
loadingAd = false loadingAd = false
lastLoadTime = System.currentTimeMillis() lastLoadTime = System.currentTimeMillis()
} }
...@@ -90,7 +91,7 @@ class AdState<T>() { ...@@ -90,7 +91,7 @@ class AdState<T>() {
} }
fun adAvailable() = fun needLoad() = currentAd == null || ((System.currentTimeMillis() - lastLoadTime) / 1000 / 60).toInt() > 30
currentAd != null || ((System.currentTimeMillis() - lastLoadTime) / 1000 / 60).toInt() < 30
} }
...@@ -5,11 +5,6 @@ import android.content.Context ...@@ -5,11 +5,6 @@ import android.content.Context
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import com.applovin.sdk.AppLovinMediationProvider
import com.applovin.sdk.AppLovinSdk
import com.applovin.sdk.AppLovinSdkInitializationConfiguration
import com.simplecleaner.app.BuildConfig
import com.simplecleaner.app.GlobalConfig
import com.simplecleaner.app.bean.config.AdConfigBean.Companion.adsConfigBean import com.simplecleaner.app.bean.config.AdConfigBean.Companion.adsConfigBean
import com.simplecleaner.app.bean.config.ConfigBean.Companion.configBean import com.simplecleaner.app.bean.config.ConfigBean.Companion.configBean
import com.simplecleaner.app.business.ads.admob.AdBannerMgr import com.simplecleaner.app.business.ads.admob.AdBannerMgr
...@@ -17,19 +12,9 @@ import com.simplecleaner.app.business.ads.admob.AdInterMgr ...@@ -17,19 +12,9 @@ import com.simplecleaner.app.business.ads.admob.AdInterMgr
import com.simplecleaner.app.business.ads.admob.AdNativeMgr import com.simplecleaner.app.business.ads.admob.AdNativeMgr
import com.simplecleaner.app.business.ads.admob.AdOpenMgr import com.simplecleaner.app.business.ads.admob.AdOpenMgr
import com.simplecleaner.app.business.ads.admob.AdmobEvent import com.simplecleaner.app.business.ads.admob.AdmobEvent
import com.simplecleaner.app.business.ads.applovin.AdMaxEvent
import com.simplecleaner.app.business.ads.applovin.MaxInsertMgr
import com.simplecleaner.app.business.ads.applovin.MaxNativeMgr
import com.simplecleaner.app.business.ads.applovin.MaxOpenMgr
import com.simplecleaner.app.business.helper.EventUtils import com.simplecleaner.app.business.helper.EventUtils
import com.simplecleaner.app.utils.AppPreferences
import com.simplecleaner.app.utils.LogEx
import com.simplecleaner.app.utils.ToastUtils.toast
import com.google.android.gms.ads.MobileAds import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import com.google.android.gms.ads.initialization.AdapterStatus import com.google.android.gms.ads.initialization.AdapterStatus
import java.util.Collections
import java.util.concurrent.Executors
/** /**
* 广告管理类 * 广告管理类
...@@ -49,27 +34,12 @@ object AdsMgr { ...@@ -49,27 +34,12 @@ object AdsMgr {
AdBannerMgr() AdBannerMgr()
} }
private val maxOpenMgr by lazy {
MaxOpenMgr()
}
private val maxInsertMgr by lazy {
MaxInsertMgr()
}
private val maxNativeMgr by lazy {
MaxNativeMgr()
}
/** /**
* 是否初始化 * 是否初始化
*/ */
var isAdmobInit = false var isAdmobInit = false
private set private set
/**
* 是否初始化
*/
var isMaxInit = false
private set
var isAdUtEvent = false var isAdUtEvent = false
...@@ -86,14 +56,7 @@ object AdsMgr { ...@@ -86,14 +56,7 @@ object AdsMgr {
* @param context 这里最好是appContext,因为是耗时操作,等它初始化完毕马上加载开屏和插屏广告 * @param context 这里最好是appContext,因为是耗时操作,等它初始化完毕马上加载开屏和插屏广告
*/ */
fun init(context: Context) { fun init(context: Context) {
if (configBean.isInBlackList) {
EventUtils.event("isInBlackList", value = "isInBlackList=${configBean.isInBlackList}")
return
}
initAdmob(context) initAdmob(context)
initMax(context)
} }
private fun initAdmob(context: Context) { private fun initAdmob(context: Context) {
...@@ -106,7 +69,7 @@ object AdsMgr { ...@@ -106,7 +69,7 @@ object AdsMgr {
EventUtils.event("AdmobInit", "AdmobInit=$isAdmobInit") EventUtils.event("AdmobInit", "AdmobInit=$isAdmobInit")
// context.toast("admob init") // context.toast("admob init")
if (adsConfigBean.adSwitch) { if (true) {
admobInitCallBack?.invoke() admobInitCallBack?.invoke()
admobInitCallBack = null admobInitCallBack = null
adNativeMgr.loadAd(context, AdmobEvent("nativeAd", context::class.java.simpleName)) adNativeMgr.loadAd(context, AdmobEvent("nativeAd", context::class.java.simpleName))
...@@ -114,44 +77,9 @@ object AdsMgr { ...@@ -114,44 +77,9 @@ object AdsMgr {
adInterMgr.loadAd(context, AdmobEvent("interAd", context::class.java.simpleName)) adInterMgr.loadAd(context, AdmobEvent("interAd", context::class.java.simpleName))
} }
} }
}
private fun initMax(context: Context) = kotlin.runCatching {
if (isMaxInit) return@runCatching
val executor = Executors.newSingleThreadExecutor()
executor.execute {
val currentGaid = AdvertisingIdClient.getAdvertisingIdInfo(context).id
AppPreferences.getInstance().getString("gid", currentGaid)
val build = AppLovinSdkInitializationConfiguration
.builder(GlobalConfig.KEY_MAX, context)
build.mediationProvider = AppLovinMediationProvider.MAX
if (BuildConfig.DEBUG) {
build.testDeviceAdvertisingIds = Collections.singletonList(currentGaid)
}
val initConfig = build.build()
runCatching {
AppLovinSdk.getInstance(context).initialize(initConfig) {
isMaxInit = true
// maxOpenMgr.loadAd(context)
if (!adsConfigBean.adSwitch) {
maxInsertMgr.loadAd(context, AdMaxEvent("interAd", context::class.java.simpleName))
context.toast("max init")
maxInitCallBack?.invoke()
maxInitCallBack = null
}
}
}
}
} }
var admobInitCallBack: (() -> Unit)? = null var admobInitCallBack: (() -> Unit)? = null
var maxInitCallBack: (() -> Unit)? = null
/** /**
...@@ -172,14 +100,9 @@ object AdsMgr { ...@@ -172,14 +100,9 @@ object AdsMgr {
return return
} }
if (configBean.isInBlackList) {
EventUtils.event("isInBlackList", "isInBlackList=${configBean.isInBlackList}")
showCallBack?.failed()
return
}
val from = activity::class.java.simpleName val from = activity::class.java.simpleName
if (adsConfigBean.adSwitch) { if (true) {
val admobEvent = AdmobEvent("openAd", from).apply { this.isUnLimit = isUnLimit } val admobEvent = AdmobEvent("openAd", from).apply { this.isUnLimit = isUnLimit }
if (isAdmobInit) { if (isAdmobInit) {
adOpenMgr.show(activity, admobEvent, showCallBack) adOpenMgr.show(activity, admobEvent, showCallBack)
...@@ -189,13 +112,6 @@ object AdsMgr { ...@@ -189,13 +112,6 @@ object AdsMgr {
adOpenMgr.show(activity, admobEvent, showCallBack) adOpenMgr.show(activity, admobEvent, showCallBack)
} }
} else { } else {
if (isMaxInit) {
maxOpenMgr.show(activity, isUnLimit, AdMaxEvent("openAd", from), showCallBack)
} else {
maxInitCallBack = {
maxOpenMgr.show(activity, isUnLimit, AdMaxEvent("openAd", from), showCallBack)
}
}
} }
} }
...@@ -218,18 +134,10 @@ object AdsMgr { ...@@ -218,18 +134,10 @@ object AdsMgr {
showCallBack?.failed() showCallBack?.failed()
return return
} }
if (configBean.isInBlackList) {
EventUtils.event("isInBlackList", configBean.isInBlackList.toString())
showCallBack?.failed()
return
}
LogEx.logDebug("showAd", "adSwitch=${adsConfigBean.adSwitch}")
val from = activity::class.java.simpleName val from = activity::class.java.simpleName
if (adsConfigBean.adSwitch) { if (true) {
adInterMgr.show(activity, AdmobEvent("interAd", from).apply { this.isUnLimit = isUnLimit }, showCallBack) adInterMgr.show(activity, AdmobEvent("interAd", from).apply { this.isUnLimit = isUnLimit }, showCallBack)
} else { } else {
maxInsertMgr.show(activity, isUnLimit, AdMaxEvent("interAd", from), showCallBack)
} }
} }
...@@ -237,29 +145,24 @@ object AdsMgr { ...@@ -237,29 +145,24 @@ object AdsMgr {
* 展示原生广告 * 展示原生广告
* *
* @param nativeView 需要展示广告的布局容器 * @param nativeView 需要展示广告的布局容器
* @param layout 原生广告布局 ,这里传入的layout要和com.example.mydemo.strategy.ads.admob.NativeView里的id一致 * @param layout 原生广告布局
*/ */
fun showNative( fun showNative(
nativeView: NativeParentView, nativeView: NativeParentView,
@LayoutRes layout: Int, @LayoutRes layout: Int,
nativeCallBack: ((Any?) -> Unit)? = null nativeCallBack: ((Any?) -> Unit)? = null
) { ) {
if (!adsConfigBean.isAdShow) { if (!adsConfigBean.isAdShow || !LimitUtils.isShowNative(AdsType.NATIVE, null)) {
nativeView.visibility = View.GONE nativeView.visibility = View.GONE
nativeCallBack?.invoke(null) nativeCallBack?.invoke(null)
return return
} }
nativeView.visibility = View.VISIBLE nativeView.visibility = View.VISIBLE
if (configBean.isInBlackList) {
EventUtils.event("isInBlackList", configBean.isInBlackList.toString())
return
}
val showNative = { val showNative = {
if (adsConfigBean.adSwitch) { if (true) {
adNativeMgr.show(AdmobEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack) adNativeMgr.show(AdmobEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack)
} else { } else {
maxNativeMgr.show(AdMaxEvent("nativeAd", "nativeAd"), nativeView, layout, nativeCallBack)
} }
} }
...@@ -282,12 +185,10 @@ object AdsMgr { ...@@ -282,12 +185,10 @@ object AdsMgr {
return return
} }
parent.visibility = View.VISIBLE parent.visibility = View.VISIBLE
if (configBean.isInBlackList) {
EventUtils.event("isInBlackList", configBean.isInBlackList.toString()) if (true) {
return
}
if (adsConfigBean.adSwitch) {
adBannerMgr.show(parent, collapsible, adClose) adBannerMgr.show(parent, collapsible, adClose)
} }
} }
}
\ No newline at end of file }
package com.simplecleaner.app.business.ads package com.simplecleaner.app.business.ads
import android.util.Log
import com.simplecleaner.app.BuildConfig import com.simplecleaner.app.BuildConfig
import com.simplecleaner.app.bean.config.AdConfigBean import com.simplecleaner.app.bean.config.AdConfigBean
import com.simplecleaner.app.utils.AppPreferences import com.simplecleaner.app.utils.AppPreferences
import com.simplecleaner.app.utils.KotlinExt.toFormatTime4 import com.simplecleaner.app.utils.KotlinExt.toFormatTime4
import com.simplecleaner.app.utils.LogEx
/** /**
...@@ -95,16 +97,15 @@ object LimitUtils { ...@@ -95,16 +97,15 @@ object LimitUtils {
AppPreferences.getInstance().put(NUM_REQUEST, 0) AppPreferences.getInstance().put(NUM_REQUEST, 0)
AppPreferences.getInstance().put(NUM_CLICK, 0) AppPreferences.getInstance().put(NUM_CLICK, 0)
} }
val flag1 = isDisplayLimited if (isDisplayLimited) {
if (flag1) {
val value = "current${getAdEventMsg(adsType)} " + val value = "current${getAdEventMsg(adsType)} " +
"show=${AppPreferences.getInstance().getInt(NUM_DISPLAY, 0)} " + "show=${AppPreferences.getInstance().getInt(NUM_DISPLAY, 0)} " +
"${getAdEventMsg(adsType).lowercase()}_" + "max_show=${AdConfigBean.adsConfigBean.numDisplayLimit}" "${getAdEventMsg(adsType).lowercase()}_" + "max_show=${AdConfigBean.adsConfigBean.numDisplayLimit}"
adEvent?.adLimited(value) adEvent?.adLimited(value)
} }
val flag2 = isClickLimited if (isClickLimited) {
if (flag2) {
val value = val value =
"current${getAdEventMsg(adsType)}Click=${AppPreferences.getInstance().getInt(NUM_CLICK, 0)} " "current${getAdEventMsg(adsType)}Click=${AppPreferences.getInstance().getInt(NUM_CLICK, 0)} "
"${getAdEventMsg(adsType).lowercase()}_max_click=${AdConfigBean.adsConfigBean.numClickLimit}" "${getAdEventMsg(adsType).lowercase()}_max_click=${AdConfigBean.adsConfigBean.numClickLimit}"
...@@ -112,15 +113,14 @@ object LimitUtils { ...@@ -112,15 +113,14 @@ object LimitUtils {
adEvent?.adLimited(value) adEvent?.adLimited(value)
} }
val flag3 = isRequestLimited if (isRequestLimited) {
if (flag3) {
val value = "current${getAdEventMsg(adsType)}Request=${AppPreferences.getInstance().getInt(NUM_REQUEST, 0)} " + val value = "current${getAdEventMsg(adsType)}Request=${AppPreferences.getInstance().getInt(NUM_REQUEST, 0)} " +
"${getAdEventMsg(adsType).lowercase()}_max_request=${AdConfigBean.adsConfigBean.numRequestLimit}" "${getAdEventMsg(adsType).lowercase()}_max_request=${AdConfigBean.adsConfigBean.numRequestLimit}"
adEvent?.adLimited(value) adEvent?.adLimited(value)
} }
return !(flag1 || flag2 || flag3) return !(isDisplayLimited || isClickLimited || isRequestLimited)
} }
private fun addNum(key: String) { private fun addNum(key: String) {
...@@ -151,27 +151,59 @@ object LimitUtils { ...@@ -151,27 +151,59 @@ object LimitUtils {
addNum(NUM_NATIVE_DISPLAY) addNum(NUM_NATIVE_DISPLAY)
} }
/**
* 开屏限制
*/
fun isIntervalOpenLimit(adEvent: AdEvent): Boolean {
val passTime = ((System.currentTimeMillis() - openLastShowTime) / 1000).toInt()
val interval = AdConfigBean.adsConfigBean.timeIntervalOpen
val flag = passTime < interval
Log.e(adEvent.TAG, "open isIntervalOpenLimit=$flag passTime=$passTime interval=$interval")
if (flag) {
adEvent.adShowError("ad in timeInterval")
}
return flag
}
/** /**
* 开屏和插页广告的显示间隔限制 * 插屏限制
*/ */
fun isIntervalLimited(adEvent: AdEvent?): Boolean { fun isIntervalInterLimit(adEvent: AdEvent): Boolean {
val flag = ((System.currentTimeMillis() - openInterLastShowTime) / 1000).toInt() < (AdConfigBean.adsConfigBean.timeInterval) val passTime = ((System.currentTimeMillis() - interLastShowTime) / 1000).toInt()
val interval = AdConfigBean.adsConfigBean.timeInterval
val flag = passTime < interval
Log.e(
adEvent.TAG,
"inter isIntervalInterLimit=$flag interLastShowTime=$interLastShowTime passTime=$passTime interval=$interval"
)
if (flag) { if (flag) {
adEvent?.adLimited("ad in timeInterval") adEvent.adShowError("ad in timeInterval")
} }
return flag return flag
} }
//开屏和插页上一次展示时间共用,避免开屏插页连弹 //开屏上次展示时间
var openInterLastShowTime = 0L var openLastShowTime = 0L
get() {
return AppPreferences.getInstance().getLong("openLastShowTime", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("openLastShowTime", value, true)
}
//插屏上次展示时间
var interLastShowTime = 0L
get() { get() {
return AppPreferences.getInstance().getLong("openInterLastShowTime", field) return AppPreferences.getInstance().getLong("interLastShowTime", field)
} }
set(value) { set(value) {
field = value field = value
AppPreferences.getInstance().put("openInterLastShowTime", value, true) AppPreferences.getInstance().put("interLastShowTime", value, true)
} }
/** /**
* 原生广告是否到达限制 * 原生广告是否到达限制
*/ */
...@@ -190,12 +222,19 @@ object LimitUtils { ...@@ -190,12 +222,19 @@ object LimitUtils {
AppPreferences.getInstance().put(NUM_NATIVE_DISPLAY, 0) AppPreferences.getInstance().put(NUM_NATIVE_DISPLAY, 0)
} }
val flag = isNativeLimited val flag = isNativeLimited
val todayNumber = AppPreferences.getInstance().getInt(NUM_NATIVE_DISPLAY, 0)
val max = AdConfigBean.adsConfigBean.numNativeDisplayLimit
LogEx.logDebug(adEvent?.TAG ?: "", "native todayNumber=$todayNumber max=$max ")
if (flag) { if (flag) {
val value = "current${getAdEventMsg(adsType)} " + val value = "current${getAdEventMsg(adsType)} " +
"show=${AppPreferences.getInstance().getInt(NUM_NATIVE_DISPLAY, 0)} " + "show=${todayNumber} " +
"${getAdEventMsg(adsType).lowercase()}_" + "max_show=${AdConfigBean.adsConfigBean.numNativeDisplayLimit}" "${getAdEventMsg(adsType).lowercase()}_" + "max_show=${max}"
adEvent?.adLimited(value) adEvent?.adLimited(value)
} }
return !flag return !flag
} }
}
\ No newline at end of file }
...@@ -13,6 +13,7 @@ import com.google.android.gms.ads.AdRequest ...@@ -13,6 +13,7 @@ import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdSize import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.LoadAdError import com.google.android.gms.ads.LoadAdError
import com.simplecleaner.app.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
import java.util.UUID import java.util.UUID
/** /**
...@@ -25,7 +26,7 @@ class AdBannerMgr { ...@@ -25,7 +26,7 @@ class AdBannerMgr {
fun show(parent: ViewGroup, collapsible: Boolean, adClose: (() -> Unit)? = null) { fun show(parent: ViewGroup, collapsible: Boolean, adClose: (() -> Unit)? = null) {
if (!AdConfigBean.adsConfigBean.adSwitch) { if (!AdConfigBean.adsConfigBean.isAdShow) {
return return
} }
val admobEvent = AdmobEvent("banner", "banner") val admobEvent = AdmobEvent("banner", "banner")
......
...@@ -19,6 +19,7 @@ import com.google.android.gms.ads.FullScreenContentCallback ...@@ -19,6 +19,7 @@ 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 com.simplecleaner.app.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
/** /**
...@@ -26,12 +27,12 @@ import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback ...@@ -26,12 +27,12 @@ import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
*/ */
class AdInterMgr { class AdInterMgr {
private val TAG = "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 private var loadingCallBack: ((flag: Boolean) -> Unit)? = null
fun show( fun show(
activity: Activity, activity: Activity,
...@@ -43,24 +44,22 @@ class AdInterMgr { ...@@ -43,24 +44,22 @@ class AdInterMgr {
return return
} }
val nowAdEvent = adEvent
//currentAdEvent!=null 表示有缓存广告,关联reqId //currentAdEvent!=null 表示有缓存广告,关联reqId
adState.currentAdEvent?.let { nowAdEvent.reqId = it.reqId } adState.currentAdEvent?.let { adEvent.reqId = it.reqId }
if (!nowAdEvent.isUnLimit) { if (!adEvent.isUnLimit) {
if (!LimitUtils.isAdShow(AdsType.INSERT, nowAdEvent)) { if (!LimitUtils.isAdShow(AdsType.INSERT, adEvent)) {
showCallBack?.failed(2) showCallBack?.failed(2)
return return
} }
if (LimitUtils.isIntervalLimited(nowAdEvent)) { if (LimitUtils.isIntervalInterLimit(adEvent)) {
showCallBack?.failed(3) showCallBack?.failed(3)
return return
} }
} }
val needLoad = !adState.adAvailable() val needLoad = adState.needLoad()
// adState.activityRef = WeakReference(activity)
this.showCallBack = showCallBack this.showCallBack = showCallBack
if (adState.adDialog == null) { if (adState.adDialog == null) {
...@@ -69,24 +68,29 @@ class AdInterMgr { ...@@ -69,24 +68,29 @@ class AdInterMgr {
adState.adDialog?.dismiss() adState.adDialog?.dismiss()
} }
nowAdEvent.adPrepareShow() adEvent.adPrepareShow()
LogEx.logDebug(adEvent.TAG, "needLoad=$needLoad") LogEx.logDebug(adEvent.TAG, "needLoad=$needLoad")
if (needLoad) { if (needLoad) {
if (!adState.loadingAd) { if (!adState.loadingAd) {
LogEx.logDebug(adEvent.TAG, "inter adState !loadingAd") LogEx.logDebug(adEvent.TAG, "inter adState !loadingAd")
loadAd(activity, nowAdEvent) { loadAd(activity, adEvent) {
showReadyAd(activity, nowAdEvent) if (it) {
showReadyAd(activity, adEvent)
} else {
showCallBack?.adFailed()
}
} }
} else { } else {
LogEx.logDebug(adEvent.TAG, "inter adState is loadingAd") LogEx.logDebug(adEvent.TAG, "inter adState is loadingAd")
loadingCallBack = { loadingCallBack = {
showReadyAd(activity, nowAdEvent) showReadyAd(activity, adEvent)
} }
} }
} else { } else {
LogEx.logDebug(adEvent.TAG, "inter ad ready") LogEx.logDebug(adEvent.TAG, "inter ad ready")
showReadyAd(activity, nowAdEvent) showReadyAd(activity, adEvent)
} }
} }
...@@ -94,13 +98,12 @@ class AdInterMgr { ...@@ -94,13 +98,12 @@ class AdInterMgr {
private fun showReadyAd(ac: Activity, adEvent: AdEvent) { private fun showReadyAd(ac: Activity, adEvent: AdEvent) {
// val ac = adState.activityRef?.get()
val admobEvent = (adEvent as AdmobEvent) val admobEvent = (adEvent as AdmobEvent)
val tag = adEvent.TAG val tag = adEvent.TAG
LogEx.logDebug(tag, "showReadyAd ac=$ac currentAd=${adState.currentAd}") LogEx.logDebug(tag, "inter showReadyAd ac=${ac.javaClass.simpleName} currentAd=${adState.currentAd}")
if (ac.isFinishing || ac.isDestroyed || adState.currentAd == null) { if (ac.isFinishing || ac.isDestroyed || adState.currentAd == null) {
LogEx.logDebug(tag, "showReadyAd ac=null isFinishing isDestroyed") LogEx.logDebug(tag, "inter showReadyAd ac=null isFinishing isDestroyed")
showCallBack?.failed() showCallBack?.failed()
adState.onAdDisplayFailed() adState.onAdDisplayFailed()
return return
...@@ -112,12 +115,12 @@ class AdInterMgr { ...@@ -112,12 +115,12 @@ class AdInterMgr {
override fun onAdShowedFullScreenContent() { override fun onAdShowedFullScreenContent() {
super.onAdShowedFullScreenContent() super.onAdShowedFullScreenContent()
admobEvent.showAd(responseInfo, ac) adState.onAdDisplayed(AdsType.INSERT)
adState.onAdDisplayed()
showCallBack?.show() showCallBack?.show()
LimitUtils.addDisplayNum() LimitUtils.addDisplayNum()
admobEvent.showAd(responseInfo, ac)
} }
override fun onAdFailedToShowFullScreenContent(adError: AdError) { override fun onAdFailedToShowFullScreenContent(adError: AdError) {
...@@ -133,10 +136,11 @@ class AdInterMgr { ...@@ -133,10 +136,11 @@ class AdInterMgr {
override fun onAdDismissedFullScreenContent() { override fun onAdDismissedFullScreenContent() {
super.onAdDismissedFullScreenContent() super.onAdDismissedFullScreenContent()
adState.onAdHidden() adState.onAdHidden(AdsType.INSERT)
showCallBack?.close() showCallBack?.close()
showCallBack = null showCallBack = null
loadAd(MyApplication.appContext, AdmobEvent("interAd", "preload")) loadAd(MyApplication.appContext, AdmobEvent("interAd", "preload"))
} }
...@@ -147,7 +151,6 @@ class AdInterMgr { ...@@ -147,7 +151,6 @@ class AdInterMgr {
LimitUtils.addClickNum() LimitUtils.addClickNum()
} }
} }
// val activity = adState.activityRef?.get()
if (AdConfigBean.adsConfigBean.showCountdown) { if (AdConfigBean.adsConfigBean.showCountdown) {
createUICountdownTimer(adState.adDialog) { createUICountdownTimer(adState.adDialog) {
show(ac) show(ac)
...@@ -158,10 +161,11 @@ class AdInterMgr { ...@@ -158,10 +161,11 @@ class AdInterMgr {
} }
} }
fun loadAd( fun loadAd(
context: Context, context: Context,
adEvent: AdEvent, adEvent: AdEvent,
loadCallBack: (() -> Unit)? = null loadCallBack: ((flag: Boolean) -> Unit)? = null
) { ) {
if (!adEvent.isUnLimit) { if (!adEvent.isUnLimit) {
if (!LimitUtils.isAdShow(AdsType.INSERT, adEvent)) { if (!LimitUtils.isAdShow(AdsType.INSERT, adEvent)) {
...@@ -173,14 +177,12 @@ class AdInterMgr { ...@@ -173,14 +177,12 @@ class AdInterMgr {
} }
//避免无效预加载 //避免无效预加载
if (adState.loadingAd && loadCallBack == null && loadingCallBack == null) { if (adState.loadingAd) {
//容错机制
adState.loadingAd = false
return return
} }
adState.loadingAd = true
adEvent.adPulStart() adEvent.adPulStart()
adState.loadStart(adEvent)
InterstitialAd.load( InterstitialAd.load(
context, GlobalConfig.ID_ADMOB_INTER, AdRequest.Builder().build(), context, GlobalConfig.ID_ADMOB_INTER, AdRequest.Builder().build(),
...@@ -188,10 +190,10 @@ class AdInterMgr { ...@@ -188,10 +190,10 @@ class AdInterMgr {
override fun onAdLoaded(ad: InterstitialAd) { override fun onAdLoaded(ad: InterstitialAd) {
val event = (adEvent as AdmobEvent) val event = (adEvent as AdmobEvent)
ad.onPaidEventListener = AdmobOnPaidEventListener(ad, adEvent.scope) ad.onPaidEventListener = AdmobOnPaidEventListener(ad, adEvent.scope)
adState.onAdLoaded(ad, adEvent) adState.onAdLoaded(ad)
loadCallBack?.invoke() loadCallBack?.invoke(true)
loadingCallBack?.invoke() loadingCallBack?.invoke(true)
loadingCallBack = null loadingCallBack = null
LimitUtils.addRequestNum() LimitUtils.addRequestNum()
...@@ -200,11 +202,14 @@ class AdInterMgr { ...@@ -200,11 +202,14 @@ class AdInterMgr {
override fun onAdFailedToLoad(loadAdError: LoadAdError) { override fun onAdFailedToLoad(loadAdError: LoadAdError) {
adState.onAdLoadFailed() adState.onAdLoadFailed()
if (loadCallBack != null) { if (loadCallBack != null) {
adState.onAdDisplayFailed() adState.onAdDisplayFailed()
} }
showCallBack?.adFailed() loadCallBack?.invoke(false)
showCallBack = null loadingCallBack?.invoke(false)
loadingCallBack = null
(adEvent as AdmobEvent).pullAd(loadAdError.responseInfo, loadAdError) (adEvent as AdmobEvent).pullAd(loadAdError.responseInfo, loadAdError)
} }
...@@ -214,4 +219,4 @@ class AdInterMgr { ...@@ -214,4 +219,4 @@ class AdInterMgr {
} }
} }
\ No newline at end of file
...@@ -13,6 +13,7 @@ import com.google.android.gms.ads.AdRequest ...@@ -13,6 +13,7 @@ import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.LoadAdError import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.nativead.NativeAd import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.nativead.NativeAdOptions import com.google.android.gms.ads.nativead.NativeAdOptions
import com.simplecleaner.app.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
import java.util.concurrent.ConcurrentLinkedDeque import java.util.concurrent.ConcurrentLinkedDeque
/** /**
...@@ -91,8 +92,6 @@ class AdNativeMgr { ...@@ -91,8 +92,6 @@ class AdNativeMgr {
nativeCallBack: ((Any?) -> Unit)? = null nativeCallBack: ((Any?) -> Unit)? = null
) { ) {
admobEvent.adPrepareShow()
if (!LimitUtils.isAdShow(AdsType.NATIVE, admobEvent)) { if (!LimitUtils.isAdShow(AdsType.NATIVE, admobEvent)) {
Log.e(TAG, "!isAdShow") Log.e(TAG, "!isAdShow")
cacheItems.clear() cacheItems.clear()
...@@ -102,6 +101,8 @@ class AdNativeMgr { ...@@ -102,6 +101,8 @@ class AdNativeMgr {
return return
} }
admobEvent.adPrepareShow()
Log.e(TAG, "adNative can show") Log.e(TAG, "adNative can show")
if (!adAvailable()) { if (!adAvailable()) {
...@@ -139,4 +140,5 @@ class AdNativeMgr { ...@@ -139,4 +140,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 }
...@@ -15,6 +15,7 @@ import com.google.android.gms.ads.AdRequest ...@@ -15,6 +15,7 @@ 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 com.simplecleaner.app.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
/** /**
...@@ -22,12 +23,11 @@ import com.google.android.gms.ads.appopen.AppOpenAd ...@@ -22,12 +23,11 @@ import com.google.android.gms.ads.appopen.AppOpenAd
*/ */
class AdOpenMgr { class AdOpenMgr {
private val TAG = "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 private var loadingCallBack: ((flag: Boolean) -> Unit)? = null
fun show( fun show(
activity: Activity, activity: Activity,
...@@ -38,65 +38,70 @@ class AdOpenMgr { ...@@ -38,65 +38,70 @@ class AdOpenMgr {
return return
} }
val nowAdEvent = adEvent adState.currentAdEvent?.let { adEvent.reqId = it.reqId }
adState.currentAdEvent?.let { nowAdEvent.reqId = it.reqId }
if (!nowAdEvent.isUnLimit) { if (!adEvent.isUnLimit) {
if (!LimitUtils.isAdShow(AdsType.OPEN, nowAdEvent)) { if (!LimitUtils.isAdShow(AdsType.OPEN, adEvent)) {
showCallBack?.failed() showCallBack?.failed()
return return
} }
if (LimitUtils.isIntervalLimited(nowAdEvent)) { if (LimitUtils.isIntervalOpenLimit(adEvent)) {
showCallBack?.failed() showCallBack?.failed()
return return
} }
} }
val needLoad = !adState.adAvailable() val needLoad = adState.needLoad()
this.showCallBack = showCallBack this.showCallBack = showCallBack
nowAdEvent.adPrepareShow() adEvent.adPrepareShow()
if (needLoad) { if (needLoad) {
if (!adState.loadingAd) { if (!adState.loadingAd) {
LogEx.logDebug(adEvent.TAG, "open adState !loadingAd") LogEx.logDebug(adEvent.TAG, "open adState !loadingAd")
loadAd(activity, adEvent) { loadAd(activity, adEvent) {
showReadyAd(activity) if (it) {
showReadyAd(activity, adEvent)
} else {
showCallBack?.adFailed()
}
} }
} else { } else {
LogEx.logDebug(adEvent.TAG, "open adState is loadingAd") LogEx.logDebug(adEvent.TAG, "open adState is loadingAd")
loadingCallBack = { loadingCallBack = {
showReadyAd(activity) if (it) {
showReadyAd(activity, adEvent)
} else {
showCallBack?.adFailed()
}
} }
} }
} else { } else {
LogEx.logDebug(adEvent.TAG, "open ad ready") LogEx.logDebug(adEvent.TAG, "open ad ready")
showReadyAd(activity) showReadyAd(activity, adEvent)
} }
} }
private fun showReadyAd(ac: Activity) { private fun showReadyAd(ac: Activity, adEvent: AdEvent) {
val admobEvent = (adEvent as AdmobEvent)
// val ac = adState.activityRef?.get()
if (ac.isFinishing || ac.isDestroyed || adState.currentAd == null) { if (ac.isFinishing || ac.isDestroyed || adState.currentAd == null) {
LogEx.logDebug(TAG, "showReadyAd ac=null isFinishing isDestroyed") LogEx.logDebug(adEvent.TAG, "open showReadyAd ac=null isFinishing isDestroyed")
return 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() {
adState.onAdDisplayed(AdsType.OPEN)
adEvent?.showAd(this@run.responseInfo, ac)
showCallBack?.show() showCallBack?.show()
adState.onAdDisplayed()
//计数 //计数
LimitUtils.addDisplayNum() LimitUtils.addDisplayNum()
admobEvent.showAd(this@run.responseInfo, ac)
} }
override fun onAdFailedToShowFullScreenContent(adError: AdError) { override fun onAdFailedToShowFullScreenContent(adError: AdError) {
...@@ -106,25 +111,24 @@ class AdOpenMgr { ...@@ -106,25 +111,24 @@ class AdOpenMgr {
showCallBack = null showCallBack = null
adState.onAdDisplayFailed() adState.onAdDisplayFailed()
adEvent?.adShowError(adError) admobEvent.adShowError(adError)
} }
override fun onAdDismissedFullScreenContent() { override fun onAdDismissedFullScreenContent() {
super.onAdDismissedFullScreenContent() super.onAdDismissedFullScreenContent()
adState.onAdHidden(AdsType.OPEN)
showCallBack?.close() showCallBack?.close()
showCallBack = null showCallBack = null
adState.onAdHidden()
//预加载,“Timeout for show call succeed.”预加载的广告大概率, //预加载,“Timeout for show call succeed.”预加载的广告大概率,
loadAd(MyApplication.appContext, AdmobEvent("openAd", "preload")) loadAd(MyApplication.appContext, AdmobEvent("openAd", "preload"))
} }
override fun onAdClicked() { override fun onAdClicked() {
adEvent?.clickAd(this@run.responseInfo) admobEvent.clickAd(this@run.responseInfo)
//计数 //计数
LimitUtils.addClickNum() LimitUtils.addClickNum()
} }
...@@ -136,7 +140,7 @@ class AdOpenMgr { ...@@ -136,7 +140,7 @@ class AdOpenMgr {
fun loadAd( fun loadAd(
context: Context, context: Context,
adEvent: AdEvent, adEvent: AdEvent,
loadCallBack: (() -> Unit)? = null loadCallBack: ((flag: Boolean) -> Unit)? = null
) { ) {
if (!adEvent.isUnLimit) { if (!adEvent.isUnLimit) {
...@@ -149,14 +153,12 @@ class AdOpenMgr { ...@@ -149,14 +153,12 @@ class AdOpenMgr {
} }
//避免无效预加载 //避免无效预加载
if (adState.loadingAd && loadCallBack == null && loadingCallBack == null) { if (adState.loadingAd) {
//容错机制
adState.loadingAd = false
return return
} }
adState.loadingAd = true
adEvent.adPulStart() adEvent.adPulStart()
adState.loadStart(adEvent)
AppOpenAd.load( AppOpenAd.load(
context, context,
...@@ -164,25 +166,31 @@ class AdOpenMgr { ...@@ -164,25 +166,31 @@ 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, adEvent) LogEx.logDebug(adEvent.TAG, "open onAdLoaded loadAd")
appOpenAd.onPaidEventListener = AdmobOnPaidEventListener(appOpenAd, adEvent.scope)
adState.onAdLoaded(appOpenAd)
loadCallBack?.invoke() loadCallBack?.invoke(true)
loadingCallBack?.invoke() loadingCallBack?.invoke(true)
loadingCallBack = null loadingCallBack = null
(adEvent as AdmobEvent).pullAd(appOpenAd.responseInfo)
appOpenAd.onPaidEventListener = AdmobOnPaidEventListener(appOpenAd, adEvent.scope)
LimitUtils.addRequestNum() LimitUtils.addRequestNum()
(adEvent as AdmobEvent).pullAd(appOpenAd.responseInfo)
} }
override fun onAdFailedToLoad(loadAdError: LoadAdError) { override fun onAdFailedToLoad(loadAdError: LoadAdError) {
showCallBack?.adFailed() LogEx.logDebug(adEvent.TAG, "open onAdFailedToLoad loadAd")
showCallBack = null
adState.onAdLoadFailed() adState.onAdLoadFailed()
loadCallBack?.invoke(false)
loadingCallBack?.invoke(false)
loadingCallBack = null
(adEvent as AdmobEvent).pullAd(loadAdError.responseInfo, loadAdError) (adEvent as AdmobEvent).pullAd(loadAdError.responseInfo, loadAdError)
} }
} }
) )
} }
} }
\ No newline at end of file
package com.simplecleaner.app.business.ads.applovin //package com.simplecleaner.app.business.ads.applovin
//
import androidx.annotation.LayoutRes //import androidx.annotation.LayoutRes
import com.applovin.mediation.MaxAd //import com.applovin.mediation.MaxAd
import com.applovin.mediation.MaxError //import com.applovin.mediation.MaxError
import com.applovin.mediation.nativeAds.MaxNativeAdListener //import com.applovin.mediation.nativeAds.MaxNativeAdListener
import com.applovin.mediation.nativeAds.MaxNativeAdLoader //import com.applovin.mediation.nativeAds.MaxNativeAdLoader
import com.applovin.mediation.nativeAds.MaxNativeAdView //import com.applovin.mediation.nativeAds.MaxNativeAdView
import com.simplecleaner.app.GlobalConfig //import com.simplecleaner.app.GlobalConfig
import com.simplecleaner.app.business.ads.AdsType //import com.simplecleaner.app.business.ads.AdsType
import com.simplecleaner.app.business.ads.LimitUtils //import com.simplecleaner.app.business.ads.LimitUtils
import com.simplecleaner.app.business.ads.NativeParentView //import com.simplecleaner.app.business.ads.NativeParentView
import com.simplecleaner.app.business.helper.EventUtils //import com.simplecleaner.app.business.helper.EventUtils
import org.json.JSONObject //import org.json.JSONObject
import java.util.UUID //import java.util.UUID
//
/** ///**
*原生广告加载显示管理类 // *原生广告加载显示管理类
*/ // */
class MaxNativeMgr { //class MaxNativeMgr {
//
/** // /**
* 上一次的缓存成功时间 // * 上一次的缓存成功时间
*/ // */
protected var lastTime: Long = 0 // protected var lastTime: Long = 0
//
/** // /**
* 原生广告 // * 原生广告
*/ // */
private var currentAd: MaxAd? = null // private var currentAd: MaxAd? = null
private var currentLoader: MaxNativeAdLoader? = null // private var currentLoader: MaxNativeAdLoader? = null
//
//
private fun loadAd( // private fun loadAd(
adMaxEvent: AdMaxEvent, // adMaxEvent: AdMaxEvent,
parent: NativeParentView, // parent: NativeParentView,
@LayoutRes layout: Int // @LayoutRes layout: Int
) { // ) {
//
if (!LimitUtils.isAdShow(AdsType.NATIVE, adMaxEvent)) return // if (!LimitUtils.isAdShow(AdsType.NATIVE, adMaxEvent)) return
//
val reqId = UUID.randomUUID().toString() // val reqId = UUID.randomUUID().toString()
val obj = JSONObject() // val obj = JSONObject()
obj.put("req_id", reqId) // obj.put("req_id", reqId)
obj.put("ad_type", "nativeAd") // obj.put("ad_type", "nativeAd")
//
val nativeAdLoader = MaxNativeAdLoader(GlobalConfig.ID_MAX_NATIVE, parent.context) // val nativeAdLoader = MaxNativeAdLoader(GlobalConfig.ID_MAX_NATIVE, parent.context)
//
nativeAdLoader.setNativeAdListener(object : MaxNativeAdListener() { // nativeAdLoader.setNativeAdListener(object : MaxNativeAdListener() {
//
override fun onNativeAdLoaded(nativeAdView: MaxNativeAdView?, ad: MaxAd) { // override fun onNativeAdLoaded(nativeAdView: MaxNativeAdView?, ad: MaxAd) {
currentLoader = nativeAdLoader // currentLoader = nativeAdLoader
currentAd = ad // currentAd = ad
lastTime = System.currentTimeMillis() // lastTime = System.currentTimeMillis()
adMaxEvent.pullAd(ad) // adMaxEvent.pullAd(ad)
nativeAdLoader.setRevenueListener(AdMaxEvent.EventOnPaidEventListener()) // nativeAdLoader.setRevenueListener(AdMaxEvent.EventOnPaidEventListener())
show(adMaxEvent, parent, layout) // show(adMaxEvent, parent, layout)
} // }
//
override fun onNativeAdLoadFailed(adUnitId: String, error: MaxError) { // override fun onNativeAdLoadFailed(adUnitId: String, error: MaxError) {
adMaxEvent.pullAd(null, error) // adMaxEvent.pullAd(null, error)
} // }
//
override fun onNativeAdClicked(ad: MaxAd) { // override fun onNativeAdClicked(ad: MaxAd) {
//
} // }
//
}) // })
nativeAdLoader.loadAd() // nativeAdLoader.loadAd()
} // }
//
fun show( // fun show(
adMaxEvent: AdMaxEvent, // adMaxEvent: AdMaxEvent,
parent: NativeParentView, // parent: NativeParentView,
@LayoutRes layout: Int, // @LayoutRes layout: Int,
nativeCallBack: ((Any?) -> Unit)? = null // nativeCallBack: ((Any?) -> Unit)? = null
) { // ) {
if (!LimitUtils.isAdShow(AdsType.NATIVE, adMaxEvent)) { // if (!LimitUtils.isAdShow(AdsType.NATIVE, adMaxEvent)) {
currentLoader = null // currentLoader = null
currentAd = null // currentAd = null
return // return
} // }
val nativeAd = currentAd // val nativeAd = currentAd
val nativeLoader = currentLoader // val nativeLoader = currentLoader
if ((nativeAd == null || nativeLoader == null).also { // if ((nativeAd == null || nativeLoader == null).also {
if (it) { // if (it) {
val obj2 = JSONObject() // val obj2 = JSONObject()
obj2.put("reason", "no_ad") // obj2.put("reason", "no_ad")
obj2.put("ad_unit", "nativeAd") // obj2.put("ad_unit", "nativeAd")
EventUtils.event("ad_show_error", ext = obj2) // EventUtils.event("ad_show_error", ext = obj2)
} // }
} || (!adAvailable()).also { // } || (!adAvailable()).also {
if (it) { // if (it) {
val obj2 = JSONObject() // val obj2 = JSONObject()
obj2.put("ad_unit", "nativeAd") // obj2.put("ad_unit", "nativeAd")
EventUtils.event("ad_expire", ext = obj2) // EventUtils.event("ad_expire", ext = obj2)
} // }
}) { // }) {
//缓存过期了就清空 // //缓存过期了就清空
currentLoader = null // currentLoader = null
currentAd = null // currentAd = null
loadAd(AdMaxEvent("nativeAd", "preload"), parent, layout) // loadAd(AdMaxEvent("nativeAd", "preload"), parent, layout)
return // return
} // }
val obj = JSONObject() // val obj = JSONObject()
obj.put("ad_unit", "nativeAd") // obj.put("ad_unit", "nativeAd")
EventUtils.event("ad_prepare_show", ext = obj) // EventUtils.event("ad_prepare_show", ext = obj)
parent.setNativeAd(nativeLoader!!, nativeAd!!, layout) // parent.setNativeAd(nativeLoader!!, nativeAd!!, layout)
nativeCallBack?.invoke(nativeAd) // nativeCallBack?.invoke(nativeAd)
} // }
//
private fun adAvailable(): Boolean { // private fun adAvailable(): Boolean {
return ((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < 30 // return ((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < 30
} // }
} //}
\ No newline at end of file \ No newline at end of file
...@@ -12,8 +12,10 @@ import com.simplecleaner.app.bean.FeatureBean.Companion.SCREENSHOT_CLEAN ...@@ -12,8 +12,10 @@ import com.simplecleaner.app.bean.FeatureBean.Companion.SCREENSHOT_CLEAN
import com.simplecleaner.app.bean.FeatureBean.Companion.SIMILAR_PHOTOS import com.simplecleaner.app.bean.FeatureBean.Companion.SIMILAR_PHOTOS
import com.simplecleaner.app.bean.FeatureBean.Companion.UNINSTALL_APP import com.simplecleaner.app.bean.FeatureBean.Companion.UNINSTALL_APP
import com.simplecleaner.app.business.ads.AdsMgr import com.simplecleaner.app.business.ads.AdsMgr
import com.simplecleaner.app.business.ads.AdsShowCallBack
import com.simplecleaner.app.databinding.ActivityGuideExperienceBinding import com.simplecleaner.app.databinding.ActivityGuideExperienceBinding
import com.simplecleaner.app.ui.dialog.StoragePermissionDialog import com.simplecleaner.app.ui.dialog.StoragePermissionDialog
import com.simplecleaner.app.ui.main.MainActivity
import com.simplecleaner.app.utils.PermissionUtils.requestStoragePermission import com.simplecleaner.app.utils.PermissionUtils.requestStoragePermission
class GuideExperienceActivity : BaseActivity<ActivityGuideExperienceBinding>( class GuideExperienceActivity : BaseActivity<ActivityGuideExperienceBinding>(
...@@ -29,7 +31,11 @@ class GuideExperienceActivity : BaseActivity<ActivityGuideExperienceBinding>( ...@@ -29,7 +31,11 @@ class GuideExperienceActivity : BaseActivity<ActivityGuideExperienceBinding>(
} }
override fun handleBackCallBack() { override fun handleBackCallBack() {
AdsMgr.showInsert(this, false, object : AdsShowCallBack() {
override fun next() {
goToAc(MainActivity::class.java)
}
})
} }
override fun initListener() { override fun initListener() {
......
//package com.base.appzxhy.ui.malware
//
//import com.base.appzxhy.MyApplication
//import com.trustlook.sdk.cloudscan.CloudScanClient
//import com.trustlook.sdk.data.Region
//
///**
// *Create by SleepDog on 2025-01-24
// */
//object CloudScan {
// val scanClient by lazy(LazyThreadSafetyMode.NONE) {
// CloudScanClient.Builder(MyApplication.appContext)
// // 设置服务地区,
//// 海外地区设置:Region.INTL,百度用户设置:Region.BAIDU
// .setRegion(Region.INTL)
// // 设置连接超时时长,单位为毫秒
// .setConnectionTimeout(30000)
// //设置传输超时时长,单位为毫秒
// .setSocketTimeout(30000)
// .build()
// }
//}
\ No newline at end of file
//package com.base.appzxhy.ui.malware
//
//import android.app.Activity
//import android.view.LayoutInflater
//import androidx.appcompat.app.AlertDialog
//import androidx.constraintlayout.widget.ConstraintLayout
//import com.base.appzxhy.R
//import com.base.appzxhy.business.ads.AdsMgr
//import com.base.appzxhy.databinding.DialogErrBinding
//
//class ErrorScanDialog(
// val activity: Activity
//) {
// val dialog = AlertDialog.Builder(activity).create()
// val binding = DialogErrBinding.inflate(LayoutInflater.from(activity))
//
// var action: (() -> Unit)? = null
//
// fun showDialog() {
// dialog.setView(binding.root)
// dialog.setCanceledOnTouchOutside(false)
// dialog.show()
//
// val params = dialog.window?.attributes
//// params?.width = ConstraintLayout.LayoutParams.MATCH_PARENT
// params?.width = activity.resources.getDimensionPixelSize(R.dimen.dp_295)
// params?.height = ConstraintLayout.LayoutParams.WRAP_CONTENT
//// params?.gravity = Gravity.BOTTOM
// dialog.window?.attributes = params
// dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
//
// AdsMgr.showNative(binding.flAd, R.layout.layout_admob_native_custom)
// binding.tvSure.setOnClickListener {
// dialog.dismiss()
// action?.invoke()
// }
// }
//}
\ No newline at end of file
//package com.base.appzxhy.ui.malware
//
//import android.app.Activity
//import android.view.LayoutInflater
//import androidx.appcompat.app.AlertDialog
//import com.base.appzxhy.databinding.DialogMalwareTipBinding
//import com.base.appzxhy.utils.AppPreferences
//
////是否已经同意
//var malwareTipAgree = false
// get() {
// return AppPreferences.getInstance().getBoolean("malwareTipAgree", field)
// }
// set(value) {
// field = value
// AppPreferences.getInstance().put("malwareTipAgree", value, true)
// }
//
//class MalwareDialog(
// val activity: Activity
//) {
//
// val dialog = AlertDialog.Builder(activity).create()
// val binding = DialogMalwareTipBinding.inflate(LayoutInflater.from(activity))
//
// var action: ((flag: Boolean) -> Unit)? = null
//
// fun showDialog() {
//
// if (malwareTipAgree) {
// action?.invoke(true)
// return
// }
//
// dialog.setView(binding.root)
// dialog.setCanceledOnTouchOutside(false)
// dialog.show()
//
// val params = dialog.window?.attributes
//// params?.width = ConstraintLayout.LayoutParams.MATCH_PARENT
//// params?.width = activity.resources.getDimensionPixelSize(R.dimen.dp_295)
//// params?.height = ConstraintLayout.LayoutParams.WRAP_CONTENT
//// params?.gravity = Gravity.BOTTOM
// dialog.window?.attributes = params
// dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
//
// var flag = false
//
// binding.tvCancel.setOnClickListener {
// dialog.dismiss()
// }
// binding.tvSure.setOnClickListener {
// dialog.dismiss()
// flag = true
// malwareTipAgree = true
// action?.invoke(true)
// }
//
// dialog.setOnDismissListener {
// action?.invoke(flag)
// }
// }
//}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ExtraTranslation"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="which_type_do_you_want_to_clean">Welchen Typ möchten Sie bereinigen?</string> <string name="which_type_do_you_want_to_clean">Welchen Typ möchten Sie bereinigen?</string>
<string name="consent"> <string name="consent">Während der Nutzung dieser App benötigen wir folgende Informationen: Handymodell, Hersteller, Android-Version, App-Versionsnummer, App-Versionsname, Paketname, Google-Werbe-ID, Zeitzone, Handy-Fotoalbum, leere Ordner, APK-Dateien, temporäre Dateien, Protokolldateien, Akkustand, Standby-Zeit, Akkutemperatur, Akkuspannung, Akkutechnologie, Akkukapazität, Akkustrom, durchschnittlicher Akkustrom. Wir behandeln Ihre Daten streng nach geltenden Gesetzen. Alle gesammelten Daten werden zweckgebunden verwendet, um App-Funktionen zu gewährleisten und Services zu verbessern. Wir ergreifen alle notwendigen Maßnahmen zum Schutz Ihrer Daten. Ihr Datenschutz hat für uns höchste Priorität.</string>
Während der Nutzung dieser App benötigen wir folgende Informationen: Handymodell, Hersteller, Android-Version, App-Versionsnummer, App-Versionsname, Paketname, Google-Werbe-ID, Zeitzone, Handy-Fotoalbum, leere Ordner, APK-Dateien, temporäre Dateien, Protokolldateien, Akkustand, Standby-Zeit, Akkutemperatur, Akkuspannung, Akkutechnologie, Akkukapazität, Akkustrom, durchschnittlicher Akkustrom.
Wir behandeln Ihre Daten streng nach geltenden Gesetzen. Alle gesammelten Daten werden zweckgebunden verwendet, um App-Funktionen zu gewährleisten und Services zu verbessern. Wir ergreifen alle notwendigen Maßnahmen zum Schutz Ihrer Daten. Ihr Datenschutz hat für uns höchste Priorität.
</string>
<string name="junk_clean">Junk-Bereinigung</string> <string name="junk_clean">Junk-Bereinigung</string>
<string name="battery_info">Akkustatus</string> <string name="battery_info">Akkustatus</string>
<string name="screenshot_clean">Screenshot-Bereinigung</string> <string name="screenshot_clean">Screenshot-Bereinigung</string>
...@@ -15,7 +10,6 @@ ...@@ -15,7 +10,6 @@
<string name="similar_photos">Doppelte Fotos</string> <string name="similar_photos">Doppelte Fotos</string>
<string name="home">Start</string> <string name="home">Start</string>
<string name="settings">Einstellungen</string> <string name="settings">Einstellungen</string>
<string name="battery_status">Akkustatus</string> <string name="battery_status">Akkustatus</string>
<string name="temperature">Temperatur</string> <string name="temperature">Temperatur</string>
<string name="voltage">Spannung</string> <string name="voltage">Spannung</string>
...@@ -24,11 +18,9 @@ ...@@ -24,11 +18,9 @@
<string name="normal">Normal</string> <string name="normal">Normal</string>
<string name="battery_type">Akkutyp</string> <string name="battery_type">Akkutyp</string>
<string name="battery_capacity">Akkukapazität</string> <string name="battery_capacity">Akkukapazität</string>
<string name="please_wait">Bitte warten</string> <string name="please_wait">Bitte warten</string>
<string name="power">Ladestand</string> <string name="power">Ladestand</string>
<string name="charging">Wird geladen</string> <string name="charging">Wird geladen</string>
<string name="found">Gefunden</string>
<string name="clean_tips">Bereinigung löscht keine persönlichen Daten</string> <string name="clean_tips">Bereinigung löscht keine persönlichen Daten</string>
<string name="clean">Bereinigen</string> <string name="clean">Bereinigen</string>
<string name="go_it">Verstanden</string> <string name="go_it">Verstanden</string>
...@@ -46,7 +38,6 @@ ...@@ -46,7 +38,6 @@
<string name="image">Bild</string> <string name="image">Bild</string>
<string name="apk">APK</string> <string name="apk">APK</string>
<string name="other_types">Andere Typen</string> <string name="other_types">Andere Typen</string>
<string name="all_time">Gesamter Zeitraum</string> <string name="all_time">Gesamter Zeitraum</string>
<string name="week_1">1 Woche</string> <string name="week_1">1 Woche</string>
<string name="month_1">1 Monat</string> <string name="month_1">1 Monat</string>
...@@ -74,19 +65,9 @@ ...@@ -74,19 +65,9 @@
<string name="version">Version</string> <string name="version">Version</string>
<string name="thank_you_for_using_app">Danke für die Nutzung von %s!</string> <string name="thank_you_for_using_app">Danke für die Nutzung von %s!</string>
<string name="submit">ABSENDEN</string> <string name="submit">ABSENDEN</string>
<string name="guide_tip_1">Junk entfernen, Geschwindigkeit steigern. Mit einem Klick Speicher freigeben.</string>
<string name="guide_tip_1"> <string name="guide_tip_2">Fotos, Videos und Audiodateien bereinigen für mehr Platz und Ordnung.</string>
Junk entfernen, Geschwindigkeit steigern. Mit einem Klick Speicher freigeben. <string name="guide_tip_3">Leistungsstarke Scanfunktion für umfassenden Schutz. Sicherheit für Ihr Gerät.</string>
</string>
<string name="guide_tip_2">
Fotos, Videos und Audiodateien bereinigen für mehr Platz und Ordnung.
</string>
<string name="guide_tip_3">
Leistungsstarke Scanfunktion für umfassenden Schutz. Sicherheit für Ihr Gerät.
</string>
<string name="next">Weiter</string> <string name="next">Weiter</string>
<string name="sure">Bestätigen</string> <string name="sure">Bestätigen</string>
<string name="exit_junk_clean">Junk-Bereinigung beenden?</string> <string name="exit_junk_clean">Junk-Bereinigung beenden?</string>
...@@ -110,10 +91,8 @@ ...@@ -110,10 +91,8 @@
<string name="powered_by_trustlook">Powered by Trustlook</string> <string name="powered_by_trustlook">Powered by Trustlook</string>
<string name="malware_recommended">Für genauere Ergebnisse Internetverbindung empfohlen</string> <string name="malware_recommended">Für genauere Ergebnisse Internetverbindung empfohlen</string>
<string name="notification_tips">Aktivieren Sie Benachrichtigungen für wichtige Hinweise.</string> <string name="notification_tips">Aktivieren Sie Benachrichtigungen für wichtige Hinweise.</string>
<string name="don_t_miss_important_tips">Wichtige Hinweise nicht verpassen</string>
<string name="select_a_language">Sprache wählen</string> <string name="select_a_language">Sprache wählen</string>
<string name="get_started">Loslegen</string> <string name="get_started">Loslegen</string>
<string name="loading">Wird geladen...</string>
<string name="battery">Akku</string> <string name="battery">Akku</string>
<string name="estimated_battery">Voraussichtliche Akkulaufzeit</string> <string name="estimated_battery">Voraussichtliche Akkulaufzeit</string>
<string name="electric_current">Stromstärke</string> <string name="electric_current">Stromstärke</string>
...@@ -126,4 +105,39 @@ ...@@ -126,4 +105,39 @@
<string name="notify_screenshot">Screenshots bereinigen für mehr Platz!</string> <string name="notify_screenshot">Screenshots bereinigen für mehr Platz!</string>
<string name="notify_photo_compression">Fotos komprimieren für mehr Speicherplatz!</string> <string name="notify_photo_compression">Fotos komprimieren für mehr Speicherplatz!</string>
<string name="ads_are_about_to_be_shown_s">Werbung wird in (%1$s Sek.) angezeigt</string> <string name="ads_are_about_to_be_shown_s">Werbung wird in (%1$s Sek.) angezeigt</string>
<string name="by_continuing_">Durch Fortfahren stimmen Sie den\u0020</string>
<string name="thank_you_very_much">Vielen Dank, dass Sie sich die Zeit genommen haben, uns zu bewerten.</string>
<string name="view">Anzeigen</string>
<string name="content_not_found">Inhalt nicht gefunden</string>
<string name="uninstall_app">App deinstallieren</string>
<string name="ok">OK</string>
<string name="size">Größe</string>
<string name="install_time">Installationszeit</string>
<string name="app_function_experience_tip">%s ist ein fortschrittlicher Reiniger für Android-Geräte, um Mobiltelefone zu bereinigen. Die Reinigungs-App kann leere Dateien, Protokolldateien, veraltete APKs, temporäre Dateien, ähnliche Bilder und große Dateien bereinigen. Sie kann auch Batterieinformationen anzeigen, Apps deinstallieren und Bilder komprimieren.</string>
<string name="experience_it_immediately">Sofort ausprobieren</string>
<string name="screenshot">Screenshot</string>
<string name="exit_uninstall_app_content">App-Deinstallation beenden? Ungenutzte Anwendungen können Speicherplatz belegen.</string>
<string name="notify_uninstall_app">Entfernen Sie ungenutzte Apps, um Speicherplatz freizugeben.</string>
<string name="quick_clean">Schnellbereinigung</string>
<string name="scan_completed">Scan abgeschlossen</string>
<string name="turn_on_notification">Benachrichtigung aktivieren</string>
<string name="redundant_files_found">Überflüssige Dateien gefunden</string>
<string name="found_f">Gefunden: %1$s</string>
<string name="involve_ad">Dieser Vorgang kann Werbung enthalten.</string>
<string name="consent_required">Zustimmung erforderlich</string>
<string name="start">Start</string>
<string name="privacy_policy">Datenschutzrichtlinie</string>
<string name="photo">Foto</string>
<string name="audio">Audio</string>
<string name="document">Dokument</string>
<string name="video">Video</string>
<string name="continue_">Fortfahren</string>
<string name="open_settings">Einstellungen öffnen</string>
<string name="storage_permission_title">Speicherberechtigungen benötigt</string>
<string name="storage_permission_content">Zulassen, dass %s auf die Berechtigung „Zugriff auf alle Dateien“ zugreift, um Dateien auf Ihrem Gerät zu verwalten?</string>
<string name="large_file">Große Dateien</string>
<string name="exit_uninstall_app">App-Deinstallation beenden</string>
</resources> </resources>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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