optimize ads initialize

Signed-off-by: Haoyi <haoyi.zhang@castbox.fm>
sdk/v3.0.0 v3.0.0
Haoyi 2024-04-11 13:18:00 +08:00
parent ea55fd4551
commit c6549bf584
2 changed files with 201 additions and 106 deletions

View File

@ -22,6 +22,7 @@ import 'package:guru_app/property/settings/guru_settings.dart';
import 'package:guru_applovin_flutter/guru_applovin_flutter.dart'; import 'package:guru_applovin_flutter/guru_applovin_flutter.dart';
import 'package:guru_utils/datetime/datetime_utils.dart'; import 'package:guru_utils/datetime/datetime_utils.dart';
import 'package:guru_utils/extensions/extensions.dart'; import 'package:guru_utils/extensions/extensions.dart';
import 'package:guru_utils/network/network_utils.dart';
import 'package:guru_utils/tuple/tuple.dart'; import 'package:guru_utils/tuple/tuple.dart';
import 'package:guru_utils/ads/ads.dart'; import 'package:guru_utils/ads/ads.dart';
@ -45,7 +46,8 @@ class AdsManager extends AdsManagerDelegate {
final Map<AdUnitId, ApplovinRewardedAds> rewardsAds = {}; final Map<AdUnitId, ApplovinRewardedAds> rewardsAds = {};
final AdImpressionController adImpressionController = AdImpressionController(); final AdImpressionController adImpressionController =
AdImpressionController();
final BehaviorSubject<AdsConfig> _adsConfigSubject = final BehaviorSubject<AdsConfig> _adsConfigSubject =
BehaviorSubject.seeded(AdsConfig.defaultAdsConfig); BehaviorSubject.seeded(AdsConfig.defaultAdsConfig);
@ -53,12 +55,11 @@ class AdsManager extends AdsManagerDelegate {
final BehaviorSubject<AdsProfile> _adsProfileSubject = final BehaviorSubject<AdsProfile> _adsProfileSubject =
BehaviorSubject.seeded(GuruApp.instance.adsProfile); BehaviorSubject.seeded(GuruApp.instance.adsProfile);
final BehaviorSubject<bool> _initializedSubject = BehaviorSubject.seeded(false); final BehaviorSubject<bool> _initializedSubject =
BehaviorSubject.seeded(false);
final BehaviorSubject<ConnectivityResult> connectivityStatusSubject = final BehaviorSubject<bool> noBannerAndInterstitialAdsSubject =
BehaviorSubject.seeded(ConnectivityResult.none); BehaviorSubject.seeded(false);
final BehaviorSubject<bool> noBannerAndInterstitialAdsSubject = BehaviorSubject.seeded(false);
final Map<String, dynamic> adsGlobalProperties = <String, dynamic>{}; final Map<String, dynamic> adsGlobalProperties = <String, dynamic>{};
@ -71,12 +72,29 @@ class AdsManager extends AdsManagerDelegate {
"connection" "connection"
}; };
static const List<int> ltSamples = [0, 1, 2, 3, 4, 5, 6, 14, 30, 60, 90, 120, 180]; static const List<int> ltSamples = [
0,
1,
2,
3,
4,
5,
6,
14,
30,
60,
90,
120,
180
];
@override @override
Stream<bool> get observableInitialized => _initializedSubject.stream; Stream<bool> get observableInitialized => _initializedSubject.stream;
Stream<ConnectivityResult> get observableConnectivityStatus => connectivityStatusSubject.stream; ConnectivityResult get connectivityStatus => NetworkUtils.currentConnectivityStatus;
Stream<ConnectivityResult> get observableConnectivityStatus =>
NetworkUtils.observableConnectivityStatus;
@override @override
Stream<bool> get observableNoAds => noBannerAndInterstitialAdsSubject.stream; Stream<bool> get observableNoAds => noBannerAndInterstitialAdsSubject.stream;
@ -89,13 +107,13 @@ class AdsManager extends AdsManagerDelegate {
bool get hasAmazonBannerAds => adsConfig.bannerConfig.amazonEnable; bool get hasAmazonBannerAds => adsConfig.bannerConfig.amazonEnable;
bool get hasAmazonInterstitialAds => adsConfig.interstitialConfig.amazonEnable; bool get hasAmazonInterstitialAds =>
adsConfig.interstitialConfig.amazonEnable;
bool get hasAmazonAds => hasAmazonBannerAds || hasAmazonInterstitialAds; bool get hasAmazonAds => hasAmazonBannerAds || hasAmazonInterstitialAds;
ConnectivityResult get connectivityStatus => connectivityStatusSubject.value; final BehaviorSubject<Map<String, String>> keywordsSubject =
BehaviorSubject.seeded({});
final BehaviorSubject<Map<String, String>> keywordsSubject = BehaviorSubject.seeded({});
Stream<Map<String, String>> get observableKeywords => keywordsSubject.stream; Stream<Map<String, String>> get observableKeywords => keywordsSubject.stream;
@ -118,14 +136,16 @@ class AdsManager extends AdsManagerDelegate {
void setNoAds(bool noAds) { void setNoAds(bool noAds) {
noBannerAndInterstitialAdsSubject.addIfChanged(noAds); noBannerAndInterstitialAdsSubject.addIfChanged(noAds);
GuruSettings.instance.isNoAds.set(noAds); GuruSettings.instance.isNoAds.set(noAds);
GuruAnalytics.instance.setUserProperty("user_type", noAds ? "noads" : "default"); GuruAnalytics.instance
.setUserProperty("user_type", noAds ? "noads" : "default");
setProperty("user_type", noAds ? "noads" : "default"); setProperty("user_type", noAds ? "noads" : "default");
} }
void ensureInitialize() {} void ensureInitialize() {}
void listenIap() { void listenIap() {
final obs = Rx.combineLatest2<bool, AssetsStore<Asset>, Tuple2<bool, AssetsStore<Asset>>>( final obs = Rx.combineLatest2<bool, AssetsStore<Asset>,
Tuple2<bool, AssetsStore<Asset>>>(
IapManager.instance.observableAvailable, IapManager.instance.observableAvailable,
IapManager.instance.observableAssetStore, IapManager.instance.observableAssetStore,
(a, b) => Tuple2(a, b)); (a, b) => Tuple2(a, b));
@ -133,10 +153,11 @@ class AdsManager extends AdsManagerDelegate {
final available = tuple.item1; final available = tuple.item1;
final purchasedStore = tuple.item2; final purchasedStore = tuple.item2;
if (available && purchasedStore.isActive) { if (available && purchasedStore.isActive) {
final tempIsNoAds = final tempIsNoAds = purchasedStore
purchasedStore.existsAssets(GuruApp.instance.productProfile.noAdsCapIds); .existsAssets(GuruApp.instance.productProfile.noAdsCapIds);
final isNoAds = isPurchasedNoAd; final isNoAds = isPurchasedNoAd;
Log.i("purchased store changed active! tempIsNoAds:$tempIsNoAds isNoAds:$isNoAds", Log.i(
"purchased store changed active! tempIsNoAds:$tempIsNoAds isNoAds:$isNoAds",
syncFirebase: true); syncFirebase: true);
if (isNoAds != tempIsNoAds) { if (isNoAds != tempIsNoAds) {
if (!tempIsNoAds) { if (!tempIsNoAds) {
@ -149,57 +170,88 @@ class AdsManager extends AdsManagerDelegate {
} }
})); }));
} }
static bool initializedSdk = false;
Future initialize({SaasUser? saasUser}) async { Future initialize({SaasUser? saasUser}) async {
_adsProfileSubject.addEx(GuruApp.instance.adsProfile); _adsProfileSubject.addEx(GuruApp.instance.adsProfile);
await initEnv(); await initEnv();
await initSdk( final connected = await NetworkUtils.isNetworkConnected();
saasUser: saasUser, Log.d("adsManager initialize connected:$connected", tag: "Ads");
onInitialized: () { if (connected) {
// loadAds(); await initSdk(
adImpressionController.init(); saasUser: saasUser,
initLifecycleConnectivity(); onInitialized: () {
checkAndPreload(); // loadAds();
// GuruSettings.instance.totalLevelUp adImpressionController.init();
// .observe() checkAndPreload();
// .throttleTime(const Duration(seconds: 1)) // GuruSettings.instance.totalLevelUp
// .listen((count) { // .observe()
// checkAndPreload(); // .throttleTime(const Duration(seconds: 1))
// }); // .listen((count) {
// checkAndPreload();
// });
Log.i("ADS Initialized", tag: "Ads", syncFirebase: true); Log.i("ADS Initialized", tag: "Ads", syncFirebase: true);
}); });
} else {
NetworkUtils.observableConnectivityTrack.listen((track) async {
if (track.newResult != ConnectivityResult.none) {
if (!initializedSdk) {
initializedSdk = true;
await initSdk(onInitialized: () {
adImpressionController.init();
checkAndPreload();
Log.i("ADS Initialized", tag: "Ads", syncFirebase: true);
});
}
}
if (track.newResult != track.oldResult) {
Log.i("connectivity result changed! retry ads!", tag: "Ads");
setKeyword("connection", track.newResult.toString());
if (LifecycleManager.instance.isAppForeground()) {
if (track.newResult == ConnectivityResult.none &&
track.oldResult != ConnectivityResult.none) {
Log.i("connectivity changed! retry ads!", tag: "Ads");
retry();
}
}
}
});
}
subscriptions.add(RemoteConfigManager.instance.observeConfig().listen((_) { subscriptions.add(RemoteConfigManager.instance.observeConfig().listen((_) {
refreshAdsConfig(); refreshAdsConfig();
}, onError: (error, stacktrace) { }, onError: (error, stacktrace) {
Log.i("init config error!", tag: "Ads", error: error, stackTrace: stacktrace); Log.i("init config error!",
tag: "Ads", error: error, stackTrace: stacktrace);
})); }));
listenIap(); listenIap();
} }
void initLifecycleConnectivity() { // void initLifecycleConnectivity() {
StreamSubscription? streamSubscription; // StreamSubscription? streamSubscription;
LifecycleManager.instance.observableAppLifecycle.listen((foreground) { // LifecycleManager.instance.observableAppLifecycle.listen((foreground) {
if (foreground) { // if (foreground) {
streamSubscription = // streamSubscription = Connectivity()
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) { // .onConnectivityChanged
Log.i("Connectivity: $result", tag: "Connectivity"); // .listen((ConnectivityResult result) {
if (connectivityStatus == ConnectivityResult.none && result != ConnectivityResult.none) { // Log.i("Connectivity: $result", tag: "Connectivity");
Log.i("connectivity changed! retry ads!", tag: "Ads"); // if (connectivityStatus == ConnectivityResult.none &&
retry(); // result != ConnectivityResult.none) {
} // Log.i("connectivity changed! retry ads!", tag: "Ads");
final changed = connectivityStatusSubject.addIfChanged(result); // retry();
if (changed) { // }
setKeyword("connection", result.toString()); // final changed = connectivityStatusSubject.addIfChanged(result);
} // if (changed) {
}); // setKeyword("connection", result.toString());
} else { // }
streamSubscription?.cancel(); // });
streamSubscription = null; // } else {
} // streamSubscription?.cancel();
}); // streamSubscription = null;
} // }
// });
// }
void initAdsProfile() { void initAdsProfile() {
final _hasAmazonBannerAds = hasAmazonBannerAds; final _hasAmazonBannerAds = hasAmazonBannerAds;
@ -209,27 +261,33 @@ class AdsManager extends AdsManagerDelegate {
final strategyInterstitialIds = adsConfig.strategyAdsConfig.interstitialIds; final strategyInterstitialIds = adsConfig.strategyAdsConfig.interstitialIds;
final newAdsProfile = adsProfile.copyWith( final newAdsProfile = adsProfile.copyWith(
amazonAppId: _hasAmazonAds ? defaultAdsProfile.amazonAppId : null, amazonAppId: _hasAmazonAds ? defaultAdsProfile.amazonAppId : null,
amazonBannerSlotId: _hasAmazonBannerAds ? defaultAdsProfile.amazonBannerSlotId : null, amazonBannerSlotId:
amazonInterstitialSlotId: _hasAmazonBannerAds ? defaultAdsProfile.amazonBannerSlotId : null,
_hasAmazonInterstitialAds ? defaultAdsProfile.amazonInterstitialSlotId : null, amazonInterstitialSlotId: _hasAmazonInterstitialAds
? defaultAdsProfile.amazonInterstitialSlotId
: null,
strategyInterstitialIds: strategyInterstitialIds); strategyInterstitialIds: strategyInterstitialIds);
_adsProfileSubject.addEx(newAdsProfile); _adsProfileSubject.addEx(newAdsProfile);
} }
Future initEnv() async { Future initEnv() async {
final adsPropertyBundle = await AppProperty.getInstance().loadValuesByTag(PropertyTags.ads); final adsPropertyBundle =
await AppProperty.getInstance().loadValuesByTag(PropertyTags.ads);
final isNoAds = adsPropertyBundle.getBool(PropertyKeys.isNoAds) ?? false; final isNoAds = adsPropertyBundle.getBool(PropertyKeys.isNoAds) ?? false;
consentTestDeviceId = adsPropertyBundle.getString(PropertyKeys.admobConsentTestDeviceId); consentTestDeviceId =
consentDebugGeography = adsPropertyBundle.getInt(PropertyKeys.admobConsentDebugGeography); adsPropertyBundle.getString(PropertyKeys.admobConsentTestDeviceId);
consentDebugGeography =
adsPropertyBundle.getInt(PropertyKeys.admobConsentDebugGeography);
noBannerAndInterstitialAdsSubject.addIfChanged(isNoAds); noBannerAndInterstitialAdsSubject.addIfChanged(isNoAds);
GuruAnalytics.instance.setUserProperty("user_type", isNoAds ? "noads" : "default"); GuruAnalytics.instance
.setUserProperty("user_type", isNoAds ? "noads" : "default");
setProperty("user_type", isNoAds ? "noads" : "default"); setProperty("user_type", isNoAds ? "noads" : "default");
final result = await Connectivity().checkConnectivity().catchError((error) { final result = await Connectivity().checkConnectivity().catchError((error) {
Log.w("checkConnectivity error! $error"); Log.w("checkConnectivity error! $error");
}); });
connectivityStatusSubject.addEx(result); // connectivityStatusSubject.addEx(result);
setProperty("connectivityStatus", result.toString()); setProperty("connectivityStatus", result.toString());
refreshAdsConfig(); refreshAdsConfig();
@ -283,7 +341,8 @@ class AdsManager extends AdsManagerDelegate {
} }
void checkAndPreload( void checkAndPreload(
{AdsValidator? rewardedValidator, AdsValidator? interstitialValidator}) async { {AdsValidator? rewardedValidator,
AdsValidator? interstitialValidator}) async {
final canPreloadReward = final canPreloadReward =
await adsConfig.rewardedConfig.canPreload(validator: rewardedValidator); await adsConfig.rewardedConfig.canPreload(validator: rewardedValidator);
if (canPreloadReward) { if (canPreloadReward) {
@ -294,8 +353,8 @@ class AdsManager extends AdsManagerDelegate {
} }
} }
final canPreloadInterstitial = final canPreloadInterstitial = await adsConfig.interstitialConfig
await adsConfig.interstitialConfig.canPreload(validator: interstitialValidator); .canPreload(validator: interstitialValidator);
if (!isPurchasedNoAd && canPreloadInterstitial) { if (!isPurchasedNoAd && canPreloadInterstitial) {
Log.d("preload interstitial canPreload!"); Log.d("preload interstitial canPreload!");
final interstitial = await getInterstitialAds(); final interstitial = await getInterstitialAds();
@ -349,7 +408,9 @@ class AdsManager extends AdsManagerDelegate {
} }
await AppProperty.getInstance().setLatestLtDate(dateNum); await AppProperty.getInstance().setLatestLtDate(dateNum);
} }
final idx = _nearestLt(0, ltSamples.lastIndex, lt).abs().clamp(0, ltSamples.lastIndex); final idx = _nearestLt(0, ltSamples.lastIndex, lt)
.abs()
.clamp(0, ltSamples.lastIndex);
Log.d( Log.d(
"getKeywordLt: installTime:$latestLtDate now:$dateNum lt:$lt keywordLt:${ltSamples[idx]}"); "getKeywordLt: installTime:$latestLtDate now:$dateNum lt:$lt keywordLt:${ltSamples[idx]}");
@ -415,7 +476,8 @@ class AdsManager extends AdsManagerDelegate {
void setKeyword(String key, String value, {bool debugForce = false}) { void setKeyword(String key, String value, {bool debugForce = false}) {
if (!GuruSettings.instance.debugMode.get() || !debugForce) { if (!GuruSettings.instance.debugMode.get() || !debugForce) {
if (_reservedKeywords.contains(key)) { if (_reservedKeywords.contains(key)) {
Log.w("setKeyword error! the key($key) is reserved and cannot be used!", tag: "Ads"); Log.w("setKeyword error! the key($key) is reserved and cannot be used!",
tag: "Ads");
return; return;
} }
@ -423,7 +485,8 @@ class AdsManager extends AdsManagerDelegate {
key.length > 36 || key.length > 36 ||
key.indexOf(_alpha) != 0 || key.indexOf(_alpha) != 0 ||
key.contains(_nonAlphaNumeric)) { key.contains(_nonAlphaNumeric)) {
Log.w("setKeyword error! the key($key) must contain 1 to 36 alphanumeric characters.", Log.w(
"setKeyword error! the key($key) must contain 1 to 36 alphanumeric characters.",
tag: "Ads"); tag: "Ads");
return; return;
} }
@ -436,7 +499,9 @@ class AdsManager extends AdsManagerDelegate {
void removeKeyword(String key, {bool debugForce = false}) { void removeKeyword(String key, {bool debugForce = false}) {
if (!GuruSettings.instance.debugMode.get() || !debugForce) { if (!GuruSettings.instance.debugMode.get() || !debugForce) {
if (_reservedKeywords.contains(key)) { if (_reservedKeywords.contains(key)) {
Log.w("removeKeyword error! the key($key) is reserved and cannot be used!", tag: "Ads"); Log.w(
"removeKeyword error! the key($key) is reserved and cannot be used!",
tag: "Ads");
return; return;
} }
@ -444,7 +509,8 @@ class AdsManager extends AdsManagerDelegate {
key.length > 36 || key.length > 36 ||
key.indexOf(_alpha) != 0 || key.indexOf(_alpha) != 0 ||
key.contains(_nonAlphaNumeric)) { key.contains(_nonAlphaNumeric)) {
Log.w("removeKeyword error! the key($key) must contain 1 to 36 alphanumeric characters.", Log.w(
"removeKeyword error! the key($key) must contain 1 to 36 alphanumeric characters.",
tag: "Ads"); tag: "Ads");
return; return;
} }
@ -463,22 +529,28 @@ class AdsManager extends AdsManagerDelegate {
} }
bool testParseAdsDefaultConfig() { bool testParseAdsDefaultConfig() {
final iadsConfigString = RemoteConfigReservedConstants.getDefaultConfigString( final iadsConfigString =
RemoteConfigReservedConstants.iadsConfig) ?? RemoteConfigReservedConstants.getDefaultConfigString(
""; RemoteConfigReservedConstants.iadsConfig) ??
final radsConfigString = RemoteConfigReservedConstants.getDefaultConfigString( "";
RemoteConfigReservedConstants.radsConfig) ?? final radsConfigString =
""; RemoteConfigReservedConstants.getDefaultConfigString(
final badsConfigString = RemoteConfigReservedConstants.getDefaultConfigString( RemoteConfigReservedConstants.radsConfig) ??
RemoteConfigReservedConstants.badsConfig) ?? "";
""; final badsConfigString =
final iosAttConfigString = RemoteConfigReservedConstants.getDefaultConfigString( RemoteConfigReservedConstants.getDefaultConfigString(
RemoteConfigReservedConstants.iosAttConfig) ?? RemoteConfigReservedConstants.badsConfig) ??
""; "";
final iosAttConfigString =
RemoteConfigReservedConstants.getDefaultConfigString(
RemoteConfigReservedConstants.iosAttConfig) ??
"";
try { try {
final adInterstitial = AdInterstitialConfig.fromJson(json.decode(iadsConfigString)); final adInterstitial =
AdInterstitialConfig.fromJson(json.decode(iadsConfigString));
final adBanner = AdBannerConfig.fromJson(json.decode(badsConfigString)); final adBanner = AdBannerConfig.fromJson(json.decode(badsConfigString));
final iosAttConfig = IOSAttConfig.fromJson(json.decode(iosAttConfigString)); final iosAttConfig =
IOSAttConfig.fromJson(json.decode(iosAttConfigString));
Log.d("==== ADS AdsConfig ===="); Log.d("==== ADS AdsConfig ====");
Log.d(" ---> [INTERSTITIAL]: $iadsConfigString"); Log.d(" ---> [INTERSTITIAL]: $iadsConfigString");
Log.d(" ---> [BANNER]: $badsConfigString"); Log.d(" ---> [BANNER]: $badsConfigString");
@ -486,7 +558,9 @@ class AdsManager extends AdsManagerDelegate {
Log.d("======================="); Log.d("=======================");
_adsConfigSubject.addEx(AdsConfig.build( _adsConfigSubject.addEx(AdsConfig.build(
interstitialConfig: adInterstitial, bannerConfig: adBanner, iosAttConfig: iosAttConfig)); interstitialConfig: adInterstitial,
bannerConfig: adBanner,
iosAttConfig: iosAttConfig));
return true; return true;
} catch (error, stacktrace) { } catch (error, stacktrace) {
Log.e("refreshAdsConfig error $error $stacktrace"); Log.e("refreshAdsConfig error $error $stacktrace");
@ -500,14 +574,18 @@ class AdsManager extends AdsManagerDelegate {
final adInterstitial = RemoteConfigManager.instance.getIadsConfig(); final adInterstitial = RemoteConfigManager.instance.getIadsConfig();
final adReward = RemoteConfigManager.instance.getRadsConfig(); final adReward = RemoteConfigManager.instance.getRadsConfig();
final adBanner = RemoteConfigManager.instance.getBadsConfig(); final adBanner = RemoteConfigManager.instance.getBadsConfig();
final strategyAdsConfig = RemoteConfigManager.instance.getStrategyAdsConfig(); final strategyAdsConfig =
RemoteConfigManager.instance.getStrategyAdsConfig();
final iosAttConfig = RemoteConfigManager.instance.getIOSAttConfig(); final iosAttConfig = RemoteConfigManager.instance.getIOSAttConfig();
Log.d("==== ADS AdsConfig ====", tag: PropertyTags.ads); Log.d("==== ADS AdsConfig ====", tag: PropertyTags.ads);
Log.d(" ---> [COMMON]: ${commonAdsConfig.toJson()}", tag: PropertyTags.ads); Log.d(" ---> [COMMON]: ${commonAdsConfig.toJson()}",
Log.d(" ---> [INTERSTITIAL]: ${adInterstitial.toJson()}", tag: PropertyTags.ads); tag: PropertyTags.ads);
Log.d(" ---> [INTERSTITIAL]: ${adInterstitial.toJson()}",
tag: PropertyTags.ads);
Log.d(" ---> [REWARD]: ${adReward.toJson()}", tag: PropertyTags.ads); Log.d(" ---> [REWARD]: ${adReward.toJson()}", tag: PropertyTags.ads);
Log.d(" ---> [BANNER]: ${adBanner.toJson()}", tag: PropertyTags.ads); Log.d(" ---> [BANNER]: ${adBanner.toJson()}", tag: PropertyTags.ads);
Log.d(" ---> [STRATEGY]: ${strategyAdsConfig.toJson()}", tag: PropertyTags.ads); Log.d(" ---> [STRATEGY]: ${strategyAdsConfig.toJson()}",
tag: PropertyTags.ads);
Log.d(" ---> [IOSATT]: ${iosAttConfig.toJson()}", tag: PropertyTags.ads); Log.d(" ---> [IOSATT]: ${iosAttConfig.toJson()}", tag: PropertyTags.ads);
Log.d("=======================", tag: PropertyTags.ads); Log.d("=======================", tag: PropertyTags.ads);
_adsConfigSubject.addEx(AdsConfig.build( _adsConfigSubject.addEx(AdsConfig.build(
@ -535,14 +613,16 @@ class AdsManager extends AdsManagerDelegate {
MaxStrategyInterstitialAds.create(strategyInterstitialIds)..init(); MaxStrategyInterstitialAds.create(strategyInterstitialIds)..init();
} else { } else {
ad = interstitialAds[strategyInterstitialIds.first.adUnitId] ??= ad = interstitialAds[strategyInterstitialIds.first.adUnitId] ??=
ApplovinInterstitialAds.create(strategyInterstitialIds.first.adUnitId, ApplovinInterstitialAds.create(
strategyInterstitialIds.first.adUnitId,
strategyInterstitialIds.first.amazonAdSlotId) strategyInterstitialIds.first.amazonAdSlotId)
..init(); ..init();
} }
} else { } else {
ad = interstitialAds[_adsProfile.interstitialId] ??= ApplovinInterstitialAds.create( ad = interstitialAds[_adsProfile.interstitialId] ??=
_adsProfile.interstitialId, _adsProfile.amazonInterstitialSlotId) ApplovinInterstitialAds.create(
..init(); _adsProfile.interstitialId, _adsProfile.amazonInterstitialSlotId)
..init();
} }
return ad; return ad;
} }
@ -561,11 +641,13 @@ class AdsManager extends AdsManagerDelegate {
} }
Future<int> requestGdpr({int? debugGeography, String? testDeviceId}) async { Future<int> requestGdpr({int? debugGeography, String? testDeviceId}) async {
Log.d("requestGdpr! debugGeography:$debugGeography testDeviceId:$testDeviceId", tag: "Ads"); Log.d(
"requestGdpr! debugGeography:$debugGeography testDeviceId:$testDeviceId",
tag: "Ads");
// adb logcat -s UserMessagingPlatform // adb logcat -s UserMessagingPlatform
// Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("xxxx") to set this as a debug device. // Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("xxxx") to set this as a debug device.
final result = await GuruApplovinFlutter.instance final result = await GuruApplovinFlutter.instance.requestGdpr(
.requestGdpr(debugGeography: debugGeography, testDeviceId: testDeviceId); debugGeography: debugGeography, testDeviceId: testDeviceId);
final consentResult = await GuruAnalytics.instance.refreshConsents(); final consentResult = await GuruAnalytics.instance.refreshConsents();
Log.d("requestGdpr result:$result consentResult:$consentResult"); Log.d("requestGdpr result:$result consentResult:$consentResult");
return result; return result;
@ -576,14 +658,17 @@ class AdsManager extends AdsManagerDelegate {
} }
Future<bool> updateOrientation(int orientation) async { Future<bool> updateOrientation(int orientation) async {
final result = await GuruApplovinFlutter.instance.updateOrientation(orientation); final result =
await GuruApplovinFlutter.instance.updateOrientation(orientation);
return result == true; return result == true;
} }
@override @override
Future<ApplovinBannerAds> createBannerAds({String? scene, AdsLifecycleObserver? observer}) async { Future<ApplovinBannerAds> createBannerAds(
{String? scene, AdsLifecycleObserver? observer}) async {
final _adsProfile = adsProfile; final _adsProfile = adsProfile;
return ApplovinBannerAds.create(_adsProfile.bannerId, _adsProfile.amazonBannerSlotId, return ApplovinBannerAds.create(
_adsProfile.bannerId, _adsProfile.amazonBannerSlotId,
scene: scene, observer: observer); scene: scene, observer: observer);
} }
@ -593,8 +678,9 @@ class AdsManager extends AdsManagerDelegate {
} }
final hiddenAt = AdsManager.instance.latestFullscreenAdsHiddenTimestamps; final hiddenAt = AdsManager.instance.latestFullscreenAdsHiddenTimestamps;
final now = DateTimeUtils.currentTimeInMillis(); final now = DateTimeUtils.currentTimeInMillis();
final impGapInMillis = final impGapInMillis = AdsManager.instance.adsConfig.interstitialConfig
AdsManager.instance.adsConfig.interstitialConfig.getSceneImpGapInSeconds(scene) * 1000; .getSceneImpGapInSeconds(scene) *
1000;
Log.d( Log.d(
"canShowInterstitial($scene): now:$now latestFullscreenAdsHiddenTimestamps:$latestFullscreenAdsHiddenTimestamps hiddenAt:$hiddenAt impGapInMillis:$impGapInMillis", "canShowInterstitial($scene): now:$now latestFullscreenAdsHiddenTimestamps:$latestFullscreenAdsHiddenTimestamps hiddenAt:$hiddenAt impGapInMillis:$impGapInMillis",
tag: "Ads"); tag: "Ads");
@ -606,7 +692,8 @@ class AdsManager extends AdsManagerDelegate {
} }
@override @override
Future<AdCause> validateInterstitial(String? scene, {AdsValidator? validator}) { Future<AdCause> validateInterstitial(String? scene,
{AdsValidator? validator}) {
final interstitialConfig = adsConfig.interstitialConfig; final interstitialConfig = adsConfig.interstitialConfig;
return interstitialConfig.check(scene ?? "", validator: validator); return interstitialConfig.check(scene ?? "", validator: validator);
} }
@ -629,9 +716,11 @@ class AdsManager extends AdsManagerDelegate {
case "bannerAutoDisposeInterval": case "bannerAutoDisposeInterval":
return adsConfig.bannerConfig.autoDisposeIntervalInMinutes; return adsConfig.bannerConfig.autoDisposeIntervalInMinutes;
case "allowInterstitialAsAlternativeReward": case "allowInterstitialAsAlternativeReward":
return GuruApp.instance.appSpec.deployment.allowInterstitialAsAlternativeReward; return GuruApp
.instance.appSpec.deployment.allowInterstitialAsAlternativeReward;
case "showInternalAdsWhenBannerUnavailable": case "showInternalAdsWhenBannerUnavailable":
return GuruApp.instance.appSpec.deployment.showInternalAdsWhenBannerUnavailable; return GuruApp
.instance.appSpec.deployment.showInternalAdsWhenBannerUnavailable;
} }
} }
} }

View File

@ -44,6 +44,12 @@ class NetworkUtils {
static Stream<ConnectivityTrack> get observableConnectivityTrack => static Stream<ConnectivityTrack> get observableConnectivityTrack =>
_connectivityTrackSubject.stream; _connectivityTrackSubject.stream;
static ConnectivityResult get currentConnectivityStatus =>
_connectivityTrackSubject.value.newResult;
static Stream<ConnectivityResult> get observableConnectivityStatus =>
observableConnectivityTrack.map((event) => event.newResult);
static void setMockConnectivityStatus(ConnectivityResult? status) { static void setMockConnectivityStatus(ConnectivityResult? status) {
_mockConnectivityStatus = status; _mockConnectivityStatus = status;
} }