Commit 7c842ceb authored by wanglei's avatar wanglei

...

parent 895d920d
......@@ -79,7 +79,5 @@ dependencies {
implementation("com.google.firebase:firebase-crashlytics")
//facebook
// implementation("com.facebook.android:facebook-android-sdk:[8,9)")
// implementation("com.facebook.android:facebook-android-sdk:[9,10)")
// implementation("com.facebook.android:facebook-android-sdk:16.0.0")
implementation("com.facebook.android:facebook-android-sdk:[8,9)")
}
\ No newline at end of file
package com.base.locationsharewhite.ads
import android.animation.ObjectAnimator
import android.animation.ValueAnimator.INFINITE
import android.app.AlertDialog
import android.content.Context
import android.view.LayoutInflater
import android.view.animation.LinearInterpolator
import com.base.locationsharewhite.R
import com.base.locationsharewhite.databinding.DialogAdPreparingBinding
object AdDialog {
fun Context.showAdPreparingDialog(): AlertDialog {
val binding = DialogAdPreparingBinding.inflate(LayoutInflater.from(this))
val dialog = AlertDialog.Builder(this).create()
dialog.setView(binding.root)
dialog.setCancelable(false)
dialog.setCanceledOnTouchOutside(false)
dialog.show()
val params = dialog.window?.attributes
params?.width = resources.getDimensionPixelOffset(R.dimen.dp_200)
params?.height = resources.getDimensionPixelOffset(R.dimen.dp_146)
dialog.window?.attributes = params
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
// 创建一个旋转动画
val rotateAnimator = ObjectAnimator.ofFloat(binding.iv, "rotation", 0f, -360f)
rotateAnimator.setDuration(1000) // 设置动画持续时间为1000毫秒
rotateAnimator.repeatCount = INFINITE
rotateAnimator.interpolator = LinearInterpolator() // 设置插值器为线性插值
rotateAnimator.start()
return dialog
}
}
\ No newline at end of file
package com.base.pdfreader2.ads
import com.base.locationsharewhite.helper.EventUtils
import com.base.locationsharewhite.utils.AppPreferences
import com.base.locationsharewhite.utils.LogEx
import com.base.pdfreader2.ads.AdmobHelper.inter_limit_click
import com.base.pdfreader2.ads.AdmobHelper.inter_limit_request
import com.base.pdfreader2.ads.AdmobHelper.inter_limit_show
import com.base.pdfreader2.ads.AdmobHelper.native_limit_request
import com.base.pdfreader2.ads.AdmobHelper.native_limit_show
import com.base.pdfreader2.ads.AdmobHelper.open_limit_click
import com.base.pdfreader2.ads.AdmobHelper.open_limit_request
import com.base.pdfreader2.ads.AdmobHelper.open_limit_show
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
object AdDisplayUtils {
//region open
private val open_max_request = AppPreferences.getInstance().getString(open_limit_request, "15").toInt()
private val open_max_show = AppPreferences.getInstance().getString(open_limit_show, "10").toInt()
private val open_max_click = AppPreferences.getInstance().getString(open_limit_click, "1").toInt()
fun incrementOpenRequestCount() {
currentOpenRequest += 1
}
fun incrementOpenShow() {
currentOpenShow += 1
}
fun incrementClickShow() {
currentOpenClick += 1
}
//当前开屏请求次数
private var currentOpenRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenRequest_${currentDate()}", value, true)
}
//当前开屏展示次数
private var currentOpenShow = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenShow_${currentDate()}", value, true)
}
//当前开屏点击次数
private var currentOpenClick = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenClick_${currentDate()}", value, true)
}
fun shouldShowOpenAd(): Boolean {
if (currentOpenRequest > open_max_request) {
LogEx.logDebug(TAG, "currentOpenRequest=$currentOpenRequest open_max_request=$open_max_request")
EventUtils.event("ad_limit", "currentOpenRequest=$currentOpenRequest open_max_request=$open_max_request")
return false
}
if (currentOpenShow > open_max_show) {
LogEx.logDebug(TAG, "currentOpenShow=$currentOpenShow open_max_show=$open_max_show")
EventUtils.event("ad_limit", "currentOpenShow=$currentOpenShow open_max_show=$open_max_show")
return false
}
if (currentOpenClick > open_max_click) {
LogEx.logDebug(TAG, "currentOpenClick=$currentOpenClick open_max_click=$open_max_click")
EventUtils.event("ad_limit", "currentOpenClick=$currentOpenClick open_max_click=$open_max_click")
return false
}
return true
}
//endregion
//region inter
private val inter_max_request = AppPreferences.getInstance().getString(inter_limit_request, "15").toInt()
private val inter_max_show = AppPreferences.getInstance().getString(inter_limit_show, "10").toInt()
private val inter_max_click = AppPreferences.getInstance().getString(inter_limit_click, "1").toInt()
fun incrementInterRequestCount() {
currentInterRequest += 1
}
fun incrementInterShowCount() {
currentInterShow += 1
}
fun incrementInterClickCount() {
currentInterClick += 1
}
//当前插页请求次数
private var currentInterRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentInterRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterRequest_${currentDate()}", value, true)
}
//当前插页展示次数
private var currentInterShow = 0
get() {
return AppPreferences.getInstance().getInt("currentInterShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterShow_${currentDate()}", value, true)
}
//当前插页点击次数
private var currentInterClick = 0
get() {
return AppPreferences.getInstance().getInt("currentInterClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterClick_${currentDate()}", value, true)
}
fun shouldShowInterAd(): Boolean {
if (currentInterRequest > inter_max_request) {
LogEx.logDebug(TAG, "currentInterRequest=$currentInterRequest inter_max_request=$inter_max_request")
EventUtils.event("ad_limit", "currentInterRequest=$currentInterRequest inter_max_request=$inter_max_request")
return false
}
if (currentInterShow > inter_max_show) {
LogEx.logDebug(TAG, "currentInterShow=$currentInterShow inter_max_show=$inter_max_show")
EventUtils.event("ad_limit", "currentInterShow=$currentInterShow inter_max_show=$inter_max_show")
return false
}
if (currentInterClick > inter_max_click) {
LogEx.logDebug(TAG, "currentInterClick=$currentInterClick inter_max_click=$inter_max_click")
EventUtils.event("ad_limit", "currentInterClick=$currentInterClick inter_max_click=$inter_max_click")
return false
}
return true
}
//endregion
//region native
private val native_max_request = AppPreferences.getInstance().getString(native_limit_request, "15").toInt()
private val native_max_show = AppPreferences.getInstance().getString(native_limit_show, "10").toInt()
private val native_max_click = AppPreferences.getInstance().getString(native_limit_show, "1").toInt()
fun incrementNativeRequestCount() {
currentNativeRequest += 1
}
fun incrementNativeShowCount() {
currentNativeShow += 1
}
fun incrementNativeClickCount() {
currentNativeClick += 1
}
private var currentNativeRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeRequest_${currentDate()}", value, true)
}
private var currentNativeShow = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeShow_${currentDate()}", value, true)
}
private var currentNativeClick = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeClick_${currentDate()}", value, true)
}
fun shouldShowNative(): Boolean {
if (currentNativeRequest > native_max_request) {
LogEx.logDebug(TAG, "currentNativeRequest=$currentNativeRequest native_max_request=$native_max_request")
EventUtils.event("ad_limit", "currentNativeRequest=$currentNativeRequest native_max_request=$native_max_request")
return false
}
if (currentNativeShow > native_max_show) {
LogEx.logDebug(TAG, "currentNativeShow=$currentNativeShow native_max_show=$native_max_show")
EventUtils.event("ad_limit", "currentNativeShow=$currentNativeShow native_max_show=$native_max_show")
return false
}
if (currentNativeClick > native_max_click) {
LogEx.logDebug(TAG, "currentNativeClick=$currentNativeClick native_max_click=$native_max_click")
EventUtils.event("ad_limit", "currentNativeClick=$currentNativeClick native_max_click=$native_max_click")
return false
}
return true
}
//endregion
private val TAG = "AdDisplayUtils"
private fun currentDate(): String {
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val currentDate = Calendar.getInstance().time
return dateFormat.format(currentDate)
}
}
package com.base.pdfreader2.ads
import android.app.Activity
import com.base.locationsharewhite.ads.admob.AdmobInterstitialUtils
import com.base.locationsharewhite.ads.admob.AdmobNativeUtils
import com.base.pdfreader2.helper.EventUtils
import com.base.pdfreader2.helper.MyApplication
import com.base.pdfreader2.utils.AppPreferences
import com.google.android.gms.ads.MobileAds
import java.util.concurrent.atomic.AtomicBoolean
object AdmobHelper {
//开屏限制
const val open_limit_request = "open_limit_request"
const val open_limit_show = "open_limit_show"
const val open_limit_click = "open_limit_click"
//插页限制
const val inter_limit_request = "inter_limit_request"
const val inter_limit_show = "inter_limit_show"
const val inter_limit_click = "inter_limit_click"
//原生广告限制
const val native_limit_request = "native_limit_request"
const val native_limit_show = "native_limit_show"
const val native_limit_click = "native_limit_click"
//是否展示多语言
val showLanPage = "showLanPage"
//开屏加载ad时间
val open_ad_loading = "open_ad_loading"
//创建pdf加载ad时间
val create_pdf_loading = "create_pdf_loading"
//删除文件
val delete_loading = "delete_loading"
//打开文件
val open_file_loading = "open_file_loading"
//合并pdf
val merge_loading = "merge_loading"
//拆分pdf
val split_loading = "split_loading"
//可请求时间段(由 x 定义)
const val ad_request_period = "ad_request_interval"
//可请求时间段内允许的最大请求数(由 y 定义)
const val ad_period_max_request = "ad_period_max_request"
//可请求时间段间隔时间
const val ad_request_period_interval = "ad_request_period_interval"
var isAdInit = AtomicBoolean(false)
fun initAdmobAd(activity: Activity) {
MobileAds.initialize(MyApplication.context) { initializationStatus ->
isAdInit.set(true)
EventUtils.event("AdmobInit", "AdmobInit")
AdmobNativeUtils.loadNativeAd()
AdmobInterstitialUtils.loadInterstitialAd(activity)
}
}
//上次展示广告时间关闭赋值,通用开屏和插页
var lastShowedOnHiddenTime = 0L
get() {
return AppPreferences.getInstance().getLong("lastShowedOnHiddenTime", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastShowedOnHiddenTime", value, true)
}
/**
* 通用广告条件判断
*/
fun canCommonShowAd(): Boolean {
val interval = AppPreferences.getInstance().getString("ad_interval", "10").toInt()
if (System.currentTimeMillis() - lastShowedOnHiddenTime < interval * 1000L) {
return false
}
return true
}
//上次scan展示ad时间
var lastScanShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastScanShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastScanShowAd", value, true)
}
//是否显示扫描功能ad
fun isShowScanInter(): Boolean {
val interval = AppPreferences.getInstance().getString("scan_ad_interval", "10").toInt()
return System.currentTimeMillis() - lastScanShowAd > interval * 1000L
}
//上次打开文档展示ad时间
var lastOpenDocumentShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastOpenDocumentShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastOpenDocumentShowAd", value, true)
}
//打开文档是否展示广告
fun isShowOpenDocumentInter(): Boolean {
val interval = AppPreferences.getInstance().getString("open_document_ad_interval", "10").toInt()
val openStatus = AppPreferences.getInstance().getString("open_document_ad_status", "1").toInt()
return openStatus == 1 && System.currentTimeMillis() - lastOpenDocumentShowAd > interval * 1000L
}
var lastCloseDocumentShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastCloseDocumentShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastCloseDocumentShowAd", value, true)
}
fun isShowCloseDocumentInter(): Boolean {
val interval = AppPreferences.getInstance().getString("close_document_ad_interval", "10").toInt()
return System.currentTimeMillis() - lastCloseDocumentShowAd > interval * 1000L
}
fun isShowCloseDocument(): Boolean {
val status = AppPreferences.getInstance().getString("close_document_ad_show", "0").toInt()
return status == 1
}
fun isShowRvNativeAd(): Boolean {
val status = AppPreferences.getInstance().getString("rv_native_ad_show", "0").toInt()
return status == 1
}
fun isBackShowAd(): Boolean {
val status = AppPreferences.getInstance().getString("is_back_show_ad", "0").toInt()
return status == 1
}
}
\ No newline at end of file
package com.base.locationsharewhite.ads
/**
* 广告限制配置
*
* @property isInBlackList 是否在黑名单
* @property numDisplayLimit 展示次数限制
* @property numRequestLimit 请求次数限制
* @property numClickLimit 点击次数限制
* @property timeInterval 广告间隔时间
*/
class AdsConfigBean(
val isInBlackList: Boolean,
val numDisplayLimit: Int,
val numRequestLimit: Int,
val numClickLimit: Int,
val timeInterval: Int
)
\ No newline at end of file
package com.base.locationsharewhite.ads
import android.app.Activity
import android.content.Context
import android.view.ViewGroup
import com.base.locationsharewhite.ads.admob.AdBannerMgr
import com.base.locationsharewhite.ads.admob.AdInsertMgr
import com.base.locationsharewhite.ads.admob.AdNativeMgr
import com.base.locationsharewhite.ads.admob.AdOpenMgr
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.initialization.AdapterStatus
/**
* 广告管理类
*/
object AdsMgr {
private val adOpenMgr by lazy {
AdOpenMgr()
}
private val adInsertMgr by lazy {
AdInsertMgr()
}
private val adNativeMgr by lazy {
AdNativeMgr()
}
private val adBannerMgr by lazy {
AdBannerMgr()
}
/**
* 是否初始化
*/
var isInit = false
private set
/**
* 广告配置项目
*/
var adsConfigBean: AdsConfigBean? = null
private set
/**
* Init 初始化
*
* @param context 这里最好是appContext,因为是耗时操作,等它初始化完毕马上加载开屏和插屏广告
*/
fun init(context: Context, adsConfigBean: AdsConfigBean) {
if (adsConfigBean.isInBlackList) return
this.adsConfigBean = adsConfigBean
MobileAds.initialize(context) {
val readyAdapter = it.adapterStatusMap.entries.find { entry ->
entry.value.initializationState == AdapterStatus.State.READY
}
isInit = readyAdapter != null
if (isInit) {
//成功初始化就提前预加载开屏广告和插页广告
adOpenMgr.loadAd(context)
adInsertMgr.loadAd(context)
}
}
}
fun showOpen(activity: Activity, showCallBack: AdsShowCallBack? = null) {
if (!isInit || adsConfigBean?.isInBlackList != false) {
showCallBack?.failed()
return
}
adOpenMgr.show(activity, showCallBack)
}
fun showInsert(activity: Activity, showCallBack: AdsShowCallBack? = null) {
if (!isInit || adsConfigBean?.isInBlackList != false) {
showCallBack?.failed()
return
}
adInsertMgr.show(activity, showCallBack)
}
fun showNative(parent: ViewGroup, layout: Int) {
if (!isInit || adsConfigBean?.isInBlackList != false) return
adNativeMgr.show(parent, layout)
}
fun showBanner(parent: ViewGroup) {
if (!isInit || adsConfigBean?.isInBlackList != false) return
adBannerMgr.show(parent)
}
}
\ No newline at end of file
package com.base.locationsharewhite.ads
abstract class AdsShowCallBack {
open fun show() {}
abstract fun close()
abstract fun failed()
}
\ No newline at end of file
package com.base.locationsharewhite.ads
/**
* 广告类型
* 0=开屏广告、1=插屏广告、2=原生广告、3=Banner横幅广告
*/
@JvmInline
value class AdsType private constructor(val value: Int) {
companion object {
val OPEN = AdsType(0)
val INSERT = AdsType(1)
val NATIVE = AdsType(2)
val BANNER = AdsType(3)
fun from(adsType: Int): AdsType {
return when (adsType) {
OPEN.value -> OPEN
INSERT.value -> INSERT
NATIVE.value -> NATIVE
else -> BANNER
}
}
}
}
\ No newline at end of file
package com.base.locationsharewhite.ads
import android.app.Activity
import android.content.Context
import java.lang.ref.WeakReference
/**
* 特定广告管理基类
* @param T 缓存广告的类
*/
abstract class BaseAdMgr<T> {
/**
* 广告展示回调
*/
protected var showCallBack: AdsShowCallBack? = null
/**
* 当前缓存的广告
*/
protected var currentAd: T? = null
/**
* 是否正在缓存加载广告
*/
protected var loadingAd: Boolean = false
/**
* 是否正在显示广告
*/
protected var showingAd: Boolean = false
/**
* 用于保存引用现有页面,在此页面显示广告(因为要等待广告加载完毕)
*/
protected var activityRef: WeakReference<Activity>? = null
/**
* 上一次的缓存成功时间
*/
protected var lastTime: Long = 0
/**
* 预加载广告
*
* @param context 加载所用的上下文,一般使用appContext
*/
abstract fun loadAd(context: Context)
/**
* 广告显示
*
* @param activity 当前页面
*/
abstract fun show(activity: Activity, showCallBack: AdsShowCallBack? = null)
/**
* 预加载的缓存超时判断
*
* @return true:没有超时 false:超时需要重新加载
*/
abstract fun adAvailable(): Boolean
}
\ No newline at end of file
package com.base.locationsharewhite.ads.admob
import android.app.Activity
import android.content.Context
import com.base.locationsharewhite.BuildConfig
import com.base.locationsharewhite.ads.AdsShowCallBack
import com.base.locationsharewhite.ads.BaseAdMgr
import com.base.locationsharewhite.helper.ConfigHelper
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import java.lang.ref.WeakReference
/**
*插屏广告加载显示管理类
*/
class AdInsertMgr : BaseAdMgr<InterstitialAd>() {
private var lastOpenDate: Long = 0
private val adLoadCallback = object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) {
super.onAdLoaded(ad)
// 开屏广告加载成功
currentAd = ad
loadingAd = false
lastTime = System.currentTimeMillis()
val ac = activityRef?.get()
if (ac != null) {
show(ac)
}
}
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
super.onAdFailedToLoad(loadAdError)
// 广告加载失败
// 官方不建议在此回调中重新加载广告
// 如果确实需要,则必须限制最大重试次数,避免在网络受限的情况下连续多次请求
loadingAd = false
if (activityRef != null && !showingAd && showCallBack != null) {
showCallBack?.failed()
showCallBack = null
}
}
}
override fun loadAd(context: Context) {
if (!loadingAd && LimitUtils.isAdShow()) {
loadingAd = true
//计数
LimitUtils.addRequestNum()
InterstitialAd.load(
context,
if (BuildConfig.DEBUG) ConfigHelper.interAdmobIdTest else ConfigHelper.interAdmobId,
AdRequest.Builder().build(),
adLoadCallback
)
}
}
override fun show(activity: Activity, showCallBack: AdsShowCallBack?) {
if (activity.isFinishing || activity.isDestroyed || !LimitUtils.isAdShow()|| LimitUtils.isIntervalLimited(
lastOpenDate
)) {
showCallBack?.failed()
return
}
if (showingAd) {
// 开屏广告正在展示
return
}
if (showCallBack != null && this.showCallBack != showCallBack) this.showCallBack =
showCallBack
if (currentAd == null || !adAvailable()) {
//缓存广告过期
currentAd = null
if (activityRef == null) {
activityRef = WeakReference(activity)
// 开屏广告不可用或者缓存超时过期,重新加载
loadAd(activity.applicationContext)
} else {
activityRef = null
this.showCallBack?.failed()
this.showCallBack = null
}
return
}
currentAd?.run {
fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdShowedFullScreenContent() {
super.onAdShowedFullScreenContent()
lastOpenDate = System.currentTimeMillis()
// 广告展示
currentAd = null
activityRef = null
this@AdInsertMgr.showCallBack?.show()
//计数
LimitUtils.addDisplayNum()
}
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
super.onAdFailedToShowFullScreenContent(adError)
// 广告展示失败,清空缓存数据,重新加载
showingAd = false
currentAd = null
activityRef = null
this@AdInsertMgr.showCallBack?.failed()
this@AdInsertMgr.showCallBack = null
}
override fun onAdDismissedFullScreenContent() {
super.onAdDismissedFullScreenContent()
// 广告关闭,清空缓存数据,重新加载
showingAd = false
this@AdInsertMgr.showCallBack?.close()
this@AdInsertMgr.showCallBack = null
loadAd(activity.applicationContext)
}
override fun onAdClicked() {
super.onAdClicked()
//计数
LimitUtils.addClickNum()
}
}
showingAd = true
show(activity)
}
}
override fun adAvailable()=((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < 30
}
\ No newline at end of file
package com.base.locationsharewhite.ads.admob
import android.content.Context
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.base.locationsharewhite.BuildConfig
import com.base.locationsharewhite.helper.ConfigHelper
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
import com.google.android.gms.ads.nativead.NativeAdOptions
import java.util.concurrent.ConcurrentLinkedDeque
/**
*原生广告加载显示管理类
*/
class AdNativeMgr {
/**
* 上一次的缓存成功时间
*/
protected var lastTime: Long = 0
/**
* 原生广告缓存队列
*/
private val cacheItems = ConcurrentLinkedDeque<NativeAd>()
fun loadAd(context: Context, parent: ViewGroup? = null, layout: Int? = null) {
val adLoader = AdLoader.Builder(
context,
if (BuildConfig.DEBUG) ConfigHelper.nativeAdmobIdTest else ConfigHelper.nativeAdmobId
)
.forNativeAd { nativeAd ->
cacheItems.offer(nativeAd)
lastTime = System.currentTimeMillis()
if (parent != null && layout != null) show(parent, layout)
}
.withAdListener(object : AdListener() {
override fun onAdFailedToLoad(error: LoadAdError) {
}
override fun onAdClicked() {
super.onAdClicked()
}
override fun onAdClosed() {
super.onAdClosed()
}
})
.withNativeAdOptions(
NativeAdOptions.Builder()
// .setAdChoicesPlacement(NativeAdOptions.ADCHOICES_TOP_RIGHT)
// .setMediaAspectRatio(NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_SQUARE)
.build()
)
.build()
// Load AdMob native advanced ads
adLoader.loadAds(AdRequest.Builder().build(), 1)
}
fun show(parent: ViewGroup, layout: Int) {
if (!LimitUtils.isAdShow()) {
cacheItems.clear()
return
}
val nativeAd = cacheItems.peek()
if (nativeAd == null || !adAvailable()) {
//缓存过期了就清空
cacheItems.clear()
loadAd(parent.context.applicationContext, parent, layout)
return
}
NativeView(parent.context, layout).run {
parent.removeAllViews()
setNativeAd(nativeAd)
parent.addView(this)
parent.isVisible = true
}
loadAd(parent.context.applicationContext)
}
fun adAvailable(): Boolean {
return ((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < 30
}
}
\ No newline at end of file
package com.base.locationsharewhite.ads.admob
import android.app.Activity
import android.content.Context
import com.base.locationsharewhite.BuildConfig
import com.base.locationsharewhite.ads.AdsShowCallBack
import com.base.locationsharewhite.ads.BaseAdMgr
import com.base.locationsharewhite.helper.ConfigHelper
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.appopen.AppOpenAd
import java.lang.ref.WeakReference
/**
* 开屏广告加载显示管理类
*/
class AdOpenMgr : BaseAdMgr<AppOpenAd>() {
private var lastOpenDate: Long = 0
private val adLoadCallback = object : AppOpenAd.AppOpenAdLoadCallback() {
override fun onAdLoaded(appOpenAd: AppOpenAd) {
super.onAdLoaded(appOpenAd)
// 开屏广告加载成功
currentAd = appOpenAd
loadingAd = false
lastTime = System.currentTimeMillis()
val ac = activityRef?.get()
if (ac != null) {
show(ac)
}
}
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
super.onAdFailedToLoad(loadAdError)
// 开屏广告加载失败
// 官方不建议在此回调中重新加载广告
// 如果确实需要,则必须限制最大重试次数,避免在网络受限的情况下连续多次请求
loadingAd = false
if (activityRef != null && !showingAd && showCallBack != null) {
showCallBack?.failed()
showCallBack = null
}
}
}
override fun loadAd(context: Context) {
if (!loadingAd && LimitUtils.isAdShow()) {
loadingAd = true
//计数
LimitUtils.addRequestNum()
AppOpenAd.load(
context,
if (BuildConfig.DEBUG) ConfigHelper.openAdmobIdTest else ConfigHelper.openAdmobId,
AdRequest.Builder().build(),
adLoadCallback
)
}
}
override fun show(activity: Activity, showCallBack: AdsShowCallBack?) {
if (activity.isFinishing || activity.isDestroyed || !LimitUtils.isAdShow() || LimitUtils.isIntervalLimited(
lastOpenDate
)
) {
showCallBack?.failed()
return
}
if (showingAd) {
// 开屏广告正在展示
return
}
if (showCallBack != null && this.showCallBack != showCallBack) this.showCallBack =
showCallBack
if (currentAd == null || !adAvailable()) {
//缓存广告过期
currentAd = null
if (activityRef == null) {
activityRef = WeakReference(activity)
// 开屏广告不可用或者缓存超时过期,重新加载
loadAd(activity.applicationContext)
} else {
activityRef = null
this.showCallBack?.failed()
this.showCallBack = null
}
return
}
currentAd?.run {
fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdShowedFullScreenContent() {
super.onAdShowedFullScreenContent()
lastOpenDate = System.currentTimeMillis()
// 广告展示
currentAd = null
activityRef = null
this@AdOpenMgr.showCallBack?.show()
//计数
LimitUtils.addDisplayNum()
}
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
super.onAdFailedToShowFullScreenContent(adError)
// 广告展示失败,清空缓存数据,重新加载
showingAd = false
currentAd = null
activityRef = null
this@AdOpenMgr.showCallBack?.failed()
this@AdOpenMgr.showCallBack = null
}
override fun onAdDismissedFullScreenContent() {
super.onAdDismissedFullScreenContent()
// 广告关闭,清空缓存数据,重新加载
showingAd = false
this@AdOpenMgr.showCallBack?.close()
this@AdOpenMgr.showCallBack = null
loadAd(activity.applicationContext)
}
override fun onAdClicked() {
super.onAdClicked()
//计数
LimitUtils.addClickNum()
}
}
showingAd = true
show(activity)
}
}
override fun adAvailable() = ((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < 30
}
\ No newline at end of file
package com.base.locationsharewhite.ads.admob
import android.content.Context
import android.os.Bundle
import android.view.ViewGroup
import android.view.ViewTreeObserver
import com.base.locationsharewhite.BuildConfig
import com.base.locationsharewhite.helper.ConfigHelper
import com.base.locationsharewhite.utils.AppPreferences
import com.base.locationsharewhite.utils.LogEx
import com.google.ads.mediation.admob.AdMobAdapter
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdRequest
......@@ -12,47 +15,43 @@ import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView
import java.util.UUID
/**
*banner广告加载显示管理类
*/
class AdBannerMgr {
object AdmobBannerUtils {
private const val TAG = "AdmobBannerUtils"
private var adView: AdView? = null
private var listener: ViewTreeObserver.OnGlobalLayoutListener? = null
fun show(parent: ViewGroup) {
if (adView != null) {
adView?.destroy()
}
if (!LimitUtils.isAdShow()) {
adView = null
fun showCollapsibleBannerAd(context: Context, parent: ViewGroup, adClose: (() -> Unit)? = null) {
val isShowBanner = AppPreferences.getInstance().getString("isShowBanner", "0").toInt()
if (isShowBanner == 0) {
return
}
adView = AdView(parent.context)
adView?.tag = "CollapsibleBannerAd"
// val list = parent.children
// list.forEach {
// if (it.tag != "zhanweitu") {
// parent.removeView(it)
// }
parent.removeAllViews()
adView?.destroy()
adView = null
adView = AdView(context)
// adView?.apply {
// onPaidEventListener = com.base.locationsharewhite.ads.admob.AdmobEvent.EventOnPaidEventListener(this)
// }
parent.addView(adView)
listener = ViewTreeObserver.OnGlobalLayoutListener {
val screenPixelDensity = parent.context.resources.displayMetrics.density
val screenPixelDensity = context.resources.displayMetrics.density
val adWidth = (parent.width / screenPixelDensity).toInt()
val adSize =
AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(parent.context, adWidth)
adView?.adUnitId =
if (BuildConfig.DEBUG) ConfigHelper.bannerAdmobIdTest else ConfigHelper.bannerAdmobId
val adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, adWidth)
adView?.adUnitId = if (BuildConfig.DEBUG) ConfigHelper.bannerAdmobIdTest else ConfigHelper.bannerAdmobId
adView?.setAdSize(adSize)
loadAd(parent)
loadCollapsibleBanner(adClose)
parent.viewTreeObserver.removeOnGlobalLayoutListener(listener)
}
parent.viewTreeObserver.addOnGlobalLayoutListener(listener)
}
private fun loadCollapsibleBanner(adClose: (() -> Unit)?) {
fun loadAd(parent: ViewGroup) {
val extras = Bundle()
extras.putString("collapsible", "bottom")
extras.putString("collapsible_request_id", UUID.randomUUID().toString())
......@@ -61,27 +60,20 @@ class AdBannerMgr {
adView?.adListener =
object : AdListener() {
override fun onAdLoaded() {
LogEx.logDebug(TAG, "onAdLoaded")
}
override fun onAdOpened() {
LogEx.logDebug(TAG, "onAdOpened")
}
override fun onAdClosed() {
super.onAdClosed()
// val removeList = arrayListOf<View>()
// parent.children.forEach {
// if (it.tag != "CollapsibleBannerAd") {
// removeList.add(it)
// }
// }
// removeList.forEach {
// parent.removeView(it)
// }
LogEx.logDebug(TAG, "onAdClosed")
adClose?.invoke()
}
}
adView?.loadAd(adRequest)
}
}
\ No newline at end of file
package com.base.locationsharewhite.ads.admob
import android.app.Activity
import android.app.Dialog
import android.widget.Toast
import com.base.locationsharewhite.BuildConfig
import com.base.locationsharewhite.ads.admob.AdmobEvent.clickAd
import com.base.locationsharewhite.ads.admob.AdmobEvent.pullAd
import com.base.locationsharewhite.ads.admob.AdmobEvent.showAd
import com.base.locationsharewhite.helper.ConfigHelper
import com.base.locationsharewhite.helper.EventUtils
import com.base.locationsharewhite.helper.MyApplication
import com.base.pdfreader2.ads.AdDialog.showAdPreparingDialog
import com.base.pdfreader2.ads.AdDisplayUtils
import com.base.pdfreader2.ads.AdmobHelper.lastShowedOnHiddenTime
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import org.json.JSONObject
import java.util.UUID
object AdmobInterstitialUtils {
private var interAd: InterstitialAd? = null
private var interLoadTime = Long.MAX_VALUE
private var adLastDisplayTime: Long = 0
private val mRequest = AdRequest.Builder().build()
private fun isAdExpired(): Boolean {
return System.currentTimeMillis() - interLoadTime > 1000 * 60 * 60
}
fun showInterstitialAd(
activity: Activity,
isReLoadAd: Boolean = false,
isShowDialog: Boolean = true,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
if (activity.isFinishing || activity.isDestroyed) {
return
}
if (isAdExpired()) {
val obj2 = JSONObject()
obj2.put("ad_unit", "interAd")
EventUtils.event("ad_expire", ext = obj2)
interAd = null
loadInterstitialAd(activity)
onHidden?.invoke(false)
return
}
if (!AdDisplayUtils.shouldShowInterAd()) {
onHidden?.invoke(false)
return
}
val obj1 = JSONObject()
obj1.put("ad_unit", "interAd")
EventUtils.event("ad_prepare_show", ext = obj1)
if (interAd != null) {
var dialog: Dialog? = null
if (!activity.isFinishing && !activity.isDestroyed) {
dialog = activity.showAdPreparingDialog()
}
displayInterstitialAd(activity, dialog, onHidden)
} else {
showAdDialogAndLoadInterstitial(activity, isReLoadAd, isShowDialog, onHidden)
}
}
fun loadInterstitialAd(activity: Activity, onLoad: (() -> Unit)? = null) {
if (interAd != null) {
onLoad?.invoke()
return
}
if (!AdDisplayUtils.shouldShowInterAd()) {
onLoad?.invoke()
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "interAd")
obj.put("from", activity.javaClass.simpleName)
EventUtils.event("ad_pull_start", ext = obj)
InterstitialAd.load(
activity,
if (BuildConfig.DEBUG) ConfigHelper.interAdmobIdTest else ConfigHelper.interAdmobId,
mRequest,
object : InterstitialAdLoadCallback() {
override fun onAdFailedToLoad(p0: LoadAdError) {
interAd = null
onLoad?.invoke()
pullAd(p0.responseInfo, "interAd", p0.message, reqId = reqId)
if (BuildConfig.DEBUG) {
Toast.makeText(
MyApplication.context, "拉取失败" + p0.message, Toast.LENGTH_SHORT
).show()
}
}
override fun onAdLoaded(ad: InterstitialAd) {
interAd = ad
onLoad?.invoke()
interLoadTime = System.currentTimeMillis()
pullAd(ad.responseInfo, "interAd", reqId = reqId)
ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
AdDisplayUtils.incrementInterRequestCount()
}
})
}
private fun showAdDialogAndLoadInterstitial(
activity: Activity,
isReLoadAd: Boolean,
isShowDialog: Boolean,
onHidden: ((showed: Boolean) -> Unit)?
) {
if (!isShowDialog) {
onHidden?.invoke(false)
return
}
var mDialog: Dialog? = null
if (!activity.isFinishing && !activity.isDestroyed) {
mDialog = activity.showAdPreparingDialog()
mDialog.show()
}
loadInterstitialAd(activity) {
mDialog?.dismiss()
if (!isReLoadAd) {
showInterstitialAd(activity, true, false) {
onHidden?.invoke(it)
}
}
}
if (isReLoadAd) {
mDialog?.dismiss()
onHidden?.invoke(false)
}
}
private fun displayInterstitialAd(
activity: Activity,
dialog: Dialog? = null,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
val thisInterAd = interAd
interAd = null
thisInterAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdClicked() {
clickAd(thisInterAd?.responseInfo, "interAd")
AdDisplayUtils.incrementInterClickCount()
}
override fun onAdDismissedFullScreenContent() {
dialog?.dismiss()
interAd = null
onHidden?.invoke(true)
loadInterstitialAd(activity)
lastShowedOnHiddenTime = System.currentTimeMillis()
}
override fun onAdFailedToShowFullScreenContent(p0: AdError) {
dialog?.dismiss()
interAd = null
onHidden?.invoke(false)
loadInterstitialAd(activity)
}
override fun onAdShowedFullScreenContent() {
dialog?.dismiss()
showAd(thisInterAd?.responseInfo, "interAd", activity)
AdDisplayUtils.incrementInterShowCount()
adLastDisplayTime = System.currentTimeMillis() / 1000
}
}
thisInterAd?.show(activity)
}
fun haveReadAd(): Boolean {
return interAd != null
}
}
\ No newline at end of file
package com.base.locationsharewhite.ads.admob
import android.app.Activity
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.base.locationsharewhite.BuildConfig
import com.base.locationsharewhite.R
import com.base.locationsharewhite.ads.admob.AdmobEvent.clickAd
import com.base.locationsharewhite.ads.admob.AdmobEvent.pullAd
import com.base.locationsharewhite.ads.admob.AdmobEvent.showAd
import com.base.locationsharewhite.helper.ConfigHelper
import com.base.locationsharewhite.helper.EventUtils
import com.base.locationsharewhite.helper.MyApplication
import com.base.locationsharewhite.utils.LogEx
import com.base.pdfreader2.ads.AdDisplayUtils
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
import org.json.JSONObject
import java.util.UUID
object AdmobNativeUtils {
private const val TAG = "AdmobNativeUtils"
private var nativeAd: NativeAd? = null
private var isLoading = false
private var nativeLoadTime = Long.MAX_VALUE
private var loadingListener: (() -> Unit)? = null
private val mRequest = AdRequest.Builder().build()
var onAdLoaded: (() -> Unit)? = null
fun loadNativeAd() {
if (nativeAd != null) {
return
}
if (isLoading) {
return
}
isLoading = true
if (!AdDisplayUtils.shouldShowNative()) {
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "nativeAd")
val adLoader = AdLoader.Builder(
MyApplication.context,
if (BuildConfig.DEBUG) ConfigHelper.nativeAdmobIdTest else ConfigHelper.nativeAdmobId
).forNativeAd {
nativeLoadTime = System.currentTimeMillis()
nativeAd = it
it.setOnPaidEventListener(AdmobEvent.EventOnPaidEventListener(it))
LogEx.logDebug(TAG, "nativeAd=${nativeAd.toString()}")
isLoading = false
loadingListener?.invoke()
loadingListener = null
pullAd(it.responseInfo, "nativeAd", reqId = reqId)
}.withAdListener(object : AdListener() {
override fun onAdLoaded() {
super.onAdLoaded()
onAdLoaded?.invoke()
onAdLoaded = null
AdDisplayUtils.incrementNativeRequestCount()
}
override fun onAdClicked() {
clickAd(nativeAd?.responseInfo, "nativeAd")
AdDisplayUtils.incrementNativeClickCount()
}
override fun onAdFailedToLoad(p0: LoadAdError) {
LogEx.logDebug(TAG, "onAdFailedToLoad=${p0.message}")
nativeAd = null
isLoading = false
pullAd(p0.responseInfo, "nativeAd", p0.message, reqId = reqId)
// Log.e("MXL", "NativeAdFailedToLoad: " + p0.message)
}
}).build()
adLoader.loadAd(mRequest)
}
fun showNativeAd(activity: Activity?, parent: ViewGroup, layout: Int = R.layout.layout_admob_native_custom) {
val obj = JSONObject()
obj.put("ad_unit", "nativeAd")
EventUtils.event("ad_prepare_show_native", ext = obj)
if (!AdDisplayUtils.shouldShowNative()) {
return
}
loadingListener = {
if (System.currentTimeMillis() - nativeLoadTime <= 1000 * 60 * 60) {
nativeAd?.let {
NativeView(parent.context, layout).run {
parent.removeAllViews()
setNativeAd(it)
parent.addView(this)
parent.isVisible = true
showAd(nativeAd?.responseInfo, "nativeAd", activity)
}
}
}
nativeAd = null
loadNativeAd()
}
if (nativeAd == null) {
loadNativeAd()
val obj2 = JSONObject()
obj2.put("reason", "no_ad")
obj2.put("ad_unit", "nativeAd")
EventUtils.event("ad_show_error", ext = obj2)
} else {
loadingListener?.invoke()
loadingListener = null
}
}
fun showReadyNativeAd(
activity: Activity?,
readyNativeAd: NativeAd?,
parent: ViewGroup,
layout: Int = R.layout.layout_admob_native_custom
) {
readyNativeAd?.let {
NativeView(parent.context, layout).run {
parent.removeAllViews()
setNativeAd(it)
parent.addView(this)
parent.isVisible = true
showAd(nativeAd?.responseInfo, "nativeAd", activity)
}
}
}
fun onDestroy() {
nativeAd?.destroy()
nativeAd = null
}
}
\ No newline at end of file
package com.base.locationsharewhite.ads.admob
import android.app.Activity
import com.base.locationsharewhite.BuildConfig
import com.base.locationsharewhite.ads.admob.AdmobEvent.clickAd
import com.base.locationsharewhite.ads.admob.AdmobEvent.pullAd
import com.base.locationsharewhite.ads.admob.AdmobEvent.showAd
import com.base.locationsharewhite.helper.ConfigHelper
import com.base.locationsharewhite.helper.EventUtils
import com.base.locationsharewhite.helper.MyApplication
import com.base.locationsharewhite.utils.LogEx
import com.base.pdfreader2.ads.AdDisplayUtils
import com.base.pdfreader2.ads.AdmobHelper.lastShowedOnHiddenTime
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.appopen.AppOpenAd
import org.json.JSONObject
import java.util.UUID
object AdmobOpenUtils {
private const val TAG = "AdmobOpenUtils"
private val mRequest = AdRequest.Builder().build()
private var openLoadTime = Long.MAX_VALUE
private var mOpenAd: AppOpenAd? = null
private fun isAdExpired(): Boolean {
return System.currentTimeMillis() - openLoadTime > 1000 * 60 * 60
}
fun haveReadAd(): Boolean {
return mOpenAd != null
}
fun loadAppOpenAd(onLoad: ((loaded: Boolean) -> Unit)? = null) {
if (mOpenAd != null) {
onLoad?.invoke(true)
return
}
if (!AdDisplayUtils.shouldShowOpenAd()) {
onLoad?.invoke(false)
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "openAd")
EventUtils.event("ad_pull_start", ext = obj)
AppOpenAd.load(
MyApplication.context,
if (BuildConfig.DEBUG) ConfigHelper.openAdmobIdTest else ConfigHelper.openAdmobId,
mRequest,
object : AppOpenAd.AppOpenAdLoadCallback() {
override fun onAdLoaded(ad: AppOpenAd) {
LogEx.logDebug(TAG, "onAdLoaded")
openLoadTime = System.currentTimeMillis()
mOpenAd = ad
onLoad?.invoke(true)
pullAd(ad.responseInfo, "openAd", reqId = reqId)
ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
AdDisplayUtils.incrementOpenRequestCount()
}
override fun onAdFailedToLoad(p0: LoadAdError) {
LogEx.logDebug(TAG, "LoadAdError ${p0.message}")
mOpenAd = null
onLoad?.invoke(false)
pullAd(p0.responseInfo, "openAd", p0.message, reqId = reqId)
}
})
}
fun showAppOpenAd(
activity: Activity,
isRetry: Boolean = false,
showBefore: ((flag: Boolean) -> Unit)? = null,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
if (activity.isFinishing || activity.isDestroyed) {
LogEx.logDebug(TAG, "activity isDestroyed")
return
}
if (!AdDisplayUtils.shouldShowOpenAd()) {
onHidden?.invoke(false)
return
}
if (isAdExpired()) {
LogEx.logDebug(TAG, "openLoadTime out time")
mOpenAd = null
loadAppOpenAd()
onHidden?.invoke(false)
val obj2 = JSONObject()
obj2.put("ad_unit", "openAd")
EventUtils.event("ad_expire", ext = obj2)
return
}
if (!isRetry) {
val obj1 = JSONObject()
obj1.put("ad_unit", "openAd")
EventUtils.event("ad_prepare_show", ext = obj1)
LogEx.logDebug(TAG, "open ad_prepare_show")
}
if (mOpenAd != null) {
LogEx.logDebug(TAG, "mOpenAd!=null")
val thisMOpenAd = mOpenAd
mOpenAd = null
thisMOpenAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdClicked() {
clickAd(thisMOpenAd?.responseInfo, "openAd")
AdDisplayUtils.incrementClickShow()
}
override fun onAdDismissedFullScreenContent() {
mOpenAd = null
onHidden?.invoke(true)
loadAppOpenAd()
lastShowedOnHiddenTime = System.currentTimeMillis()
}
override fun onAdFailedToShowFullScreenContent(p0: AdError) {
mOpenAd = null
onHidden?.invoke(false)
loadAppOpenAd()
val obj = JSONObject()
obj.put("reason", p0.message)
obj.put("code", p0.code)
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
}
override fun onAdShowedFullScreenContent() {
showBefore?.invoke(true)
showAd(thisMOpenAd?.responseInfo, "openAd", activity)
AdDisplayUtils.incrementOpenShow()
}
}
thisMOpenAd?.show(activity)
} else {
LogEx.logDebug(TAG, "mOpenAd=null")
loadAppOpenAd {
if (mOpenAd != null) {
showAppOpenAd(activity, true, showBefore, onHidden)
} else {
val obj = JSONObject()
obj.put("reason", "no_ad")
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
onHidden?.invoke(false)
}
}
}
}
}
\ No newline at end of file
package com.base.locationsharewhite.ads.admob
import com.base.locationsharewhite.ads.AdsMgr
import com.base.locationsharewhite.utils.AppPreferences
import com.base.locationsharewhite.utils.KotlinExt.toFormatTime4
/**
* 控制广告计数与判断显示条件
*
*/
object LimitUtils {
const val NUM_DISPLAY = "numDisplayLimit"
const val NUM_REQUEST = "numRequestLimit"
const val NUM_CLICK = "numClickLimit"
const val SAVE_DATE = "SAVE_DATE"
/**
* 保存的时间,用来判断是否是当天,不是当天要重置计数次数
*/
private var saveDate
get() = AppPreferences.getInstance()
.getString(SAVE_DATE, System.currentTimeMillis().toFormatTime4())
set(value) = AppPreferences.getInstance().put(SAVE_DATE, value)
/**
* 广告请求是否到达限制
*/
private inline val isRequestLimited: Boolean
get() {
return AppPreferences.getInstance()
.getInt(NUM_REQUEST, 0) >= (AdsMgr.adsConfigBean?.numRequestLimit ?: 100)
}
/**
* 广告展示是否到达限制
*/
private inline val isDisplayLimited: Boolean
get() {
return AppPreferences.getInstance()
.getInt(NUM_DISPLAY, 0) >= (AdsMgr.adsConfigBean?.numDisplayLimit ?: 100)
}
/**
* 广告点击是否到达限制
*/
private inline val isClickLimited: Boolean
get() {
return AppPreferences.getInstance()
.getInt(NUM_CLICK, 0) >= (AdsMgr.adsConfigBean?.numClickLimit ?: 100)
}
/**
* 是否显示广告
*
* @return true or false
*/
fun isAdShow(): Boolean {
val currentDate = System.currentTimeMillis().toFormatTime4()
if (saveDate != currentDate) {
//如果已经不是今天了,就重置个数
saveDate = currentDate
AppPreferences.getInstance().put(NUM_DISPLAY, 0)
AppPreferences.getInstance().put(NUM_REQUEST, 0)
AppPreferences.getInstance().put(NUM_CLICK, 0)
}
return !(isDisplayLimited || isClickLimited || isRequestLimited)
}
private fun addNum(key: String) {
val currentDate = System.currentTimeMillis().toFormatTime4()
if (saveDate != currentDate) {
//如果已经不是今天了,就重置个数
saveDate = currentDate
AppPreferences.getInstance().put(key, 1)
return
}
AppPreferences.getInstance()
.put(key, (AppPreferences.getInstance().getInt(key, 0) + 1))
}
fun addDisplayNum() {
addNum(NUM_DISPLAY)
}
fun addRequestNum() {
addNum(NUM_REQUEST)
}
fun addClickNum() {
addNum(NUM_CLICK)
}
/**
* 开屏和插页广告的显示间隔限制
*
* @param lastTime 上一次显示的时间
*/
fun isIntervalLimited(lastTime: Long) =
((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < (AdsMgr.adsConfigBean?.timeInterval
?: 1)
}
\ No newline at end of file
......@@ -15,12 +15,10 @@ import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.nativead.NativeAdView
@SuppressLint("ViewConstructor")
class NativeView(context: Context, val layout: Int, attrs: AttributeSet? = null) :
FrameLayout(context, attrs) {
class NativeView(context: Context, val layout: Int, attrs: AttributeSet? = null) : FrameLayout(context, attrs) {
init {
layoutParams =
LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
fun setNativeAd(nativeAd: NativeAd?) {
......@@ -29,32 +27,35 @@ class NativeView(context: Context, val layout: Int, attrs: AttributeSet? = null)
val adView = LayoutInflater.from(context)
.inflate(layout, this, false) as NativeAdView
// runCatching {
// adView.advertiserView = adView.findViewById(R.id.ad_advertiser)
// }
adView.mediaView = adView.findViewById(R.id.ad_media)
adView.headlineView = adView.findViewById(R.id.ad_headline)
adView.bodyView = adView.findViewById(R.id.ad_body)
adView.callToActionView = adView.findViewById(R.id.ad_call_to_action)
adView.iconView = adView.findViewById(R.id.ad_app_icon)
(adView.headlineView as TextView?)?.text = nativeAd.headline
adView.mediaView!!.mediaContent = nativeAd.mediaContent
adView.mediaView?.mediaContent = nativeAd.mediaContent
if (nativeAd.body == null) {
adView.bodyView!!.visibility = View.INVISIBLE
adView.bodyView?.visibility = View.INVISIBLE
} else {
adView.bodyView!!.visibility = View.VISIBLE
adView.bodyView?.visibility = View.VISIBLE
(adView.bodyView as TextView?)?.text = nativeAd.body
}
if (nativeAd.callToAction == null) {
adView.callToActionView!!.visibility = View.INVISIBLE
adView.callToActionView?.visibility = View.INVISIBLE
} else {
adView.callToActionView!!.visibility = View.VISIBLE
adView.callToActionView?.visibility = View.VISIBLE
(adView.callToActionView as Button?)?.text = nativeAd.callToAction
}
if (nativeAd.icon == null) {
adView.iconView!!.visibility = View.GONE
adView.iconView?.visibility = View.GONE
} else {
(adView.iconView as ImageView?)?.setImageDrawable(
nativeAd.icon!!.drawable
nativeAd.icon?.drawable
)
adView.iconView!!.visibility = View.VISIBLE
adView.iconView?.visibility = View.VISIBLE
}
adView.setNativeAd(nativeAd)
......
......@@ -16,7 +16,7 @@ import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import androidx.core.graphics.drawable.IconCompat
import com.base.locationsharewhite.R
import com.base.locationsharewhite.bean.ConstObject
import com.base.locationsharewhite.fcm.PopupConstObject
import com.base.locationsharewhite.helper.EventUtils
import com.base.locationsharewhite.helper.MyApplication
import com.base.locationsharewhite.ui.main.MainActivity
......@@ -68,7 +68,7 @@ class StayNotificationService : Service() {
val requestCode1 = Random.nextInt(1800)
val intent1 = Intent(context, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.NOTIFICATION_ACTION_HOME)
putExtra("actionId", PopupConstObject.NOTIFICATION_ACTION_HOME)
}
val pendingIntent1 =
PendingIntent.getActivity(
......@@ -82,7 +82,7 @@ class StayNotificationService : Service() {
val requestCode2 = Random.nextInt(1800)
val intent2 = Intent(context, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.NOTIFICATION_ACTION_MY_CODE)
putExtra("actionId", PopupConstObject.NOTIFICATION_ACTION_MY_CODE)
}
val pendingIntent2 =
PendingIntent.getActivity(
......@@ -96,7 +96,7 @@ class StayNotificationService : Service() {
val requestCode3 = Random.nextInt(1800)
val intent3 = Intent(context, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.NOTIFICATION_ACTION_SHARE)
putExtra("actionId", PopupConstObject.NOTIFICATION_ACTION_SHARE)
}
val pendingIntent3 =
PendingIntent.getActivity(
......@@ -111,7 +111,7 @@ class StayNotificationService : Service() {
val requestCode4 = Random.nextInt(1800)
val intent4 = Intent(context, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.NOTIFICATION_ACTION_SETTINGS)
putExtra("actionId", PopupConstObject.NOTIFICATION_ACTION_SETTINGS)
}
val pendingIntent4 =
PendingIntent.getActivity(
......
......@@ -9,6 +9,10 @@ import androidx.activity.addCallback
import androidx.core.view.updatePadding
import com.base.locationsharewhite.R
import com.base.locationsharewhite.databinding.ActivityMainBinding
import com.base.locationsharewhite.fcm.PopupConstObject
import com.base.locationsharewhite.fcm.PopupConstObject.NOTIFICATION_ACTION_MY_CODE
import com.base.locationsharewhite.fcm.PopupConstObject.NOTIFICATION_ACTION_SETTINGS
import com.base.locationsharewhite.fcm.PopupConstObject.NOTIFICATION_ACTION_SHARE
import com.base.locationsharewhite.helper.BaseActivity
import com.base.locationsharewhite.helper.MyApplication
import com.base.locationsharewhite.location.LocationLoginUtils
......@@ -39,6 +43,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), OnMapReadyCallback {
private var map: GoogleMap? = null
private lateinit var mainPresenter: MainPresenter
private var marker: Marker? = null
private var actionId: String = ""
override fun initView() {
LogEx.logDebug(TAG, "initView")
......@@ -51,6 +56,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), OnMapReadyCallback {
}
mainPresenter = MainPresenter(this)
actionId = intent.extras?.getString("actionId", "") ?: ""
LogEx.logDebug(TAG, "initView actionId=$actionId", true)
if (!checkLocationPermission()) {
launcher.launch(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION)) {
......@@ -107,7 +114,25 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), OnMapReadyCallback {
binding.flSettings.setOnClickListener {
startActivity(Intent(this, SettingActivity::class.java))
}
actionIdOperation()
}
private fun actionIdOperation() {
if (actionId == PopupConstObject.NOTIFICATION_ACTION_HOME) {
}
if (actionId == NOTIFICATION_ACTION_MY_CODE) {
startActivity(Intent(this, LocationCodeActivity::class.java))
return
}
if (actionId == NOTIFICATION_ACTION_SHARE) {
startActivity(Intent(this, LocationShareActivity::class.java))
return
}
if (actionId == NOTIFICATION_ACTION_SETTINGS) {
startActivity(Intent(this, SettingActivity::class.java))
return
}
}
override fun onResume() {
......
......@@ -10,6 +10,7 @@ import com.base.locationsharewhite.bean.ConstObject.isFirstLauncher
import com.base.locationsharewhite.databinding.ActivitySplashBinding
import com.base.locationsharewhite.fcm.NotificationHoverUtils
import com.base.locationsharewhite.helper.BaseActivity
import com.base.locationsharewhite.service.StayNotificationService.Companion.startStayNotification
import com.base.locationsharewhite.ui.howuse.HowUseActivity
import com.base.locationsharewhite.ui.main.MainActivity
import com.base.locationsharewhite.ui.set.LanguageActivity
......@@ -26,7 +27,7 @@ import java.util.concurrent.atomic.AtomicBoolean
@SuppressLint("CustomSplashScreen")
class SplashActivity : BaseActivity<ActivitySplashBinding>(), SplashView {
private val TAG="SplashActivity"
private val TAG = "SplashActivity"
private lateinit var splashPresenter: SplashPresenter
private var progressJob: Job? = null
......@@ -41,6 +42,7 @@ class SplashActivity : BaseActivity<ActivitySplashBinding>(), SplashView {
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
// binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
splashPresenter = SplashPresenter(this)
startStayNotification()
actionId = intent.extras?.getString("actionId") ?: ""
LogEx.logDebug(TAG, "actionId=$actionId")
......
......@@ -2,6 +2,7 @@ package com.base.locationsharewhite.ui.splash
import androidx.lifecycle.LifecycleCoroutineScope
import com.base.locationsharewhite.bean.ConstObject
import com.base.locationsharewhite.utils.AppPreferences
import com.base.locationsharewhite.utils.LogEx
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
......@@ -15,8 +16,7 @@ class SplashPresenter(
private var jumpJob: Job? = null
// var loadingTime = AppPreferences.getInstance().getString(open_ad_loading, "15").toInt()
var loadingTime = 8
var loadingTime = AppPreferences.getInstance().getString(open_ad_loading, "15").toInt()
var startJumpJob: Boolean = false
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F2F2F2" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF8A00" />
<corners android:radius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="180dp"
android:layout_height="136dp"
android:layout_margin="5dp"
app:cardCornerRadius="25dp"
app:cardElevation="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="23dp"
android:src="@mipmap/jiazai_ad"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="18dp"
android:layout_marginBottom="22dp"
android:includeFontPadding="false"
android:text="@string/preparing_advertisement"
android:textColor="@color/black"
android:textSize="13sp"
tools:ignore="HardcodedText" />
</LinearLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/bg_f2f2f2"
android:baselineAligned="false">
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_media"
android:layout_width="91dp"
android:layout_height="91dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="8dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#FF923E"
android:padding="2dp"
android:text="Ad"
android:textColor="@color/white"
android:textSize="12sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="5dp">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
tools:ignore="ContentDescription" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/ad_call_to_action"
android:layout_width="match_parent"
android:layout_height="26dp"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="12dp"
android:background="@drawable/bg_ff8a00_10"
android:gravity="center"
android:textColor="@color/white"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
\ No newline at end of file
......@@ -17,8 +17,8 @@
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/home_notification"
tools:ignore="ContentDescription" />
......@@ -46,8 +46,8 @@
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/mycode_notification"
tools:ignore="ContentDescription" />
......@@ -74,8 +74,8 @@
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/share_notification"
tools:ignore="ContentDescription" />
......@@ -102,8 +102,8 @@
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/settings_notification"
tools:ignore="ContentDescription" />
......
......@@ -23,4 +23,5 @@
<dimen name="dp_250">250dp</dimen>
<dimen name="dp_225">225dp</dimen>
<dimen name="dp_235">235dp</dimen>
<dimen name="dp_146">146dp</dimen>
</resources>
\ No newline at end of file
......@@ -58,4 +58,5 @@
<string name="home">Home</string>
<string name="my_code">My Code</string>
<string name="share">Share</string>
<string name="preparing_advertisement"><![CDATA[Preparing advertisement&#8230;]]></string>
</resources>
\ No newline at end of file
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