feat: 开屏广告神策埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-4955 See merge request halo/android/assistant-android!1587
683 lines
24 KiB
Kotlin
683 lines
24 KiB
Kotlin
package com.gh.ad
|
||
|
||
import android.annotation.SuppressLint
|
||
import android.app.Activity
|
||
import android.content.Context
|
||
import android.content.SharedPreferences
|
||
import android.os.Message
|
||
import android.text.TextUtils
|
||
import android.view.View
|
||
import android.view.ViewGroup
|
||
import android.widget.FrameLayout
|
||
import android.widget.TextView
|
||
import androidx.appcompat.content.res.AppCompatResources
|
||
import androidx.fragment.app.Fragment
|
||
import com.alibaba.android.arouter.launcher.ARouter
|
||
import com.facebook.drawee.view.SimpleDraweeView
|
||
import com.gh.common.exposure.ExposureManager
|
||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||
import com.gh.common.util.LogUtils
|
||
import com.gh.common.util.NewFlatLogUtils.logOpenScreenAdSkip
|
||
import com.gh.common.util.PackageUtils
|
||
import com.gh.gamecenter.BuildConfig
|
||
import com.gh.gamecenter.MainActivity
|
||
import com.gh.gamecenter.R
|
||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||
import com.gh.gamecenter.common.constant.Constants
|
||
import com.gh.gamecenter.common.constant.RouteConsts
|
||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||
import com.gh.gamecenter.common.utils.*
|
||
import com.gh.gamecenter.core.provider.IBeiziAdProvider
|
||
import com.gh.gamecenter.core.provider.ICsjAdProvider
|
||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||
import com.gh.gamecenter.core.utils.SPUtils
|
||
import com.gh.gamecenter.core.utils.TimeUtils.getToday
|
||
import com.gh.gamecenter.entity.AdConfig
|
||
import com.gh.gamecenter.entity.StartupAdEntity
|
||
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
|
||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||
import com.halo.assistant.HaloApp
|
||
import io.reactivex.schedulers.Schedulers
|
||
|
||
/**
|
||
* 广告实现代理类
|
||
*
|
||
* 由它来分发功能实现到具体的实现
|
||
*
|
||
* 以最复杂的开屏广告为例,有三种实现(1. 自有的广告实现 2. 穿山甲的开屏广告实现 3. Beizi 的开屏广告实现)
|
||
*
|
||
* 由于两个广告 SDK 有可能在一次启动中都被使用,所以会根据获取到的广告配置 config 来决定是否需要出是很好两个 SDK
|
||
*/
|
||
object AdDelegateHelper {
|
||
|
||
private var mCsjAdImpl: ICsjAdProvider? = null
|
||
private var mBeiziAdImpl: IBeiziAdProvider? = null
|
||
|
||
private val mAdConfigList: ArrayList<AdConfig> by lazy { arrayListOf() }
|
||
|
||
private var mSplashAd: AdConfig? = null
|
||
private var mDownloadManagerAd: AdConfig? = null
|
||
private val mGameSearchAdList: ArrayList<AdConfig> by lazy { arrayListOf() }
|
||
private var mVGameLaunchAd: AdConfig? = null
|
||
|
||
val vGameLaunchAd: AdConfig?
|
||
get() = mVGameLaunchAd
|
||
|
||
private const val AD_SDK_CSJ = "穿山甲"
|
||
private const val AD_SDK_BEIZI = "倍孜"
|
||
const val AD_TYPE_SDK = "third_party_ads" // 第三方 SDK 广告
|
||
const val AD_TYPE_OWNER = "owner_ads" // 自有广告
|
||
|
||
private const val KEY_CACHE_CONFIG = "cache_config" // 放在 SP 里的广告缓存(避免接口加载问题)
|
||
|
||
private val mAdConfigSp: SharedPreferences by lazy {
|
||
HaloApp.getInstance().getSharedPreferences("AdConfig", Context.MODE_PRIVATE)
|
||
}
|
||
|
||
var isShowingSplashAd = false // 是否正在显示开屏广告
|
||
var gameSearchKeyword = ""
|
||
|
||
fun initAdSdk(context: Context) {
|
||
// 初始化 Beizi
|
||
if (mBeiziAdImpl == null) {
|
||
mBeiziAdImpl =
|
||
ARouter.getInstance().build(RouteConsts.provider.beiziAd).navigation() as? IBeiziAdProvider
|
||
mBeiziAdImpl?.initSDK(context)
|
||
}
|
||
|
||
// 初始化穿山甲
|
||
if (mCsjAdImpl == null) {
|
||
mCsjAdImpl =
|
||
ARouter.getInstance().build(RouteConsts.provider.csjAd).navigation() as? ICsjAdProvider
|
||
val csjAppId = if (EnvHelper.isDevEnv) BuildConfig.DEV_CSJ_APPID else BuildConfig.CSJ_APPID
|
||
mCsjAdImpl?.initSDK(context, csjAppId, HaloApp.getInstance().oaid)
|
||
// 监听亮色/暗色模式切换
|
||
DarkModeUtils.registerModeChangeListener {
|
||
val topActivity = CurrentActivityHolder.getCurrentActivity() ?: return@registerModeChangeListener
|
||
updateThemeStatus(context, DarkModeUtils.isDarkModeOn(topActivity))
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 请求接口获取广告相关配置
|
||
*/
|
||
@SuppressLint("CheckResult")
|
||
fun requestAdConfig(isFromRetry: Boolean, keyword: String = "", callback: (() -> Unit)? = null) {
|
||
// mAdConfigList 不为空不需要重试
|
||
if (isFromRetry && mAdConfigList.isNotEmpty()) {
|
||
return
|
||
}
|
||
val paramsMap = if (keyword.isNotEmpty()) mapOf("keyword" to keyword) else mapOf()
|
||
RetrofitManager.getInstance()
|
||
.newApi
|
||
.getAdConfig(paramsMap)
|
||
.subscribeOn(Schedulers.io())
|
||
.subscribe(object : BiResponse<List<AdConfig>>() {
|
||
override fun onSuccess(data: List<AdConfig>) {
|
||
gameSearchKeyword = keyword
|
||
handleAdConfig(data)
|
||
callback?.invoke()
|
||
|
||
// 缓存数据到 SP 供接口请求失败用
|
||
SPUtils.setString(mAdConfigSp, KEY_CACHE_CONFIG, data.toJson())
|
||
}
|
||
|
||
override fun onFailure(exception: Exception) {
|
||
super.onFailure(exception)
|
||
|
||
// 若接口请求失败时,从 SP 里获取上次缓存的数据
|
||
val cachedConfig: List<AdConfig>? = SPUtils.getString(mAdConfigSp, KEY_CACHE_CONFIG).toObject()
|
||
if (cachedConfig != null && mAdConfigList.isEmpty()) {
|
||
handleAdConfig(cachedConfig)
|
||
}
|
||
|
||
callback?.invoke()
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取搜索页的广告列表
|
||
*/
|
||
fun getGameSearchAdList(): ArrayList<AdConfig> {
|
||
return mGameSearchAdList
|
||
}
|
||
|
||
/**
|
||
* 获取下载管理页的广告
|
||
*/
|
||
fun getDownloadManagerAd(): AdConfig? {
|
||
return mDownloadManagerAd
|
||
}
|
||
|
||
/**
|
||
* 处理广告配置
|
||
*/
|
||
fun handleAdConfig(configList: List<AdConfig>) {
|
||
mAdConfigList.clear()
|
||
mGameSearchAdList.clear()
|
||
mSplashAd = null
|
||
mDownloadManagerAd = null
|
||
mVGameLaunchAd = null
|
||
for (config in configList) {
|
||
mAdConfigList.add(config)
|
||
// 处理返回的数据
|
||
when (config.location) {
|
||
"halo_launch" -> {
|
||
config.ownerAd?.startAd?.let { it.id = config.ownerAd.id }
|
||
mSplashAd = config
|
||
}
|
||
|
||
"download_manager" -> mDownloadManagerAd = config
|
||
"game_search" -> config.let { mGameSearchAdList.add(it) }
|
||
"helper_launch" -> mVGameLaunchAd = config
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 是否需要显示开屏广告
|
||
* @param isHotLaunch 是否为热启动
|
||
*/
|
||
fun shouldShowStartUpAd(isHotLaunch: Boolean): Boolean {
|
||
return mSplashAd != null
|
||
&& !isShowingSplashAd
|
||
&& (!isHotLaunch || shouldShowStartUpAdWhenHotLaunch())
|
||
&& !isMatchAdFreeRule(mSplashAd)
|
||
&& isMatchStartUpAdDisplayRule()
|
||
}
|
||
|
||
/**
|
||
* 热启动是否需要显示开屏广告
|
||
*/
|
||
private fun shouldShowStartUpAdWhenHotLaunch() =
|
||
mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK && mSplashAd?.hotStartThirdPartyAd != null
|
||
|
||
/**
|
||
* 是否需要显示下载管理广告
|
||
*/
|
||
fun shouldShowDownloadManagerAd(): Boolean {
|
||
return mDownloadManagerAd != null && !isMatchAdFreeRule(mDownloadManagerAd) && isMatchDownloadManagerAdDisplayRule()
|
||
}
|
||
|
||
/**
|
||
* 是否需要显示游戏搜索广告
|
||
*/
|
||
fun shouldShowGameSearchAd(adConfig: AdConfig): Boolean {
|
||
return !isMatchAdFreeRule(adConfig) && isMatchGameSearchAdDisplayRule(adConfig)
|
||
}
|
||
|
||
/**
|
||
* 是否在免广告时长内
|
||
*/
|
||
private fun isMatchAdFreeRule(adConfig: AdConfig?): Boolean {
|
||
adConfig?.displayRule?.run {
|
||
if (adFreeDuration > 0) {
|
||
val ghInstalledDurationInHours = (System.currentTimeMillis() - PackageUtils.getInstalledTime(
|
||
HaloApp.getInstance(),
|
||
BuildConfig.APPLICATION_ID
|
||
)).toFloat() / 1000 / 3600
|
||
return ghInstalledDurationInHours < adFreeDuration
|
||
} else {
|
||
return false
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
/**
|
||
* 是否大于开屏广告展示间隔时长
|
||
*/
|
||
private fun isMatchStartUpAdDisplayRule(): Boolean {
|
||
mSplashAd?.displayRule?.run {
|
||
if (adDisplayInterval > 0) {
|
||
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, 0L)
|
||
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
|
||
return durationInMinutes > adDisplayInterval
|
||
} else {
|
||
return true
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
/**
|
||
* 是否大于广告管理展示间隔时长
|
||
*/
|
||
private fun isMatchDownloadManagerAdDisplayRule(): Boolean {
|
||
mDownloadManagerAd?.displayRule?.run {
|
||
if (adDisplayInterval > 0) {
|
||
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME, 0L)
|
||
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
|
||
return durationInMinutes > adDisplayInterval
|
||
} else {
|
||
return true
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
/**
|
||
* 是否大于游戏搜索展示间隔时长
|
||
*/
|
||
private fun isMatchGameSearchAdDisplayRule(adConfig: AdConfig?): Boolean {
|
||
adConfig?.displayRule?.run {
|
||
if (adDisplayInterval > 0) {
|
||
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position, 0L)
|
||
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
|
||
return durationInMinutes > adDisplayInterval
|
||
} else {
|
||
return true
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
/**
|
||
* 更新主题样式
|
||
*/
|
||
private fun updateThemeStatus(context: Context, isDarkMode: Boolean) {
|
||
mCsjAdImpl?.updateThemeStatus(context, isDarkMode)
|
||
}
|
||
|
||
/**
|
||
* 请求开屏广告
|
||
*/
|
||
@JvmStatic
|
||
fun requestSplashAd(
|
||
activity: Activity,
|
||
adViewWidthInPx: Int,
|
||
adViewHeightInPx: Int,
|
||
adViewWidthInDp: Float,
|
||
adViewHeightInDp: Float,
|
||
startAdContainer: ViewGroup,
|
||
sdkStartAdContainer: ViewGroup,
|
||
adsViewGroup: FrameLayout,
|
||
handler: BaseActivity.BaseHandler,
|
||
isHotLaunch: Boolean,
|
||
hideAction: () -> Unit
|
||
) {
|
||
val hideCallback = {
|
||
isShowingSplashAd = false
|
||
hideAction.invoke()
|
||
}
|
||
if (mSplashAd != null) {
|
||
when (if (isHotLaunch) mSplashAd!!.displayRule.hotStartSplashAd?.type else mSplashAd!!.displayRule.adSource) {
|
||
AD_TYPE_SDK -> {
|
||
isShowingSplashAd = true
|
||
requestThirdPartySplashAd(
|
||
activity,
|
||
adViewWidthInPx,
|
||
adViewHeightInPx,
|
||
adViewWidthInDp,
|
||
adViewHeightInDp,
|
||
startAdContainer,
|
||
sdkStartAdContainer,
|
||
adsViewGroup,
|
||
handler,
|
||
isHotLaunch,
|
||
hideCallback
|
||
)
|
||
}
|
||
|
||
AD_TYPE_OWNER -> {
|
||
isShowingSplashAd = true
|
||
requestStandardSplashAd(
|
||
activity,
|
||
adViewWidthInPx,
|
||
adViewHeightInPx,
|
||
adViewWidthInDp,
|
||
adViewHeightInDp,
|
||
startAdContainer,
|
||
sdkStartAdContainer,
|
||
adsViewGroup,
|
||
handler,
|
||
isHotLaunch,
|
||
hideCallback
|
||
)
|
||
}
|
||
}
|
||
} else {
|
||
hideCallback.invoke()
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取第三方开屏广告
|
||
*/
|
||
private fun requestThirdPartySplashAd(
|
||
activity: Activity,
|
||
adViewWidthInPx: Int,
|
||
adViewHeightInPx: Int,
|
||
adViewWidthInDp: Float,
|
||
adViewHeightInDp: Float,
|
||
startAdContainer: ViewGroup,
|
||
sdkStartAdContainer: ViewGroup,
|
||
adsViewGroup: FrameLayout,
|
||
handler: BaseActivity.BaseHandler,
|
||
isHotLaunch: Boolean,
|
||
hideCallback: () -> Unit
|
||
) {
|
||
// 第三方开屏广告回调,失败时根据接口配置选项决定是否显示自有开屏广告
|
||
val sdkSplashCallback: (isSuccess: Boolean) -> Unit = { isSuccess ->
|
||
if (isSuccess) {
|
||
hideCallback.invoke()
|
||
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis())
|
||
} else {
|
||
if (mSplashAd?.displayRule?.adSource == AD_TYPE_SDK && mSplashAd?.displayRule?.onFailedAction == "show" && !isHotLaunch) {
|
||
sdkStartAdContainer.visibility = View.GONE
|
||
requestStandardSplashAd(
|
||
activity,
|
||
adViewWidthInPx,
|
||
adViewHeightInPx,
|
||
adViewWidthInDp,
|
||
adViewHeightInDp,
|
||
startAdContainer,
|
||
sdkStartAdContainer,
|
||
adsViewGroup,
|
||
handler,
|
||
isHotLaunch,
|
||
hideCallback
|
||
)
|
||
} else {
|
||
hideCallback.invoke()
|
||
}
|
||
}
|
||
}
|
||
|
||
val thirdPartyAd = if (isHotLaunch) mSplashAd?.hotStartThirdPartyAd else mSplashAd?.thirdPartyAd
|
||
|
||
// 第三方广告的数据为空,按加载失败处理
|
||
if (mSplashAd == null || thirdPartyAd == null) {
|
||
sdkSplashCallback.invoke(false)
|
||
return
|
||
}
|
||
|
||
val timeout = if (isHotLaunch) {
|
||
((mSplashAd?.displayRule?.hotStartSplashAd?.timeout ?: 3.5F) * 1000).toInt()
|
||
} else {
|
||
((mSplashAd?.displayRule?.timeout ?: 3.5F) * 1000).toInt()
|
||
}
|
||
|
||
if (thirdPartyAd.sourceName == AD_SDK_BEIZI) {
|
||
sdkStartAdContainer.visibility = View.VISIBLE
|
||
requestBeiziSplashAd(sdkStartAdContainer, adsViewGroup, adViewWidthInPx, adViewHeightInPx, timeout.toLong(), sdkSplashCallback)
|
||
} else if (thirdPartyAd.sourceName == AD_SDK_CSJ) {
|
||
sdkStartAdContainer.visibility = View.VISIBLE
|
||
requestCsjSplashAd(
|
||
activity,
|
||
thirdPartyAd.slotId,
|
||
adViewWidthInPx,
|
||
adViewHeightInPx,
|
||
adViewWidthInDp,
|
||
adViewHeightInDp,
|
||
sdkStartAdContainer,
|
||
timeout,
|
||
sdkSplashCallback
|
||
)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取穿山甲的开屏广告
|
||
*/
|
||
private fun requestCsjSplashAd(
|
||
activity: Activity,
|
||
slotId: String,
|
||
adViewWidthInPx: Int,
|
||
adViewHeightInPx: Int,
|
||
adViewWidthInDp: Float,
|
||
adViewHeightInDp: Float,
|
||
startAdContainer: ViewGroup,
|
||
timeout: Int,
|
||
callback: (isSuccess: Boolean) -> Unit,
|
||
) {
|
||
if (mCsjAdImpl == null) {
|
||
callback.invoke(false)
|
||
} else {
|
||
mCsjAdImpl?.requestSplashAd(
|
||
activity,
|
||
slotId,
|
||
adViewWidthInPx,
|
||
adViewHeightInPx,
|
||
adViewWidthInDp,
|
||
adViewHeightInDp,
|
||
startAdContainer,
|
||
timeout,
|
||
callback,
|
||
)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取 Beizi 的开屏广告
|
||
*/
|
||
private fun requestBeiziSplashAd(
|
||
startAdContainer: View,
|
||
adsFl: FrameLayout,
|
||
adViewWidthInPx: Int,
|
||
adViewHeightInPx: Int,
|
||
timeout: Long,
|
||
callback: (isSuccess: Boolean) -> Unit,
|
||
) {
|
||
if (mBeiziAdImpl == null) {
|
||
callback.invoke(false)
|
||
} else {
|
||
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, timeout, callback)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 显示自有的开屏广告
|
||
*/
|
||
private fun requestStandardSplashAd(
|
||
activity: Activity,
|
||
adViewWidthInPx: Int,
|
||
adViewHeightInPx: Int,
|
||
adViewWidthInDp: Float,
|
||
adViewHeightInDp: Float,
|
||
startAdContainer: ViewGroup,
|
||
sdkStartAdContainer: ViewGroup,
|
||
adsViewGroup: FrameLayout,
|
||
handler: BaseActivity.BaseHandler,
|
||
isHotLaunch: Boolean,
|
||
hideCallback: () -> Unit
|
||
) {
|
||
val splashAd = mSplashAd?.ownerAd?.startAd
|
||
val onEmptyCallback = {
|
||
if (mSplashAd?.displayRule?.adSource == AD_TYPE_OWNER && mSplashAd?.displayRule?.onFailedAction == "show" && mSplashAd?.thirdPartyAd != null) {
|
||
// 自有广告为空时,显示第三方广告
|
||
requestThirdPartySplashAd(
|
||
activity,
|
||
adViewWidthInPx,
|
||
adViewHeightInPx,
|
||
adViewWidthInDp,
|
||
adViewHeightInDp,
|
||
startAdContainer,
|
||
sdkStartAdContainer,
|
||
adsViewGroup,
|
||
handler,
|
||
isHotLaunch,
|
||
hideCallback
|
||
)
|
||
} else {
|
||
hideCallback.invoke()
|
||
}
|
||
}
|
||
if (splashAd == null) {
|
||
onEmptyCallback.invoke()
|
||
return
|
||
}
|
||
|
||
if (!TextUtils.isEmpty(splashAd.img)) {
|
||
val showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "") ?: ""
|
||
when (splashAd.rule) {
|
||
"each" -> showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||
"once" -> if (TextUtils.isEmpty(showedTodayTimestamp)
|
||
|| !showedTodayTimestamp.contains(splashAd.id)
|
||
) {
|
||
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||
} else {
|
||
onEmptyCallback.invoke()
|
||
}
|
||
|
||
"everyday" -> {
|
||
val today = getToday()
|
||
if (TextUtils.isEmpty(showedTodayTimestamp)
|
||
|| !showedTodayTimestamp.contains(today)
|
||
|| !showedTodayTimestamp.contains(splashAd.id)
|
||
) {
|
||
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||
} else {
|
||
onEmptyCallback.invoke()
|
||
}
|
||
}
|
||
|
||
else -> hideCallback.invoke()
|
||
}
|
||
SPUtils.setString(Constants.SP_STARTUP_AD_TIMESTAMP, splashAd.id + getToday())
|
||
} else {
|
||
hideCallback.invoke()
|
||
}
|
||
}
|
||
|
||
private fun showStandardSplashAd(
|
||
ad: StartupAdEntity,
|
||
startAdContainer: ViewGroup,
|
||
handler: BaseActivity.BaseHandler,
|
||
hideCallback: () -> Unit
|
||
) {
|
||
val jumpBtn: View = startAdContainer.findViewById(R.id.jumpBtn)
|
||
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
|
||
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
|
||
val icpContainer: View? = startAdContainer.findViewById(R.id.startAdIcpContainer)
|
||
startAdContainer.visibility = View.VISIBLE
|
||
icpContainer?.visibility = View.VISIBLE
|
||
jumpDetailBtn.text = ad.desc
|
||
jumpDetailBtn.setDrawableEnd(
|
||
AppCompatResources.getDrawable(
|
||
startAdContainer.context,
|
||
R.drawable.ic_startup_ad_arrow
|
||
), null, null
|
||
)
|
||
ImageUtils.display(adImage, ad.img)
|
||
startAdContainer.setOnClickListener {
|
||
// 拦截点击事件传递
|
||
}
|
||
jumpBtn.setOnClickListener {
|
||
handler.removeMessages(MainActivity.COUNTDOWN_AD)
|
||
hideCallback.invoke()
|
||
val linkEntity = ad.jump
|
||
logOpenScreenAdSkip(
|
||
ad.id,
|
||
(if (linkEntity.text != null) linkEntity.text else "")!!,
|
||
(if (linkEntity.type != null) linkEntity.type else "")!!,
|
||
(if (linkEntity.link != null) linkEntity.link else "")!!
|
||
)
|
||
SensorsBridge.trackEvent(
|
||
"SplashAdOwnSkip",
|
||
"splash_ad_id",
|
||
ad.id,
|
||
"link_type",
|
||
linkEntity.type ?: "",
|
||
"link_id",
|
||
linkEntity.link ?: "",
|
||
"link_text",
|
||
linkEntity.text ?: ""
|
||
)
|
||
}
|
||
val sources: MutableList<ExposureSource> = ArrayList()
|
||
sources.add(ExposureSource("开屏广告", ad.id))
|
||
val event = createEvent(null, sources, null, ExposureType.EXPOSURE)
|
||
ExposureManager.log(event)
|
||
if (ad.button) {
|
||
jumpDetailBtn.setOnClickListener { v: View ->
|
||
val linkEntity = ad.jump
|
||
directToLinkPage(v.context, linkEntity, "(启动广告)", "", event)
|
||
SensorsBridge.trackEvent(
|
||
"SplashAdOwnClick",
|
||
"splash_ad_id",
|
||
ad.id,
|
||
"link_type",
|
||
linkEntity.type ?: "",
|
||
"link_id",
|
||
linkEntity.link ?: "",
|
||
"link_text",
|
||
linkEntity.text ?: ""
|
||
)
|
||
v.postDelayed({
|
||
handler.removeMessages(MainActivity.COUNTDOWN_AD)
|
||
hideCallback.invoke()
|
||
}, 1000)
|
||
}
|
||
jumpDetailBtn.visibility = View.VISIBLE
|
||
LogUtils.logStartAd("watch_start_ads", ad)
|
||
} else {
|
||
LogUtils.logStartAd("start_ads", ad)
|
||
}
|
||
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis())
|
||
val msg = Message.obtain()
|
||
msg.what = MainActivity.COUNTDOWN_AD
|
||
msg.obj = ad
|
||
handler.sendMessageDelayed(msg, 1000)
|
||
}
|
||
|
||
/**
|
||
* 获取第三方信息流广告
|
||
*/
|
||
fun requestThirdPartyFlowAd(
|
||
fragment: Fragment,
|
||
slotId: String,
|
||
adContainerView: ViewGroup,
|
||
expressViewWidth: Float,
|
||
callback: (isSuccess: Boolean) -> Unit,
|
||
) {
|
||
mCsjAdImpl?.requestFlowAd(fragment, adContainerView, slotId, expressViewWidth, callback)
|
||
}
|
||
|
||
/**
|
||
* 获取第三方 Banner 广告
|
||
*/
|
||
fun requestThirdPartyBannerAd(
|
||
fragment: Fragment,
|
||
containerView: ViewGroup,
|
||
ad: AdConfig.ThirdPartyAd,
|
||
expressViewWidthInDp: Float,
|
||
callback: (isSuccess: Boolean) -> Unit
|
||
) {
|
||
|
||
val slotId = ad.slotId
|
||
val displayRatio: Float = if (ad.displaySize.isEmpty()) {
|
||
2F
|
||
} else {
|
||
val array = ad.displaySize.split("*")
|
||
if (array.size == 2) {
|
||
array[0].toFloat() / array[1].toFloat()
|
||
} else {
|
||
2F
|
||
}
|
||
}
|
||
val expressViewHeightInDp = expressViewWidthInDp / displayRatio
|
||
|
||
mCsjAdImpl?.requestBannerAd(
|
||
fragment,
|
||
containerView,
|
||
slotId,
|
||
expressViewWidthInDp,
|
||
expressViewHeightInDp,
|
||
callback
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 取消开屏广告
|
||
*/
|
||
fun cancelSplashAd(context: Context) {
|
||
mBeiziAdImpl?.cancelSplashAd(context)
|
||
mCsjAdImpl?.cancelSplashAd(context)
|
||
}
|
||
|
||
} |