You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AppLovin MAX插屏广告后台切换后消失及singleTop启动模式引发的实例重复问题求助

AppLovin MAX插屏广告后台切换后消失及singleTop启动模式引发的实例重复问题求助

各位好,我现在遇到了两个关联的棘手问题,想请教下大家有没有解决思路:

  1. 插屏广告后台切换后消失的问题
    当AppLovin MAX的插屏广告正在展示时,如果用户把应用切到后台,再通过应用图标重新打开,广告直接消失了。我期望的是用户返回应用时,广告能从之前暂停的地方继续播放,而不是直接消失。

  2. 设置singleTop启动模式后的新问题
    为了解决上面的广告问题,我尝试在AndroidManifest里把Activity的launchMode改成了singleTop,这时候广告后台切换的问题确实好了,但又出现了新的异常:当我在MP3媒体文件的“打开方式”选项里选择我的应用时,后台会出现两个我的应用实例,这显然不符合预期。

我的环境信息

  • Flutter版本:3.22.0
  • applovin_max插件版本:4.5.0

初始化及广告相关代码

下面是我处理AppLovin MAX初始化、广告加载和监听的核心代码:

bool isInitialized = false;
bool isAdActive = false;
bool isFirstAdShowed = false;
bool isInterstitialFailed = false;
int? mRecViewId1, mRecViewId2, bannerViewId;
final String interstitialStartUnitId = "你的插屏广告单元ID";
final String mRecAdUnitId1 = "你的MRec广告单元ID1";
final String mRecAdUnitId2 = "你的MRec广告单元ID2";
final String bannerAdUnitId = "你的Banner广告单元ID";
final String appLovinSdkKey = "你的AppLovin SDK Key";
final String privacyUrl = "你的隐私政策URL";
final String termsUrl = "你的服务条款URL";

void init() async {
  if (!isInitialized) {
    if (locator.call<Preferences>().isUserFromGDPRCountry) {
      AppLovinMAX.setPrivacyPolicyUrl(privacyUrl);
      AppLovinMAX.setTermsOfServiceUrl(termsUrl);
      AppLovinMAX.setTermsAndPrivacyPolicyFlowEnabled(true);
    }
    AppLovinMAX.setHasUserConsent(true);
    var config = await AppLovinMAX.initialize(appLovinSdkKey);
    isInitialized = config != null;
  }

  if (locator.call<ProProvider>().isPro || !isInitialized) {
    return;
  }

  attachAdListeners();
  AppLovinMAX.loadInterstitial(interstitialStartUnitId);
  AppLovinMAX.preloadWidgetAdView(mRecAdUnitId1, AdFormat.mrec)
      .then((adViewId) => {mRecViewId1 = adViewId?.toInt()});
  AppLovinMAX.preloadWidgetAdView(mRecAdUnitId2, AdFormat.mrec)
      .then((adViewId) => {mRecViewId2 = adViewId?.toInt()});
  AppLovinMAX.preloadWidgetAdView(bannerAdUnitId, AdFormat.banner)
      .then((adViewId) => {bannerViewId = adViewId?.toInt()});
}

void attachAdListeners() async {
  _initInterstitialAdListener();
}

void _initInterstitialAdListener() {
  var interstitialRetryAttempt = 0;
  AppLovinMAX.setInterstitialListener(InterstitialListener(
    onAdLoadedCallback: (ad) {
      final logger = locator.call<Logger>();
      logger.info('Interstitial ad loaded from ${ad.networkName}');
      interstitialRetryAttempt = 0;
      if (isInterstitialFailed) {
        showInterstitialAd();
        return;
      }
      showInterstitialAd();
    },
    onAdLoadFailedCallback: (adUnitId, error) {
      interstitialRetryAttempt = interstitialRetryAttempt + 1;
      int retryDelay = pow(2, min(6, interstitialRetryAttempt)).toInt();
      locator.call<Logger>().error(
          'Interstitial ad failed to load with code ${error.code} - retrying in ${retryDelay}s');
      Future.delayed(Duration(milliseconds: retryDelay * 1000), () {
        AppLovinMAX.loadInterstitial(adUnitId);
      });
    },
    onAdDisplayedCallback: (MaxAd ad) {
      locator.call<VideoPlayerManager>().action?.call();
      locator.call<MP3Provider>().pauseMP3();
      locator.call<ThumbnailVideoPlayerBloc>().add(PauseCurrentVideo());
      isAdActive = true;
      isFirstAdShowed = true;
      isInterstitialFailed = false;
    },
    onAdDisplayFailedCallback: (MaxAd ad, MaxError error) {},
    onAdClickedCallback: (MaxAd ad) {},
    onAdHiddenCallback: (MaxAd ad) {
      isAdActive = false;
      timerManager.reset();
      AppLovinMAX.loadInterstitial(interstitialStartUnitId);
    },
  ));
}

void showInterstitialAd() async {
  _showInterstitial(interstitialStartUnitId);
}

void _showInterstitial(String adUnitId) async {
  if (locator.call<ProProvider>().isPro) {
    return;
  }
  bool isReady = await isAdReady(adUnitId);
  if (isReady) {
    var context = TubazyApp.navigatorKey.currentContext!;
    if (!context.mounted) return;
    showLoadingDialog(context);
    Future.delayed(const Duration(milliseconds: 350), () {
      if (Navigator.canPop(context)) {
        Navigator.of(context).pop();
      }
      AppLovinMAX.showInterstitial(adUnitId, placement: _interstitialType.name);
    });
  } else {
    isInterstitialFailed = true;
  }
}

// 辅助方法:判断插屏广告是否就绪
Future<bool> isAdReady(String adUnitId) async {
  return await AppLovinMAX.isInterstitialReady(adUnitId);
}

想请教的问题

  • 有没有办法在不设置singleTop的情况下,解决插屏广告后台切换后消失的问题?
  • 如果必须用singleTop,那怎么处理“打开方式”导致的应用实例重复问题?
  • 或者有没有其他的launchMode配置或者AppLovin插件的设置,可以同时兼顾这两个问题?

非常感谢大家的帮助!

内容来源于stack exchange

火山引擎 最新活动