|
@@ -0,0 +1,333 @@
|
|
|
+package com.composition.android.ad.applovinmax.load
|
|
|
+
|
|
|
+import android.app.Activity
|
|
|
+import android.content.Context
|
|
|
+import android.view.View
|
|
|
+import android.view.ViewGroup
|
|
|
+import com.applovin.mediation.*
|
|
|
+import com.applovin.mediation.ads.MaxAdView
|
|
|
+import com.applovin.mediation.ads.MaxAppOpenAd
|
|
|
+import com.applovin.mediation.ads.MaxInterstitialAd
|
|
|
+import com.applovin.mediation.ads.MaxRewardedAd
|
|
|
+import com.applovin.mediation.nativeAds.MaxNativeAdLoader
|
|
|
+import com.applovin.mediation.nativeAds.MaxNativeAdView
|
|
|
+import com.applovin.sdk.AppLovinSdk
|
|
|
+import com.composition.android.ad.applovinmax.load.request.*
|
|
|
+import com.composition.android.ad.applovinmax.load.view.AppLovinMaxBannerView
|
|
|
+import com.composition.android.ad.applovinmax.load.view.AppLovinMaxNativeTemplateView
|
|
|
+import com.composition.android.lib.ad.AdManager
|
|
|
+import com.composition.android.lib.ad.basic.*
|
|
|
+import com.composition.android.lib.ad.bean.AdUnitBean
|
|
|
+import com.composition.android.lib.ad.interfaces.AdListener
|
|
|
+import com.composition.android.lib.ad.interfaces.AdLoader
|
|
|
+import com.composition.android.lib.ad.util.adLog
|
|
|
+import com.composition.android.lib.ad.util.adLogE
|
|
|
+import com.composition.android.lib.ad.util.parentRemove
|
|
|
+
|
|
|
+/**
|
|
|
+ * @classname:
|
|
|
+ * @author: LiuXiaoLong
|
|
|
+ * @date: 2022/11/11
|
|
|
+ * description:AppLovinMax广告加载器
|
|
|
+ */
|
|
|
+class AppLovinMaxLoader : AdLoader {
|
|
|
+ override val advertisers: Advertisers
|
|
|
+ get() = Advertisers.AppLovinMax
|
|
|
+
|
|
|
+
|
|
|
+ suspend fun loadNativeAd(context: Context, adUnitBean: AdUnitBean, nativeAdViewHolder: NativeAdViewHolder): AdResult{
|
|
|
+ return loadByStrategy(context, adUnitBean, AppLovinMaxNativeRequestImpl(nativeAdViewHolder))
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun load(context: Context, adUnitBean: AdUnitBean): AdResult {
|
|
|
+
|
|
|
+ val requestImpl = when (adUnitBean.getAdType()) {
|
|
|
+ AdType.APP_OPEN -> AppLovinMaxAppOpenRequestImpl()
|
|
|
+ AdType.INTERSTITIAL -> AppLovinMaxInterstitialRequestImpl()
|
|
|
+ AdType.BANNER -> AppLovinMaxBannerRequestImpl()
|
|
|
+ AdType.NATIVE_TEMPLATE -> AppLovinMaxNativeTemplateRequestImpl()
|
|
|
+ AdType.REWARDED_VIDEO -> AppLovinMaxRewardRequestImpl()
|
|
|
+ else -> null
|
|
|
+ }
|
|
|
+ return loadByStrategy(context, adUnitBean, requestImpl)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取横幅Banner广告View
|
|
|
+ * @param context 上下文
|
|
|
+ * @param adResult 请求成功的结果
|
|
|
+ * @param viewHolder 横幅广告需要的配置:activity、adListener
|
|
|
+ */
|
|
|
+ override fun getBannerView(context: Context, adResult: AdResult.Success, viewHolder: BannerAdViewHolder): BasicAdView<*>? {
|
|
|
+ return if (adResult.adObject is MaxAdView) {
|
|
|
+ AdManager.instance.globalListener?.invoke(adResult.adBean)
|
|
|
+ AppLovinMaxBannerView(context).apply {
|
|
|
+ setBannerAdViewHolder(viewHolder)
|
|
|
+ render(adResult)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ null
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取原生、原生模板广告View
|
|
|
+ * @param context 上下文
|
|
|
+ * @param adResult 请求成功的结果
|
|
|
+ * @param viewHolder 原生广告需要的配置
|
|
|
+ * @return View?
|
|
|
+ */
|
|
|
+ override fun getNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder): View? {
|
|
|
+ return if (adResult.adObject != null) {
|
|
|
+ AdManager.instance.globalListener?.invoke(adResult.adBean)
|
|
|
+ when (adResult.adBean.getAdType()) {
|
|
|
+ AdType.NATIVE_TEMPLATE -> {
|
|
|
+ AppLovinMaxNativeTemplateView(context).apply {
|
|
|
+ setViewHolder(viewHolder)
|
|
|
+ render(adResult)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else -> {
|
|
|
+ null
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ null
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据广告adResult.adObject类型,销毁广告
|
|
|
+ * @param 广告实例
|
|
|
+ *
|
|
|
+ */
|
|
|
+ override fun destroyAd(adResult: AdResult) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (adResult is AdResult.Success) {
|
|
|
+ when(val ad = adResult.adObject) {
|
|
|
+ is Triple<*, *, *>-> {
|
|
|
+ val triple = adResult.adObject as? Triple<MaxNativeAdLoader, MaxNativeAdView?, MaxAd?>
|
|
|
+ triple?.first?.destroy(triple.third)
|
|
|
+ }
|
|
|
+ is MaxAdView -> ad.destroy()
|
|
|
+ is MaxInterstitialAd -> ad.destroy()
|
|
|
+ is MaxRewardedAd -> ad.destroy()
|
|
|
+ is MaxAppOpenAd -> ad.destroy()
|
|
|
+ else -> {}
|
|
|
+ }
|
|
|
+ adResult.adObject = null
|
|
|
+ }
|
|
|
+ adLog(msg = "APPLovin广告-${adResult.adBean.getAdType().name}-销毁广告对象完成")
|
|
|
+ }catch (e : Exception){
|
|
|
+ adLog(msg = "APPLovin广告-销毁广告出现了问题\n${e.message}")
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充原生广告
|
|
|
+ *
|
|
|
+ */
|
|
|
+ override fun populateNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder, advertisersContainerView: ViewGroup) {
|
|
|
+ when(adResult.adBean.getAdType()){
|
|
|
+ AdType.NATIVE_TEMPLATE ->{
|
|
|
+ val triple = adResult.adObject as? Triple<MaxNativeAdLoader, MaxNativeAdView?, MaxAd?>
|
|
|
+ //这里主要是对广告View设置监听
|
|
|
+ AppLovinMaxNativeTemplateView.populateNativeTemplateAdView(context, adResult, viewHolder)
|
|
|
+ //父布局先移除
|
|
|
+ triple?.second?.parentRemove()
|
|
|
+ //移除View
|
|
|
+ advertisersContainerView.removeAllViews()
|
|
|
+ advertisersContainerView.addView(triple?.second)
|
|
|
+ }
|
|
|
+ else->{
|
|
|
+ adLogE(tag = AdManager.TAG, "AppLovinMax组件暂未接入原生广告,不支持填充")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun showInterstitialAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
|
|
|
+ if (adResult.adObject is MaxInterstitialAd) {
|
|
|
+ val maxInterstitialAd = adResult.adObject as? MaxInterstitialAd
|
|
|
+ if (maxInterstitialAd?.isReady == true) {
|
|
|
+ maxInterstitialAd.setListener(object : MaxAdListener{
|
|
|
+ override fun onAdLoaded(ad: MaxAd?) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdDisplayed(ad: MaxAd?) {
|
|
|
+ AdManager.instance.globalListener?.invoke(adResult.adBean)
|
|
|
+ adListener.onAdShow(adResult.adBean)
|
|
|
+ adLog(msg = "AppLovinMax广告-插屏-显示")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdHidden(ad: MaxAd?) {
|
|
|
+ adListener.onAdClose()
|
|
|
+ adLog(msg = "AppLovinMax广告-插屏-关闭")
|
|
|
+ destroyAd(adResult)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdClicked(ad: MaxAd?) {
|
|
|
+ adListener.onAdClick()
|
|
|
+ adLog(msg = "AppLovinMax广告-插屏-点击")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdLoadFailed(adUnitId: String?, error: MaxError?) {
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdDisplayFailed(ad: MaxAd?, error: MaxError?) {
|
|
|
+ adListener.onAdShowFail("AppLovinMax广告-插屏-显示失败-${error?.message}")
|
|
|
+ adLog(msg = "AppLovinMax广告-插屏-显示失败")
|
|
|
+ }
|
|
|
+ })
|
|
|
+ maxInterstitialAd.showAd()
|
|
|
+ }else{
|
|
|
+ adLog(msg = "AppLovinMax广告-插屏-显示失败-isReady:false")
|
|
|
+ adListener.onAdShowFail("AppLovinMax广告-插屏-显示失败-isReady:false")
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ adLog(
|
|
|
+ msg = "AppLovinMax广告-插屏-错误\n" +
|
|
|
+ "类型错误,当前为:${adResult.adObject?.javaClass?.simpleName}, 应该为:MaxInterstitialAd"
|
|
|
+ )
|
|
|
+ adListener.onAdShowFail("类型错误,当前为:${adResult.adObject?.javaClass?.simpleName}, 应该为:MaxInterstitialAd")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun showRewardedAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
|
|
|
+ if (adResult.adObject is MaxRewardedAd) {
|
|
|
+ val maxRewardedAd = adResult.adObject as? MaxRewardedAd
|
|
|
+ if (maxRewardedAd?.isReady == true) {
|
|
|
+ maxRewardedAd.setListener(object : MaxRewardedAdListener{
|
|
|
+ override fun onAdLoaded(ad: MaxAd?) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdDisplayed(ad: MaxAd?) {
|
|
|
+ AdManager.instance.globalListener?.invoke(adResult.adBean)
|
|
|
+ adListener.onAdShow(adResult.adBean)
|
|
|
+ adLog(msg = "AppLovinMax广告-激励-显示")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdHidden(ad: MaxAd?) {
|
|
|
+ adListener.onAdClose()
|
|
|
+ adLog(msg = "AppLovinMax广告-激励-关闭")
|
|
|
+ destroyAd(adResult)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdClicked(ad: MaxAd?) {
|
|
|
+ adListener.onAdClick()
|
|
|
+ adLog(msg = "AppLovinMax广告-激励-点击")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdLoadFailed(adUnitId: String?, error: MaxError?) {
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdDisplayFailed(ad: MaxAd?, error: MaxError?) {
|
|
|
+ adListener.onAdShowFail("AppLovinMax广告-激励-显示失败-${error?.message}")
|
|
|
+ adLog(msg = "AppLovinMax广告-激励-显示失败")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onUserRewarded(ad: MaxAd?, reward: MaxReward?) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewardedVideoStarted(ad: MaxAd?) {
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewardedVideoCompleted(ad: MaxAd?) {
|
|
|
+ }
|
|
|
+ })
|
|
|
+ maxRewardedAd.showAd()
|
|
|
+ }else{
|
|
|
+ adLog(msg = "AppLovinMax广告-激励-显示失败-isReady:false")
|
|
|
+ adListener.onAdShowFail("AppLovinMax广告-激励-显示失败-isReady:false")
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ adLog(
|
|
|
+ msg = "AppLovinMax广告-激励-错误\n" +
|
|
|
+ "类型错误,当前为:${adResult.adObject?.javaClass?.simpleName}, 应该为:MaxRewardedAd"
|
|
|
+ )
|
|
|
+ adListener.onAdShowFail("类型错误,当前为:${adResult.adObject?.javaClass?.simpleName}, 应该为:MaxRewardedAd")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun showRewardedInterstitialAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
|
|
|
+ adLogE(tag = AdManager.TAG, msg = "AppLovinMax广告-插屏激励-不支持此广告格式")
|
|
|
+ adListener.onAdShowFail("AppLovinMax广告-插屏激励-不支持此广告格式")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun showSplashAd(activity: Activity, splashViewGroup: ViewGroup?, adResult: AdResult.Success, adListener: AdListener) {
|
|
|
+ if (adResult.adObject is MaxAppOpenAd) {
|
|
|
+
|
|
|
+ val maxAppOpenAd = adResult.adObject as MaxAppOpenAd
|
|
|
+
|
|
|
+ if (maxAppOpenAd.isReady && AppLovinSdk.getInstance(activity).isInitialized) {
|
|
|
+ maxAppOpenAd.setListener(object : MaxAdListener {
|
|
|
+ override fun onAdLoaded(ad: MaxAd?) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdDisplayed(ad: MaxAd?) {
|
|
|
+ adListener.onAdShow(adResult.adBean)
|
|
|
+ AdManager.instance.globalListener?.invoke(adResult.adBean)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdHidden(ad: MaxAd?) {
|
|
|
+ adLog(msg = "穿山甲广告-开屏-关闭")
|
|
|
+ adListener.onAdClose()
|
|
|
+ destroyAd(adResult)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdClicked(ad: MaxAd?) {
|
|
|
+ adLog(msg = "AppLovinMax广告-开屏-点击")
|
|
|
+ adListener.onAdClick()
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdLoadFailed(adUnitId: String?, error: MaxError?) {
|
|
|
+ adLog(msg = "AppLovinMax广告-开屏-点击")
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onAdDisplayFailed(ad: MaxAd?, error: MaxError?) {
|
|
|
+ adLog(msg = "AppLovinMax广告-开屏-显示失败")
|
|
|
+ adListener.onAdShowFail("AppLovinMax广告-开屏-显示失败")
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+ maxAppOpenAd.showAd()
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+ adLog(
|
|
|
+ msg = "AppLovinMax广告-开屏-异常\n" +
|
|
|
+ "类型错误,当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为:MaxAppOpenAd"
|
|
|
+ )
|
|
|
+ adListener.onAdShowFail("类型错误,当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为:MaxAppOpenAd")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示全屏类型广告
|
|
|
+ * @param activity 用于展示广告的上下文
|
|
|
+ * @param adResult 请求成功的广告实例
|
|
|
+ * @param adListener 广告监听
|
|
|
+ */
|
|
|
+ override fun showFullScreenAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
|
|
|
+ when(adResult.adBean.getAdType()){
|
|
|
+ AdType.INTERSTITIAL -> showInterstitialAd(activity, adResult, adListener)
|
|
|
+ AdType.REWARDED_INTERSTITIAL -> showRewardedInterstitialAd(activity, adResult, adListener)
|
|
|
+ AdType.REWARDED_VIDEO -> showRewardedAd(activity, adResult, adListener)
|
|
|
+ else -> {
|
|
|
+ adListener.onAdShowFail("AppLovinMax, 传入的AdType为:${adResult.adBean.getAdType()}, 非全屏类型广告")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|