229 lines
8.5 KiB
C#
229 lines
8.5 KiB
C#
using System.Collections.Generic;
|
|
using GoogleMobileAds.Api;
|
|
using System;
|
|
using UnityEngine;
|
|
using System.Linq;
|
|
|
|
namespace WZ
|
|
{
|
|
public class AdmobCollapsibleBannerAdManager
|
|
{
|
|
private Dictionary<string, BannerView> _bannerAds = new Dictionary<string, BannerView>();
|
|
private Dictionary<string, int> _retryCounters = new Dictionary<string, int>();
|
|
private Dictionary<string, Action> _loadCallbacks = new Dictionary<string, Action>();
|
|
private Dictionary<string, double> _adRevenueCache = new Dictionary<string, double>();
|
|
private Dictionary<string, float> _adStartLoadTimes = new Dictionary<string, float>();
|
|
private BannerView _currentBannerView = null;
|
|
|
|
public void InitializeAdUnits(BannerAlignType type, List<string> adUnitIds)
|
|
{
|
|
foreach (var adUnitId in adUnitIds)
|
|
{
|
|
CreateRewardedAd(type, adUnitId);
|
|
}
|
|
}
|
|
|
|
private void CreateRewardedAd(BannerAlignType type,string adUnitId)
|
|
{
|
|
if (string.IsNullOrEmpty(adUnitId)) return;
|
|
if (_bannerAds.ContainsKey(adUnitId))
|
|
{
|
|
LoggerUtils.Debug($"[Admob] banner collapsible Ad unit {adUnitId} already exists");
|
|
return;
|
|
}
|
|
|
|
var bannerAds = new BannerView(adUnitId, AdSize.Banner, type == BannerAlignType.CenterBottom ? AdPosition.Bottom : AdPosition.Top);
|
|
_adStartLoadTimes[adUnitId] = Time.realtimeSinceStartup;
|
|
bannerAds.Hide();
|
|
|
|
_bannerAds[adUnitId] = bannerAds;
|
|
_retryCounters[adUnitId] = 0;
|
|
_adRevenueCache[adUnitId] = 0;
|
|
|
|
bannerAds.OnBannerAdLoaded += () =>
|
|
{
|
|
_retryCounters[adUnitId] = 0;
|
|
_adRevenueCache[adUnitId] = AdmobUtils.GetBannerEcpm(bannerAds);
|
|
LoggerUtils.Debug($"[Admob] banner collapsible -[Load]: {adUnitId} successfully iscollapsible: {bannerAds.IsCollapsible()},ecpm: {AdmobUtils.GetBannerEcpm(bannerAds)}");
|
|
|
|
AdsActionEvents.TrackAdLoaded(AdmobAdsManager.Instance.Platfrom,
|
|
bannerAds?.GetResponseInfo()?.GetLoadedAdapterResponseInfo()?.AdSourceName ?? "",
|
|
adUnitId,
|
|
AdsType.Banner,
|
|
Time.realtimeSinceStartup - (_adStartLoadTimes.TryGetValue(adUnitId, out var time)? time : 0));
|
|
AdsKeyEvents.Instance.LogAdFPUEvents(AdsType.Banner);
|
|
};
|
|
|
|
bannerAds.OnBannerAdLoadFailed += ((msg) =>
|
|
{
|
|
if (!_retryCounters.TryAdd(adUnitId, 0))
|
|
{
|
|
_retryCounters[adUnitId]++;
|
|
}
|
|
double retryDelay = Math.Pow(2, Math.Min(6, _retryCounters.TryGetValue(adUnitId,out var times)? times : 0));
|
|
LoggerUtils.Debug($"[Admob] banner collapsible -[Load]: {adUnitId} failed, error message = {msg}");
|
|
|
|
// 延迟重试加载
|
|
_loadCallbacks[adUnitId] = () => LoadAd(adUnitId);
|
|
_loadCallbacks.TryGetValue(adUnitId, out Action _loadCallback);
|
|
if (_loadCallback != null)
|
|
{
|
|
TimerUtils.Instance.DelayExecute((float)retryDelay, () => _loadCallback?.Invoke());
|
|
}
|
|
AdsActionEvents.TrackAdFailToLoad(AdmobAdsManager.Instance.Platfrom,
|
|
"",
|
|
"",
|
|
AdsType.Banner,Time.realtimeSinceStartup - (_adStartLoadTimes.TryGetValue(adUnitId, out var time)? time : 0),
|
|
msg.GetMessage());
|
|
});
|
|
|
|
bannerAds.OnAdPaid += ((adValue) =>
|
|
{
|
|
LoggerUtils.Debug($"[Admob] banner collapsible -[interaction]: {adUnitId} show");
|
|
AdmobAdsManager.Instance.TrackAdImpression(bannerAds?.GetResponseInfo()?.GetLoadedAdapterResponseInfo()?.AdSourceName ?? "",
|
|
bannerAds?.GetResponseInfo()?.GetLoadedAdapterResponseInfo()?.AdSourceInstanceId ?? "",
|
|
adValue,
|
|
AdsType.Banner,
|
|
adUnitId);
|
|
});
|
|
|
|
bannerAds.OnAdClicked += () =>
|
|
{
|
|
AdsActionEvents.TrackAdClicked(AdmobAdsManager.Instance.Platfrom,
|
|
bannerAds?.GetResponseInfo()?.GetLoadedAdapterResponseInfo()?.AdSourceName ?? "",
|
|
adUnitId,
|
|
AdsType.Banner,
|
|
"",
|
|
AdmobUtils.GetBannerEcpm(bannerAds));
|
|
};
|
|
LoadAd(adUnitId);
|
|
}
|
|
|
|
public void LoadAd(string adUnitId)
|
|
{
|
|
if (!AdmobAdsManager.Instance.FindAdsID(AdsType.Banner, adUnitId, BannerType.Collapsible))
|
|
{
|
|
return;
|
|
}
|
|
if (_bannerAds.TryGetValue(adUnitId, out var ad))
|
|
{
|
|
var adRequest = new AdRequest();
|
|
adRequest.Extras.Add("collapsible", "bottom");
|
|
ad.LoadAd(adRequest);
|
|
}
|
|
}
|
|
|
|
// 显示价格最高的广告
|
|
public void ShowHighestPayingAd(BannerAlignType bannerAlignType)
|
|
{
|
|
var highestPayingAdUnit = GetHighestPayingAdUnit();
|
|
if (!string.IsNullOrEmpty(highestPayingAdUnit))
|
|
{
|
|
|
|
ShowAd(highestPayingAdUnit,bannerAlignType);
|
|
}
|
|
}
|
|
|
|
public void HideBanner()
|
|
{
|
|
_currentBannerView?.Hide();
|
|
_currentBannerView?.Destroy();
|
|
AdmobAdsManager.Instance.LoadCollapsingBanner();
|
|
}
|
|
// 显示特定广告位的广告
|
|
private void ShowAd(string adUnitId,BannerAlignType bannerAlignType)
|
|
{
|
|
if (!AdmobAdsManager.Instance.FindAdsID(AdsType.Banner, adUnitId,BannerType.Collapsible))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_bannerAds.TryGetValue(adUnitId, out var ad))
|
|
{
|
|
ad.SetPosition(bannerAlignType == BannerAlignType.CenterBottom ? AdPosition.Bottom : AdPosition.Top);
|
|
ad.Show();
|
|
_currentBannerView = ad;
|
|
}
|
|
}
|
|
|
|
// 获取所有可用的广告位
|
|
public List<string> GetAvailableAdUnits()
|
|
{
|
|
var available = new List<string>();
|
|
foreach (var kvp in _bannerAds)
|
|
{
|
|
available.Add(kvp.Key);
|
|
}
|
|
return available;
|
|
}
|
|
|
|
// 获取特定广告位的收益信息
|
|
public double GetAdRevenue(string adUnitId)
|
|
{
|
|
if (_adRevenueCache.TryGetValue(adUnitId, out var revenue))
|
|
{
|
|
return revenue;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// 获取价格最高的广告位ID
|
|
public string GetHighestPayingAdUnit()
|
|
{
|
|
if (_adRevenueCache.Count == 0) return null;
|
|
return _adRevenueCache.OrderByDescending(kvp => kvp.Value).First().Key;
|
|
}
|
|
|
|
// 获取价格最高的广告收益信息
|
|
public double GetHighestPayingAdRevenue()
|
|
{
|
|
var highestPayingAdUnit = GetHighestPayingAdUnit();
|
|
if (!string.IsNullOrEmpty(highestPayingAdUnit) &&
|
|
_adRevenueCache.TryGetValue(highestPayingAdUnit, out var revenue))
|
|
{
|
|
return revenue;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// 清理资源
|
|
public void Destroy()
|
|
{
|
|
foreach (var ad in _bannerAds.Values)
|
|
{
|
|
ad.Destroy();
|
|
}
|
|
_bannerAds.Clear();
|
|
_retryCounters.Clear();
|
|
_loadCallbacks.Clear();
|
|
_adRevenueCache.Clear();
|
|
}
|
|
|
|
public void ClearAds(string[] adUnitIds)
|
|
{
|
|
// 将数组转换为HashSet以提高查找性能
|
|
HashSet<string> validKeys = new HashSet<string>(adUnitIds);
|
|
// 收集需要移除的key
|
|
List<string> keysToRemove = new List<string>();
|
|
|
|
foreach (var key in _bannerAds.Keys)
|
|
{
|
|
if (!validKeys.Contains(key))
|
|
{
|
|
keysToRemove.Add(key);
|
|
}
|
|
}
|
|
|
|
// 移除不在数组中的key
|
|
foreach (string key in keysToRemove)
|
|
{
|
|
_bannerAds.Remove(key);
|
|
_retryCounters.Remove(key);
|
|
_loadCallbacks.Remove(key);
|
|
_adRevenueCache.Remove(key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|