|
@@ -0,0 +1,160 @@
|
|
|
+package com.kdanmobile.admanager.admob
|
|
|
+
|
|
|
+import android.app.Activity
|
|
|
+import android.content.Context
|
|
|
+import com.google.android.gms.ads.MobileAds
|
|
|
+import com.google.android.gms.ads.reward.RewardItem
|
|
|
+import com.google.android.gms.ads.reward.RewardedVideoAd
|
|
|
+import com.google.android.gms.ads.reward.RewardedVideoAdListener
|
|
|
+import com.kdanmobile.admanager.RewardedAdListener
|
|
|
+import com.kdanmobile.admanager.RewardedAdManager
|
|
|
+import com.kdanmobile.admanager.toRewardedAdItem
|
|
|
+import java.util.concurrent.CopyOnWriteArrayList
|
|
|
+
|
|
|
+class AdMobRewardedAdManager: RewardedAdManager {
|
|
|
+
|
|
|
+ companion object {
|
|
|
+ private const val MAX_KEEPING_AD_DURATION = 60 * 60 * 1000L
|
|
|
+ }
|
|
|
+
|
|
|
+ override var isPersonalized: Boolean = false
|
|
|
+ private val adListeners = CopyOnWriteArrayList<RewardedAdListener>()
|
|
|
+ private val rewardedAdDataMap = HashMap<String, RewardedAdData>()
|
|
|
+
|
|
|
+ private data class RewardedAdData(
|
|
|
+ var ad: RewardedVideoAd,
|
|
|
+ var status: RewardedAdStatus,
|
|
|
+ var time: Long = 0L
|
|
|
+ )
|
|
|
+
|
|
|
+ private enum class RewardedAdStatus {
|
|
|
+ NOT_INIT,
|
|
|
+ LOADING,
|
|
|
+ LOADED,
|
|
|
+ FAILED
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun request(activity: Activity, adUnitId: String) {
|
|
|
+ if (rewardedAdDataMap[adUnitId] == null) {
|
|
|
+ val status = RewardedAdStatus.NOT_INIT
|
|
|
+ val ad = MobileAds.getRewardedVideoAdInstance(activity.application).apply {
|
|
|
+ rewardedVideoAdListener = object : RewardedVideoAdListener {
|
|
|
+ override fun onRewardedVideoAdClosed() {
|
|
|
+ adListeners.forEach {
|
|
|
+ it.onRewardedAdClosed(adUnitId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewardedVideoAdLeftApplication() {
|
|
|
+ adListeners.forEach {
|
|
|
+ it.onRewardedAdLeftApplication(adUnitId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewardedVideoAdLoaded() {
|
|
|
+ rewardedAdDataMap[adUnitId]?.status = RewardedAdStatus.LOADED
|
|
|
+ adListeners.forEach {
|
|
|
+ it.onRewardedAdLoaded(adUnitId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewardedVideoAdOpened() {
|
|
|
+ adListeners.forEach {
|
|
|
+ it.onRewardedAdOpened(adUnitId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewardedVideoCompleted() {
|
|
|
+ adListeners.forEach {
|
|
|
+ it.onRewardedAdCompleted(adUnitId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewarded(rewardItem: RewardItem?) {
|
|
|
+ val item = rewardItem?.toRewardedAdItem()
|
|
|
+ adListeners.forEach {
|
|
|
+ it.onRewarded(adUnitId, item)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewardedVideoStarted() {
|
|
|
+ adListeners.forEach {
|
|
|
+ it.onRewardedAdStarted(adUnitId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onRewardedVideoAdFailedToLoad(errorCode: Int) {
|
|
|
+ rewardedAdDataMap[adUnitId]?.status = RewardedAdStatus.FAILED
|
|
|
+ adListeners.forEach {
|
|
|
+ it.onRewardedAdFailedToLoad(adUnitId, errorCode)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rewardedAdDataMap[adUnitId] = RewardedAdData(ad, status)
|
|
|
+ }
|
|
|
+ request(adUnitId)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun request(adUnitId: String) {
|
|
|
+ rewardedAdDataMap[adUnitId]?.apply {
|
|
|
+ if (System.currentTimeMillis() - time <= MAX_KEEPING_AD_DURATION) {
|
|
|
+ if (status == RewardedAdStatus.LOADING) return
|
|
|
+ if (status == RewardedAdStatus.LOADED) return
|
|
|
+ }
|
|
|
+ ad.loadAd(adUnitId, RequestFactory.create(isPersonalized))
|
|
|
+ status = RewardedAdStatus.LOADING
|
|
|
+ time = System.currentTimeMillis()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun show(adUnitId: String): Boolean {
|
|
|
+ if (!isLoaded(adUnitId)) return false
|
|
|
+ return rewardedAdDataMap[adUnitId]?.let {
|
|
|
+ it.ad.show()
|
|
|
+ it.status = RewardedAdStatus.NOT_INIT
|
|
|
+ true
|
|
|
+ } ?: false
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun registerListener(listener: RewardedAdListener) {
|
|
|
+ adListeners.add(listener)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun unregisterListener(listener: RewardedAdListener) {
|
|
|
+ adListeners.remove(listener)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun isLoading(adUnitId: String): Boolean {
|
|
|
+ return rewardedAdDataMap[adUnitId]?.status == RewardedAdStatus.LOADING
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun isLoaded(adUnitId: String): Boolean {
|
|
|
+ val data = rewardedAdDataMap[adUnitId]
|
|
|
+ return when {
|
|
|
+ data == null -> false
|
|
|
+ data.status != RewardedAdStatus.LOADED -> false
|
|
|
+ System.currentTimeMillis() - data.time > MAX_KEEPING_AD_DURATION -> false
|
|
|
+ else -> true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun pauseAll(context: Context) {
|
|
|
+ for (rewardedAd in rewardedAdDataMap.values.map { it.ad }) {
|
|
|
+ rewardedAd.pause(context)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun resumeAll(context: Context) {
|
|
|
+ for (rewardedAd in rewardedAdDataMap.values.map { it.ad }) {
|
|
|
+ rewardedAd.resume(context)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun destroyAll(context: Context) {
|
|
|
+ for (rewardedAd in rewardedAdDataMap.values.map { it.ad }) {
|
|
|
+ rewardedAd.destroy(context)
|
|
|
+ }
|
|
|
+ rewardedAdDataMap.clear()
|
|
|
+ }
|
|
|
+}
|