聚合tradplus平台。

This commit is contained in:
ocean 2025-12-16 17:50:42 +08:00
parent 544fe96be5
commit 1cfbfb32de
20 changed files with 342 additions and 624 deletions

View File

@ -36,8 +36,8 @@ android {
applicationId = "com.all.pdfreader.pdf.reader"
minSdk = 24
targetSdk = 36
versionCode = 6
versionName = "1.0.6"
versionCode = 7
versionName = "1.0.7"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
setProperty("archivesBaseName", "${getAppNameFromStringsFile()}-$versionName($versionCode)-${timestamp}")
@ -119,10 +119,54 @@ dependencies {
implementation("com.google.firebase:firebase-crashlytics-ndk")
implementation("com.google.firebase:firebase-analytics")
// google ads
implementation("com.google.android.gms:play-services-ads:24.7.0")
implementation ("com.google.android.gms:play-services-ads-identifier:18.0.1")
// implementation("com.google.android.gms:play-services-ads:24.7.0")
// implementation ("com.google.android.gms:play-services-ads-identifier:18.0.1")
// okhttp
implementation ("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
// TradPlus
implementation("com.tradplusad:tradplus:15.1.10.1")
//noinspection GradleCompatible
implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("androidx.appcompat:appcompat:1.3.0-alpha02")
// Ironsource
implementation("com.ironsource.sdk:mediationsdk:9.0.0")
implementation("com.tradplusad:tradplus-ironsource:10.15.1.10.1")
// Pangle
implementation("com.tradplusad:tradplus-pangle:19.15.1.10.1")
implementation("com.pangle.global:pag-sdk:7.7.0.2")
// UnityAds
implementation("com.tradplusad:tradplus-unity:5.15.1.10.1")
implementation("com.unity3d.ads:unity-ads:4.16.3")
// Inmobi
implementation("com.tradplusad:tradplus-inmobix:23.15.1.10.1")
implementation("com.inmobi.monetization:inmobi-ads-kotlin:11.0.0")
implementation("com.squareup.okhttp3:okhttp:3.14.9")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
implementation("androidx.core:core-ktx:1.5.0")
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0")
implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
implementation("com.google.android.gms:play-services-location:21.0.1")
//optional dependency for better targeting
implementation("androidx.browser:browser:1.8.0")
implementation("com.squareup.picasso:picasso:2.8")
implementation("androidx.viewpager:viewpager:1.0.0")
implementation("androidx.recyclerview:recyclerview:1.2.1")
// Mintegral
implementation("com.tradplusad:tradplus-mintegralx_overseas:18.15.1.10.1")
implementation("androidx.recyclerview:recyclerview:1.1.0")
implementation("com.mbridge.msdk.oversea:mbridge_android_sdk:16.10.11")
// Liftoff
implementation("com.tradplusad:tradplus-vunglex:7.15.1.10.1")
implementation("com.vungle:vungle-ads:7.6.0")
// Bigo
implementation("com.bigossp:bigo-ads:5.5.2")
implementation("com.tradplusad:tradplus-bigo:57.15.1.10.1")
// Cross Promotion
implementation("com.tradplusad:tradplus-crosspromotion:27.15.1.10.1")
// TP Exchange
// 请注意保持与主包版本同步更新
implementation("com.google.code.gson:gson:2.8.6")
implementation("com.tradplusad:tp_exchange:40.15.1.10.1")
}

View File

@ -51,3 +51,6 @@
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes InnerClasses
-keep public class com.tradplus.** { *; }
-keep class com.tradplus.ads.** { *; }

View File

@ -28,6 +28,8 @@
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.AD_ID" />
<application
android:name=".PRApp"
android:allowBackup="true"
@ -36,6 +38,7 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
tools:replace="networkSecurityConfig"
android:networkSecurityConfig="@xml/net"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"

View File

@ -6,9 +6,8 @@ import androidx.annotation.StringRes
import com.all.pdfreader.pdf.reader.room.repository.PdfRepository
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.all.pdfreader.pdf.reader.util.FileChangeObserver
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.RequestConfiguration
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
import com.tradplus.ads.open.TradPlusSdk
import com.up.uploadlibrary.UpLoadManager
class PRApp : Application() {
@ -44,14 +43,12 @@ class PRApp : Application() {
PDFBoxResourceLoader.init(this)
// 上传
UpLoadManager.init(context = this, tag = "PRApp_upload_task") { _, _ -> }
// 广告初始化
MobileAds.initialize(this)
initAds()
}
private fun initMobileAds() {
val testDeviceIds = listOf("9A96E667D69B45F744FD7D724DF8B093")
val configuration = RequestConfiguration.Builder().setTestDeviceIds(testDeviceIds).build()
MobileAds.setRequestConfiguration(configuration)
private fun initAds() {
// 广告初始化
TradPlusSdk.initSdk(this, "7D782C68D2CB653BE84B6912673BDF11")
}
// 在权限授权后调用

View File

@ -3,10 +3,10 @@ package com.all.pdfreader.pdf.reader.ad
import android.app.Activity
import android.util.Log
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import com.tradplus.ads.base.bean.TPAdError
import com.tradplus.ads.base.bean.TPAdInfo
import com.tradplus.ads.open.interstitial.InterstitialAdListener
import com.tradplus.ads.open.interstitial.TPInterstitial
class AdInstLoad(
private val activity: Activity,
@ -19,11 +19,11 @@ class AdInstLoad(
}
private fun loadAd() {
Log.d(AdsInsUtil.Placement.TAG,"广告 $placement 开始加载")
Log.d(AdsInsUtil.Placement.TAG, "广告 $placement 开始加载")
// 是否存在缓存广告、展示安全
val cachedAd = InstAdCacheManager.instance.getAdCache(placement)
if (cachedAd != null) {
Log.d(AdsInsUtil.Placement.TAG,"广告存在缓存,跳过加载,返回成功")
Log.d(AdsInsUtil.Placement.TAG, "广告存在缓存,跳过加载,返回成功")
//缓存广告有效,跳过加载,返回成功
adLoadListener?.loaded(cachedAd)
return
@ -31,7 +31,7 @@ class AdInstLoad(
// 如果正在加载(其他地方已 load 加入等待队列
if (InstAdCacheManager.instance.isLoading(placement)) {
Log.d(AdsInsUtil.Placement.TAG,"广告 $placement 正在加载中,加入等待队列")
Log.d(AdsInsUtil.Placement.TAG, "广告 $placement 正在加载中,加入等待队列")
InstAdCacheManager.instance.addPendingListener(placement, adLoadListener)
return
}
@ -41,35 +41,68 @@ class AdInstLoad(
val adUnitId = AdsInsUtil.adUnitIdMap[placement] ?: run {
val errorMsg = "No AdUnitId for $placement"
Log.d(AdsInsUtil.Placement.TAG,"没找到对应的广告ID->$placement")
Log.d(AdsInsUtil.Placement.TAG, "没找到对应的广告ID->$placement")
InstAdCacheManager.instance.notifyFail(placement, errorMsg)
return
}
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.REQ)
Log.d(AdsInsUtil.Placement.TAG,"adUnitId->$adUnitId")
InterstitialAd.load(
activity,
adUnitId,
AdRequest.Builder().build(),
object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) {
Log.d(AdsInsUtil.Placement.TAG,"广告 $placement 加载成功")
InstAdCacheManager.instance.setAdCache(placement, ad)
Log.d(AdsInsUtil.Placement.TAG, "adUnitId->$adUnitId")
val tpInterstitial = TPInterstitial(activity, adUnitId)
tpInterstitial.setAdListener(object : InterstitialAdListener {
//广告加载完成 首个广告源加载成功时回调 一次加载流程只会回调一次
override fun onAdLoaded(tpAdInfo: TPAdInfo) {
Log.d(AdsInsUtil.Placement.TAG, "广告 $placement 加载成功")
InstAdCacheManager.instance.setAdCache(placement, tpInterstitial)
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.LOADED)
InstAdCacheManager.instance.notifySuccess(placement, ad)
InstAdCacheManager.instance.notifySuccess(placement, tpInterstitial)
}
override fun onAdFailedToLoad(adError: LoadAdError) {
Log.d(AdsInsUtil.Placement.TAG,"广告 $placement 加载失败")
// 广告被点击
override fun onAdClicked(tpAdInfo: TPAdInfo?) {
Log.d("ocean", "tradplus onAdClicked")
}
// 广告成功展示在页面上
override fun onAdImpression(tpAdInfo: TPAdInfo?) {
Log.d("ocean", "tradplus onAdImpression")
}
// 广告加载失败
override fun onAdFailed(error: TPAdError?) {
Log.d(AdsInsUtil.Placement.TAG, "广告 $placement 加载失败 ${error?.errorCode} ${error?.errorMsg}")
AnalyticsUtils.logAdEvent(
placement,
AnalyticsUtils.AdEvent.LOAD_FAIL,
adError.code,
adError.message
error?.errorCode,
error?.errorMsg
)
InstAdCacheManager.instance.notifyFail(placement, adError.toString())
InstAdCacheManager.instance.notifyFail(placement, "${error?.errorCode} ${error?.errorMsg}")
}
},
// 广告被关闭
override fun onAdClosed(tpAdInfo: TPAdInfo?) {
Log.d("ocean", "tradplus onAdClosed")
}
// 视频播放开始(部分广告源支持)
override fun onAdVideoStart(tpAdInfo: TPAdInfo?) {
Log.d("ocean", "tradplus onAdVideoStart")
}
//视频播放结束(部分广告源支持)
override fun onAdVideoEnd(tpAdInfo: TPAdInfo?) {
Log.d("ocean", "tradplus onAdVideoEnd")
}
//视频播放失败(部分广告源支持)
override fun onAdVideoError(tpAdInfo: TPAdInfo?, error: TPAdError?) {
Log.d(
"ocean",
"onAdVideoError code->${error?.errorCode}message->${error?.errorMsg}"
)
}
})
tpInterstitial.loadAd()
}
}

View File

@ -3,8 +3,9 @@ package com.all.pdfreader.pdf.reader.ad
import android.app.Activity
import android.util.Log
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.FullScreenContentCallback
import com.tradplus.ads.base.bean.TPAdError
import com.tradplus.ads.base.bean.TPAdInfo
import com.tradplus.ads.open.interstitial.InterstitialAdListener
class AdInstShower(
private val activity: Activity,
@ -23,22 +24,22 @@ class AdInstShower(
private fun showAd() {
// ======= 新增:全局展示间隔限制 启动页不处理 =======
if(placement != AdsInsUtil.AdPlacement.SPL_AND_INTO_HOME){
val now = System.currentTimeMillis()
if (now - lastShowTimestamp < SHOW_INTERVAL) {
val errorMsg = "广告展示过于频繁, 请等待 ${(SHOW_INTERVAL - (now - lastShowTimestamp)) / 1000}s间隔限制60s"
showListener?.onAdShowFailed(errorMsg)
Log.d(AdsInsUtil.Placement.TAG, "showAd->$errorMsg")
AnalyticsUtils.logAdEvent(
placement,
AnalyticsUtils.AdEvent.SHOW_FAIL_ME,
1001,
errorMsg
)
return
}
}
// if(placement != AdsInsUtil.AdPlacement.SPL_AND_INTO_HOME){
// val now = System.currentTimeMillis()
// if (now - lastShowTimestamp < SHOW_INTERVAL) {
// val errorMsg = "广告展示过于频繁, 请等待 ${(SHOW_INTERVAL - (now - lastShowTimestamp)) / 1000}s间隔限制60s"
// showListener?.onAdShowFailed(errorMsg)
// Log.d(AdsInsUtil.Placement.TAG, "showAd->$errorMsg")
//
// AnalyticsUtils.logAdEvent(
// placement,
// AnalyticsUtils.AdEvent.SHOW_FAIL_ME,
// 1001,
// errorMsg
// )
// return
// }
// }
val interstitialAd = InstAdCacheManager.instance.getAdCache(placement)
?: run {
@ -55,43 +56,55 @@ class AdInstShower(
return
}
interstitialAd.fullScreenContentCallback = object : FullScreenContentCallback() {
interstitialAd.setAdListener(object : InterstitialAdListener {
//广告加载完成 首个广告源加载成功时回调 一次加载流程只会回调一次
override fun onAdLoaded(tpAdInfo: TPAdInfo?) {}
override fun onAdShowedFullScreenContent() {
// ======= 新增:展示成功 记录时间 =======
// 广告被点击
override fun onAdClicked(tpAdInfo: TPAdInfo?) {
showListener?.onAdClicked()
Log.d("ocean", "AdInstShower 广告点击回调")
}
// 广告成功展示在页面上
override fun onAdImpression(tpAdInfo: TPAdInfo?) {
lastShowTimestamp = System.currentTimeMillis()
Log.d(AdsInsUtil.Placement.TAG, "广告 $placement 展示成功")
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.SHOW_SUC)
showListener?.onAdShown()
}
override fun onAdDismissedFullScreenContent() {
// 广告加载失败
override fun onAdFailed(error: TPAdError?) {}
// 广告被关闭
override fun onAdClosed(tpAdInfo: TPAdInfo?) {
// 用户关闭广告
InstAdCacheManager.instance.remove(placement)
showListener?.onAdClosed()
Log.d("ocean", "AdInstShower 广告关闭回调")
}
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
// 视频播放开始(部分广告源支持)
override fun onAdVideoStart(tpAdInfo: TPAdInfo?) {}
//视频播放结束(部分广告源支持)
override fun onAdVideoEnd(tpAdInfo: TPAdInfo?) {}
//视频播放失败(部分广告源支持)
override fun onAdVideoError(tpAdInfo: TPAdInfo?, error: TPAdError?) {
Log.d("ocean", "AdInstShower 视频广告播放失败回调->${error}")
AnalyticsUtils.logAdEvent(
placement,
AnalyticsUtils.AdEvent.SHOW_FAIL,
adError.code,
adError.message
error?.errorCode,
error?.errorMsg
)
InstAdCacheManager.instance.remove(placement)
showListener?.onAdShowFailed(adError.toString())
Log.d(AdsInsUtil.Placement.TAG, "广告 $placement 展示失败->${adError}")
showListener?.onAdShowFailed(error.toString())
Log.d(AdsInsUtil.Placement.TAG, "广告 $placement 展示失败->${error}")
}
override fun onAdClicked() {
showListener?.onAdClicked()
}
override fun onAdImpression() {
// 曝光回调
}
}
interstitialAd.show(activity)
})
interstitialAd.showAd(activity, placement.tag)
}
}

View File

@ -8,11 +8,7 @@ object AdsInsUtil {
enum class AdPlacement(val tag: String) {
SPL_AND_INTO_HOME(Placement.SPL_AND_INTO_HOME),
INT_AND_TOPDF(Placement.INT_AND_TOPDF),
INT_AND_PDFTOHOME(Placement.INT_AND_PDFTOHOME),
INT_AND_MERGE(Placement.INT_AND_MERGE),
INT_AND_SPLIT(Placement.INT_AND_SPLIT),
NATIVE_AND_EXIT(Placement.NATIVE_AND_EXIT),
BAN_AND_HOMEPAGE(Placement.BAN_AND_HOMEPAGE)
INT_AND_TO_RESULT(Placement.INT_AND_TO_RESULT),
}
object Placement {
@ -27,11 +23,7 @@ object AdsInsUtil {
* 在首页/最近页/喜欢页-点击文件进入PDF内容页过程中弹出缓存的插屏广告
*/
const val INT_AND_TOPDF = "int_and_topdf"
/**
* PDF内容页点击返回到首页/最近页/喜欢页过程中弹出缓存的插屏广告
*/
const val INT_AND_PDFTOHOME = "int_and_pdftohome"
const val INT_AND_TO_RESULT = "int_and_to_result"
/**
* 首页/最近/喜欢-PDF内容页-更多-合并文件在点击ok后出现插屏广告插屏广告结束后到合并成功页面
@ -56,41 +48,9 @@ object AdsInsUtil {
// 广告位对应的广告ID
val adUnitIdMap: Map<AdPlacement, String> = mapOf(
AdPlacement.SPL_AND_INTO_HOME to if (BuildConfig.DEBUG) {
"ca-app-pub-3940256099942544/1033173712"
} else {
"ca-app-pub-5717753826607607/9606833210"
},
AdPlacement.INT_AND_TOPDF to if (BuildConfig.DEBUG) {
"ca-app-pub-3940256099942544/1033173712"
} else {
"ca-app-pub-5717753826607607/5308904672"
},
AdPlacement.INT_AND_PDFTOHOME to if (BuildConfig.DEBUG) {
"ca-app-pub-3940256099942544/1033173712"
} else {
"ca-app-pub-5717753826607607/7085128570"
},
AdPlacement.INT_AND_MERGE to if (BuildConfig.DEBUG) {
"ca-app-pub-3940256099942544/1033173712"
} else {
"ca-app-pub-5717753826607607/8928693282"
},
AdPlacement.INT_AND_SPLIT to if (BuildConfig.DEBUG) {
"ca-app-pub-3940256099942544/1033173712"
} else {
"ca-app-pub-5717753826607607/2338415962"
},
AdPlacement.NATIVE_AND_EXIT to if (BuildConfig.DEBUG) {
"ca-app-pub-3940256099942544/2247696110"
} else {
"ca-app-pub-5717753826607607/7276700267"
},
AdPlacement.BAN_AND_HOMEPAGE to if (BuildConfig.DEBUG) {
"ca-app-pub-3940256099942544/9214589741"
} else {
"ca-app-pub-5717753826607607/5939567861"
}
AdPlacement.SPL_AND_INTO_HOME to "B421758030611F925EE37C791CCDDA12",
AdPlacement.INT_AND_TOPDF to "558381BCAC5CF8CEEFFD26B668C4AD12",
AdPlacement.INT_AND_TO_RESULT to "746C9253315481118A10AF5417F1FB12",
)
fun loadAd(

View File

@ -1,132 +0,0 @@
package com.all.pdfreader.pdf.reader.ad
import android.app.Activity
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.LoadAdError
object BannerManager {
private data class BannerInfo(val adView: AdView, val container: FrameLayout, var isLoaded: Boolean = false)
private val bannerMap = mutableMapOf<String, BannerInfo>()
//因为有多个activity来展示这个banner所以我们使用act的名称+广告位做为key
private fun key(placement: AdsInsUtil.AdPlacement, activity: Activity): String {
return "${placement.name}_${activity::class.java.simpleName}"
}
fun loadBanner(
activity: Activity,
container: FrameLayout,
placement: AdsInsUtil.AdPlacement,
onLoaded: (() -> Unit)? = null
) {
val currentKey = key(placement, activity)//得到当前的key
val adUnitId = AdsInsUtil.adUnitIdMap[placement] ?: run {
Log.d(AdsInsUtil.Placement.TAG, "${activity::class.java.simpleName} Banner 未找到广告ID: $placement")
container.visibility = View.GONE
return
}
Log.d(AdsInsUtil.Placement.TAG, "${activity::class.java.simpleName} Banner $placement 开始加载")
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.REQ)
container.post {
container.visibility = View.GONE
val adSize = getAdSize(activity, container)
// 销毁旧 AdView
bannerMap[currentKey]?.adView?.destroy()
val adView = AdView(activity).apply {
this.adUnitId = adUnitId
setAdSize(adSize)
adListener = object : AdListener() {
override fun onAdLoaded() {
Log.d(AdsInsUtil.Placement.TAG, "${activity::class.java.simpleName} Banner $placement 加载成功")
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.LOADED)
val info = bannerMap[currentKey]
info?.isLoaded = true
// 广告加载成功后显示容器
info?.container?.visibility = View.VISIBLE
info?.container?.alpha = 0f
info?.container?.animate()?.alpha(1f)?.setDuration(300)?.start()
onLoaded?.invoke()
}
override fun onAdFailedToLoad(error: LoadAdError) {
Log.d(AdsInsUtil.Placement.TAG, "${activity::class.java.simpleName} Banner $placement 加载失败: ${error.message}")
AnalyticsUtils.logAdEvent(
placement,
AnalyticsUtils.AdEvent.LOAD_FAIL,
error.code,
error.message
)
val info = bannerMap[currentKey]
info?.isLoaded = false
info?.container?.visibility = View.GONE
}
}
}
bannerMap[currentKey] = BannerInfo(adView, container)
container.removeAllViews()
container.addView(adView)
adView.loadAd(AdRequest.Builder().build())
}
}
fun onResume(activity: Activity, placement: AdsInsUtil.AdPlacement) {
Log.d(AdsInsUtil.Placement.TAG, "${activity::class.java.simpleName} Banner $placement 恢复广告")
val info = bannerMap[key(placement, activity)] ?: return
info.adView.resume()
if (info.isLoaded) {
info.container.visibility = View.VISIBLE
info.container.alpha = 0f
info.container.animate().alpha(1f).setDuration(300).start()
} else {
info.container.visibility = View.GONE
}
}
fun onPause(activity: Activity, placement: AdsInsUtil.AdPlacement) {
val info = bannerMap[key(placement, activity)] ?: return
info.container.visibility = View.GONE//暂停后就隐藏,让回调来显示
info.adView.pause()
Log.d(AdsInsUtil.Placement.TAG, "${activity::class.java.simpleName} Banner $placement 暂停广告")
}
fun onDestroy(activity: Activity, placement: AdsInsUtil.AdPlacement) {
val key = key(placement, activity)
bannerMap[key]?.adView?.destroy()
bannerMap.remove(key)
Log.d(AdsInsUtil.Placement.TAG, "${activity::class.java.simpleName} Banner $placement 销毁广告")
}
private fun getAdSize(activity: Activity, container: FrameLayout): AdSize {
val display = activity.windowManager.defaultDisplay
val outMetrics = DisplayMetrics()
display.getMetrics(outMetrics)
var adWidthPixels = container.width.toFloat()
if (adWidthPixels == 0f) adWidthPixels = outMetrics.widthPixels.toFloat()
val density = outMetrics.density
val adWidth = (adWidthPixels / density).toInt()
return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(activity, adWidth)
}
}

View File

@ -1,6 +1,6 @@
package com.all.pdfreader.pdf.reader.ad
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.tradplus.ads.open.interstitial.TPInterstitial
class InstAdCacheManager {
@ -39,7 +39,7 @@ class InstAdCacheManager {
}
fun notifySuccess(place: AdsInsUtil.AdPlacement, ad: InterstitialAd) {
fun notifySuccess(place: AdsInsUtil.AdPlacement, ad: TPInterstitial) {
pendingListeners[place]?.forEach { it?.loaded(ad) }
pendingListeners.remove(place)
loadingSet.remove(place)
@ -53,13 +53,13 @@ class InstAdCacheManager {
/** ============= 广告缓存逻辑 ============= */
fun setAdCache(place: AdsInsUtil.AdPlacement, adCache: InterstitialAd) {
fun setAdCache(place: AdsInsUtil.AdPlacement, adCache: TPInterstitial) {
mAdCacheDict[place] = CachedAd(adCache)
}
fun getAdCache(place: AdsInsUtil.AdPlacement): InterstitialAd? {
fun getAdCache(place: AdsInsUtil.AdPlacement): TPInterstitial? {
val cached = mAdCacheDict[place]
return if (cached != null && cached.isValid()) cached.ad
return if (cached != null && cached.ad.isReady) cached.ad
else {
mAdCacheDict.remove(place) // 清理过期
null
@ -74,10 +74,7 @@ class InstAdCacheManager {
* 包装广告 + 时间
*/
data class CachedAd(
val ad: InterstitialAd,
val loadedAt: Long = System.currentTimeMillis()
val ad: TPInterstitial,
) {
// 广告有效期 1 小时
fun isValid(): Boolean = System.currentTimeMillis() - loadedAt < 3600_000
}
}

View File

@ -1,8 +1,8 @@
package com.all.pdfreader.pdf.reader.ad
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.tradplus.ads.open.interstitial.TPInterstitial
interface LoadListener {
fun loadFailed(string: String) {}
fun loaded(ad: InterstitialAd) {}
fun loaded(ad: TPInterstitial) {}
}

View File

@ -1,74 +0,0 @@
package com.all.pdfreader.pdf.reader.ad
import android.app.Activity
import android.content.Context
import android.util.Log
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdLoader
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.nativead.NativeAd
object NativeAdCache {
private var cachedAd: NativeAd? = null
fun load(
context: Context,
placement: AdsInsUtil.AdPlacement,
onAdLoaded: (() -> Unit)? = null,
onAdFailedToLoad: (() -> Unit)? = null
) {
if (cachedAd != null) {
onAdLoaded?.invoke()
return
}
val adUnitId = AdsInsUtil.adUnitIdMap[placement] ?: run {
val errorMsg = "No AdUnitId for $placement"
Log.d(AdsInsUtil.Placement.TAG, "没找到对应的广告ID->$placement")
onAdFailedToLoad?.invoke()
return
}
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.REQ)
val adLoader = AdLoader.Builder(context, adUnitId)
.forNativeAd { ad ->
if (context is Activity) {
if (context.isFinishing || context.isDestroyed) {
ad.destroy()
return@forNativeAd
}
}
cachedAd?.destroy()
cachedAd = ad
onAdLoaded?.invoke()
}
.withAdListener(object : AdListener() {
override fun onAdFailedToLoad(error: LoadAdError) {
cachedAd = null
onAdFailedToLoad?.invoke()
Log.d(AdsInsUtil.Placement.TAG, "$placement 广告加载失败 ${error.message}")
AnalyticsUtils.logAdEvent(
placement,
AnalyticsUtils.AdEvent.LOAD_FAIL,
error.code,
error.message
)
}
override fun onAdLoaded() {
Log.d(AdsInsUtil.Placement.TAG, "$placement 广告加载成功")
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.LOADED)
}
})
.build()
adLoader.loadAd(AdRequest.Builder().build())
}
fun getAd(): NativeAd? = cachedAd
fun clear() {
cachedAd?.destroy()
cachedAd = null
}
}

View File

@ -15,8 +15,6 @@ import androidx.lifecycle.lifecycleScope
import com.all.pdfreader.pdf.reader.PRApp
import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil
import com.all.pdfreader.pdf.reader.ad.BannerManager
import com.all.pdfreader.pdf.reader.ad.NativeAdCache
import com.all.pdfreader.pdf.reader.databinding.ActivityMainBinding
import com.all.pdfreader.pdf.reader.model.FileActionEvent
import com.all.pdfreader.pdf.reader.model.FragmentType
@ -39,16 +37,6 @@ import com.all.pdfreader.pdf.reader.util.PdfScanner
import com.all.pdfreader.pdf.reader.util.StoragePermissionHelper
import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel
import com.all.pdfreader.pdf.reader.viewmodel.observeEvent
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdLoader
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.nativead.NativeAdOptions
import com.google.android.gms.ads.nativead.NativeAdView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
@ -76,7 +64,6 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
loadAd()
AnalyticsUtils.logEvent(AnalyticsUtils.Event.HOME_SHOW)
setupDoubleBackExit()
initObserve()
@ -579,16 +566,17 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
private fun loadAd() {
AdsInsUtil.loadAd(this, AdsInsUtil.AdPlacement.INT_AND_TOPDF)
AdsInsUtil.loadAd(this, AdsInsUtil.AdPlacement.INT_AND_PDFTOHOME)
AdsInsUtil.loadAd(this, AdsInsUtil.AdPlacement.INT_AND_TO_RESULT)
NativeAdCache.load(this, AdsInsUtil.AdPlacement.NATIVE_AND_EXIT)
BannerManager.loadBanner(this, binding.bannerAdFl, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
// NativeAdCache.load(this, AdsInsUtil.AdPlacement.NATIVE_AND_EXIT)
//
// BannerManager.loadBanner(this, binding.bannerAdFl, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
}
override fun onResume() {
super.onResume()
BannerManager.onResume(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
loadAd()
// BannerManager.onResume(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
logDebug("main onResume")
if (StoragePermissionHelper.hasBasicStoragePermission(this)) {
// 有授权才初始化文件变化监听器
@ -605,12 +593,12 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
}
override fun onPause() {
BannerManager.onPause(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
// BannerManager.onPause(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
super.onPause()
}
override fun onDestroy() {
BannerManager.onDestroy(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
// BannerManager.onDestroy(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
super.onDestroy()
}

View File

@ -43,7 +43,7 @@ class MergePdfActivity : BaseActivity() {
binding = ActivityPdfMergeBinding.inflate(layoutInflater)
setContentView(binding.root)
AnalyticsUtils.logEvent(AnalyticsUtils.Event.MERGE_SHOW)
AdsInsUtil.loadAd(this, AdsInsUtil.AdPlacement.INT_AND_MERGE)
// AdsInsUtil.loadAd(this, AdsInsUtil.AdPlacement.INT_AND_MERGE)
setupImmersionBar {
statusBarView(binding.view)
statusBarDarkFont(true)

View File

@ -130,6 +130,15 @@ class PdfResultActivity : BaseActivity() {
super.onCreate(savedInstanceState)
binding = ActivityPdfSplitResultBinding.inflate(layoutInflater)
setContentView(binding.root)
AdsInsUtil.showFinishAd(
this,
AdsInsUtil.AdPlacement.INT_AND_TO_RESULT
) {
AdsInsUtil.loadAd(
this,
AdsInsUtil.AdPlacement.INT_AND_TO_RESULT
)
}
setupImmersionBar {
statusBarView(binding.view)
statusBarDarkFont(true)
@ -162,9 +171,9 @@ class PdfResultActivity : BaseActivity() {
if (source == PdfPickerSource.SPLIT) {
val splitPassword = intent.getStringExtra(EXTRA_SPLIT_PASSWORD) ?: ""
withContext(Dispatchers.Main) {
AdsInsUtil.showFinishAd(this@PdfResultActivity, AdsInsUtil.AdPlacement.INT_AND_SPLIT){
AdsInsUtil.loadAd(this@PdfResultActivity, AdsInsUtil.AdPlacement.INT_AND_SPLIT)
}
// AdsInsUtil.showFinishAd(this@PdfResultActivity, AdsInsUtil.AdPlacement.INT_AND_SPLIT){
// AdsInsUtil.loadAd(this@PdfResultActivity, AdsInsUtil.AdPlacement.INT_AND_SPLIT)
// }
binding.progressBar.isIndeterminate = false
binding.progressBar.progress = 0
@ -216,9 +225,9 @@ class PdfResultActivity : BaseActivity() {
}
} else if (source == PdfPickerSource.MERGE) {
withContext(Dispatchers.Main) {
AdsInsUtil.showFinishAd(this@PdfResultActivity, AdsInsUtil.AdPlacement.INT_AND_MERGE){
AdsInsUtil.loadAd(this@PdfResultActivity, AdsInsUtil.AdPlacement.INT_AND_MERGE)
}
// AdsInsUtil.showFinishAd(this@PdfResultActivity, AdsInsUtil.AdPlacement.INT_AND_MERGE){
// AdsInsUtil.loadAd(this@PdfResultActivity, AdsInsUtil.AdPlacement.INT_AND_MERGE)
// }
binding.progressBar.isIndeterminate = false
binding.progressBar.progress = 0
binding.progressBar.max = 100

View File

@ -14,7 +14,6 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil
import com.all.pdfreader.pdf.reader.ad.BannerManager
import com.all.pdfreader.pdf.reader.databinding.ActivityPdfViewBinding
import com.all.pdfreader.pdf.reader.model.FileActionEvent
import com.all.pdfreader.pdf.reader.room.entity.PdfDocumentEntity
@ -82,7 +81,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
binding = ActivityPdfViewBinding.inflate(layoutInflater)
setContentView(binding.root)
AnalyticsUtils.logEvent(AnalyticsUtils.Event.PDF_SHOW)
BannerManager.loadBanner(this, binding.bannerAdFl, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
// BannerManager.loadBanner(this, binding.bannerAdFl, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
setupImmersionBar {
statusBarView(binding.view)
statusBarDarkFont(true)
@ -490,15 +489,6 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
}
} else {
AnalyticsUtils.logEvent(AnalyticsUtils.Event.PDFTO_HOME_CK)
AdsInsUtil.showFinishAd(
this@PdfViewActivity,
AdsInsUtil.AdPlacement.INT_AND_PDFTOHOME
) {
AdsInsUtil.loadAd(
this@PdfViewActivity,
AdsInsUtil.AdPlacement.INT_AND_PDFTOHOME
)
}
isEnabled = false // 解除拦截
onBackPressedDispatcher.onBackPressed() // 调用系统默认返回逻辑
}
@ -606,7 +596,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
}
override fun onDestroy() {
BannerManager.onDestroy(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
// BannerManager.onDestroy(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
super.onDestroy()
if (::searchManager.isInitialized) {
searchManager.closeCachedDocument()
@ -615,11 +605,11 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
override fun onResume() {
super.onResume()
BannerManager.onResume(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
// BannerManager.onResume(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
}
override fun onPause() {
BannerManager.onPause(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
// BannerManager.onPause(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
super.onPause()
}
}

View File

@ -5,18 +5,13 @@ import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.activity.OnBackPressedCallback
import androidx.core.view.doOnPreDraw
import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil
import com.all.pdfreader.pdf.reader.ad.LoadListener
import com.all.pdfreader.pdf.reader.ad.ShowListener
import com.all.pdfreader.pdf.reader.databinding.ActivitySplashBinding
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.gyf.immersionbar.BarHide
import com.gyf.immersionbar.ImmersionBar
import com.tradplus.ads.open.interstitial.TPInterstitial
@SuppressLint("CustomSplashScreen")
class SplashActivity : BaseActivity() {
@ -56,7 +51,7 @@ class SplashActivity : BaseActivity() {
act = this,
adPlacement = AdsInsUtil.AdPlacement.SPL_AND_INTO_HOME,
loadListener = object : LoadListener {
override fun loaded(ad: InterstitialAd) {
override fun loaded(ad: TPInterstitial) {
logDebug("loaded 启动页广告加载成功")
adHandler.removeCallbacks(adTimeoutRunnable)
showSplashAd()

View File

@ -65,7 +65,7 @@ class SplitPdfActivity : BaseActivity() {
super.onCreate(savedInstanceState)
binding = ActivityPdfSplitBinding.inflate(layoutInflater)
setContentView(binding.root)
AdsInsUtil.loadAd(this, AdsInsUtil.AdPlacement.INT_AND_SPLIT)
// AdsInsUtil.loadAd(this, AdsInsUtil.AdPlacement.INT_AND_SPLIT)
setupImmersionBar {
statusBarView(binding.view)
statusBarDarkFont(true)

View File

@ -1,17 +1,12 @@
package com.all.pdfreader.pdf.reader.ui.dialog
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil
import com.all.pdfreader.pdf.reader.ad.NativeAdCache
import com.all.pdfreader.pdf.reader.databinding.AdAdmobNativeExitLayoutBinding
import com.all.pdfreader.pdf.reader.databinding.DialogExitBinding
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class ExitDialogFragment() : BottomSheetDialogFragment() {
@ -50,14 +45,14 @@ class ExitDialogFragment() : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupOnClick()
val cached = NativeAdCache.getAd()
if (cached != null) {
Log.d(AdsInsUtil.Placement.TAG, "使用缓存广告")
showNativeAd(cached)
} else {
Log.d(AdsInsUtil.Placement.TAG, "无缓存,开始加载")
loadNativeAd()
}
// val cached = NativeAdCache.getAd()
// if (cached != null) {
// Log.d(AdsInsUtil.Placement.TAG, "使用缓存广告")
// showNativeAd(cached)
// } else {
// Log.d(AdsInsUtil.Placement.TAG, "无缓存,开始加载")
// loadNativeAd()
// }
}
private fun setupOnClick() {
@ -67,116 +62,116 @@ class ExitDialogFragment() : BottomSheetDialogFragment() {
}
}
private fun showNativeAd(nativeAd: NativeAd) {
if (!isAdded || activity == null) {
nativeAd.destroy()
return
}
if (requireActivity().isFinishing || requireActivity().isDestroyed) {
nativeAd.destroy()
return
}
// Inflate 必须在主线程
val adBinding = AdAdmobNativeExitLayoutBinding.inflate(layoutInflater)
populateNativeAdView(nativeAd, adBinding)
binding.adFl.removeAllViews()
binding.adFl.addView(adBinding.root)
}
// private fun showNativeAd(nativeAd: NativeAd) {
// if (!isAdded || activity == null) {
// nativeAd.destroy()
// return
// }
//
// if (requireActivity().isFinishing || requireActivity().isDestroyed) {
// nativeAd.destroy()
// return
// }
//
// // Inflate 必须在主线程
// val adBinding = AdAdmobNativeExitLayoutBinding.inflate(layoutInflater)
// populateNativeAdView(nativeAd, adBinding)
//
// binding.adFl.removeAllViews()
// binding.adFl.addView(adBinding.root)
// }
private fun loadNativeAd() {
NativeAdCache.load(requireActivity(), AdsInsUtil.AdPlacement.NATIVE_AND_EXIT, onAdLoaded = {
if (!isAdded) return@load
val ad = NativeAdCache.getAd() ?: return@load
showNativeAd(ad)
})
// NativeAdCache.load(requireActivity(), AdsInsUtil.AdPlacement.NATIVE_AND_EXIT, onAdLoaded = {
// if (!isAdded) return@load
// val ad = NativeAdCache.getAd() ?: return@load
// showNativeAd(ad)
// })
}
private fun populateNativeAdView(
nativeAd: NativeAd,
unifiedAdBinding: AdAdmobNativeExitLayoutBinding
) {
val nativeAdView = unifiedAdBinding.root
// Set the media view.
nativeAdView.mediaView = unifiedAdBinding.adMedia
// Set other ad assets.
nativeAdView.headlineView = unifiedAdBinding.adHeadline
nativeAdView.bodyView = unifiedAdBinding.adBody
nativeAdView.callToActionView = unifiedAdBinding.adCallToAction
nativeAdView.iconView = unifiedAdBinding.adAppIcon
// nativeAdView.priceView = unifiedAdBinding.adPrice
nativeAdView.starRatingView = unifiedAdBinding.adStars
// nativeAdView.storeView = unifiedAdBinding.adStore
nativeAdView.advertiserView = unifiedAdBinding.adAdvertiser
// The headline and media content are guaranteed to be in every UnifiedNativeAd.
unifiedAdBinding.adHeadline.text = nativeAd.headline
nativeAd.mediaContent?.let { unifiedAdBinding.adMedia.setMediaContent(it) }
// These assets aren't guaranteed to be in every UnifiedNativeAd, so it's important to
// check before trying to display them.
if (nativeAd.body == null) {
unifiedAdBinding.adBody.visibility = View.INVISIBLE
} else {
unifiedAdBinding.adBody.visibility = View.VISIBLE
unifiedAdBinding.adBody.text = nativeAd.body
}
if (nativeAd.callToAction == null) {
unifiedAdBinding.adCallToAction.visibility = View.INVISIBLE
} else {
unifiedAdBinding.adCallToAction.visibility = View.VISIBLE
unifiedAdBinding.adCallToAction.text = nativeAd.callToAction
}
if (nativeAd.icon == null) {
unifiedAdBinding.adAppIcon.visibility = View.GONE
} else {
unifiedAdBinding.adAppIcon.setImageDrawable(nativeAd.icon?.drawable)
unifiedAdBinding.adAppIcon.visibility = View.VISIBLE
}
// if (nativeAd.price == null) {
// unifiedAdBinding.adPrice.visibility = View.INVISIBLE
//
// private fun populateNativeAdView(
// nativeAd: NativeAd,
// unifiedAdBinding: AdAdmobNativeExitLayoutBinding
// ) {
// val nativeAdView = unifiedAdBinding.root
//
// // Set the media view.
// nativeAdView.mediaView = unifiedAdBinding.adMedia
//
// // Set other ad assets.
// nativeAdView.headlineView = unifiedAdBinding.adHeadline
// nativeAdView.bodyView = unifiedAdBinding.adBody
// nativeAdView.callToActionView = unifiedAdBinding.adCallToAction
// nativeAdView.iconView = unifiedAdBinding.adAppIcon
//// nativeAdView.priceView = unifiedAdBinding.adPrice
// nativeAdView.starRatingView = unifiedAdBinding.adStars
//// nativeAdView.storeView = unifiedAdBinding.adStore
// nativeAdView.advertiserView = unifiedAdBinding.adAdvertiser
//
// // The headline and media content are guaranteed to be in every UnifiedNativeAd.
// unifiedAdBinding.adHeadline.text = nativeAd.headline
// nativeAd.mediaContent?.let { unifiedAdBinding.adMedia.setMediaContent(it) }
//
// // These assets aren't guaranteed to be in every UnifiedNativeAd, so it's important to
// // check before trying to display them.
// if (nativeAd.body == null) {
// unifiedAdBinding.adBody.visibility = View.INVISIBLE
// } else {
// unifiedAdBinding.adPrice.visibility = View.VISIBLE
// unifiedAdBinding.adPrice.text = nativeAd.price
// unifiedAdBinding.adBody.visibility = View.VISIBLE
// unifiedAdBinding.adBody.text = nativeAd.body
// }
//
// if (nativeAd.store == null) {
// unifiedAdBinding.adStore.visibility = View.INVISIBLE
// if (nativeAd.callToAction == null) {
// unifiedAdBinding.adCallToAction.visibility = View.INVISIBLE
// } else {
// unifiedAdBinding.adStore.visibility = View.VISIBLE
// unifiedAdBinding.adStore.text = nativeAd.store
// unifiedAdBinding.adCallToAction.visibility = View.VISIBLE
// unifiedAdBinding.adCallToAction.text = nativeAd.callToAction
// }
//
// if (nativeAd.icon == null) {
// unifiedAdBinding.adAppIcon.visibility = View.GONE
// } else {
// unifiedAdBinding.adAppIcon.setImageDrawable(nativeAd.icon?.drawable)
// unifiedAdBinding.adAppIcon.visibility = View.VISIBLE
// }
//
//// if (nativeAd.price == null) {
//// unifiedAdBinding.adPrice.visibility = View.INVISIBLE
//// } else {
//// unifiedAdBinding.adPrice.visibility = View.VISIBLE
//// unifiedAdBinding.adPrice.text = nativeAd.price
//// }
////
//// if (nativeAd.store == null) {
//// unifiedAdBinding.adStore.visibility = View.INVISIBLE
//// } else {
//// unifiedAdBinding.adStore.visibility = View.VISIBLE
//// unifiedAdBinding.adStore.text = nativeAd.store
//// }
//
// if (nativeAd.starRating == null) {
// unifiedAdBinding.adStars.visibility = View.INVISIBLE
// } else {
// unifiedAdBinding.adStars.rating = nativeAd.starRating!!.toFloat()
// unifiedAdBinding.adStars.visibility = View.VISIBLE
// }
//
// if (nativeAd.advertiser == null) {
// unifiedAdBinding.adAdvertiser.visibility = View.INVISIBLE
// } else {
// unifiedAdBinding.adAdvertiser.text = nativeAd.advertiser
// unifiedAdBinding.adAdvertiser.visibility = View.VISIBLE
// }
//
// // This method tells the Google Mobile Ads SDK that you have finished populating your
// // native ad view with this native ad.
// nativeAdView.setNativeAd(nativeAd)
// }
//
// override fun onDestroyView() {
// super.onDestroyView()
// // 销毁广告,避免内存泄漏
// NativeAdCache.clear()
// }
if (nativeAd.starRating == null) {
unifiedAdBinding.adStars.visibility = View.INVISIBLE
} else {
unifiedAdBinding.adStars.rating = nativeAd.starRating!!.toFloat()
unifiedAdBinding.adStars.visibility = View.VISIBLE
}
if (nativeAd.advertiser == null) {
unifiedAdBinding.adAdvertiser.visibility = View.INVISIBLE
} else {
unifiedAdBinding.adAdvertiser.text = nativeAd.advertiser
unifiedAdBinding.adAdvertiser.visibility = View.VISIBLE
}
// This method tells the Google Mobile Ads SDK that you have finished populating your
// native ad view with this native ad.
nativeAdView.setNativeAd(nativeAd)
}
override fun onDestroyView() {
super.onDestroyView()
// 销毁广告,避免内存泄漏
NativeAdCache.clear()
}
}

View File

@ -1,113 +0,0 @@
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:minHeight="50dp"
android:orientation="vertical">
<TextView style="@style/AdAttribution" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingTop="3dp"
android:paddingRight="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:adjustViewBounds="true"
android:paddingEnd="5dp"
android:paddingRight="5dp"
android:paddingBottom="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#0000FF"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/ad_advertiser"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="bottom"
android:textSize="14sp"
android:textStyle="bold" />
<RatingBar
android:id="@+id/ad_stars"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:textSize="12sp" />
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_media"
android:layout_width="match_parent"
android:layout_height="175dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:orientation="horizontal"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<Button
android:id="@+id/ad_call_to_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/bg_color"
android:gravity="center"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>

View File

@ -23,9 +23,19 @@ dependencyResolutionManagement {
flatDir {
dirs("libs")
}
// TradPlus
mavenCentral()
// Ironsource
maven("https://android-sdk.is.com/")
// Pangle
maven("https://artifact.bytedance.com/repository/pangle")
// Mintegral
//Launch GP market application Android X Version
//If you fail to pull the code using gradle, add the maven warehouse configuration to the project root build.gradle file
maven("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea")
}
}
rootProject.name = "PDF Reader Pro"
include(":app")