I am trying to put an interstitial ad on one of the screens in my app. My banner ads work perfectly fine. However, whenever the app tries to load the ad, <_interstitial.load();>, it crashes.
Code with interstitial ad:
import 'package:quench/models/achievement.dart';import 'package:quench/models/user.dart';import 'package:quench/screens/achievements/achievement_list.dart';import 'package:flutter/material.dart';import 'package:quench/services/achievement_data.dart';import 'package:quench/shared/constants.dart';import 'package:quench/shared/loading.dart';import 'package:quench/services/user_data.dart';import 'package:google_mobile_ads/google_mobile_ads.dart';import 'package:provider/provider.dart';import 'package:quench/services/ad_state.dart';class Achievements extends StatefulWidget { @override _AchievementsState createState() => _AchievementsState();}class _AchievementsState extends State<Achievements> { bool firstTime = false; bool doneLoading = false; int currentWater = 0; int waterTotal = 0; var waterNeeded; String needText = ''; UserData userData = new UserData(); Achievement achievement = new Achievement(); InterstitialAd _interstitial = InterstitialAd( adUnitId: '', listener: AdListener(), request: AdRequest()); void initState() { super.initState(); _initializeData(); } @override void didChangeDependencies() { super.didChangeDependencies(); final adState = Provider.of<AdState>(context); adState.initialization.then((status) { setState(() { _interstitial = InterstitialAd( adUnitId: adState.interstitialAdUnitId, request: AdRequest(), listener: adState.adListenerInterstitial, ); _interstitial.load(); }); }); } void _update(int coins) { setState(() => userData.coins = coins); } @override Widget build(BuildContext context) { if (doneLoading == true) { return Scaffold( backgroundColor: Colors.blue[200], appBar: AppBar( title: Text('Achievements', style: heading, textAlign: TextAlign.left, ), centerTitle: true, leading: FittedBox( fit: BoxFit.contain, child: Text("Current Streak: ${userData.currentStreak}", style: basic, ), ), leadingWidth: 100, toolbarOpacity: 1, toolbarTextStyle: basic, backgroundColor: Colors.blueGrey[400], elevation: 0.0, ), body: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/bgImg5.png'), fit: BoxFit.cover), ), child: AchievementList( update: _update, ), ), floatingActionButton: FloatingActionButton( onPressed: () { //print('coins = ${userData.coins}'); _interstitial.show(); Navigator.pop(context); }, child: Icon(Icons.home), backgroundColor: Colors.grey[850], ), ); } else { return Loading(); } } resetData() { firstTime = true; } _initializeData() async { await AchievementDataSet().getAchievement(achievement); await UserDataSet().getUserData(userData); setState(() { doneLoading = true; }); }}
adState File:
import 'dart:io';import 'package:google_mobile_ads/google_mobile_ads.dart';class AdState { Future<InitializationStatus> initialization; AdState(this.initialization); String get bannerAdUnitId => Platform.isAndroid ? 'ca-app-pub-3940256099942544/6300978111' : 'ca-app-pub-3940256099942544/6300978111'; String get bannerAd2UnitId => Platform.isAndroid ? 'ca-app-pub-3940256099942544/6300978111' : 'ca-app-pub-3940256099942544/6300978111'; String get interstitialAdUnitId => Platform.isAndroid ? 'ca-app-pub-3940256099942544/1033173712' : 'ca-app-pub-3940256099942544/1033173712'; AdListener get adListener => _adListener; AdListener get adListenerInterstitial => _adListenerInterstitial; AdListener _adListener = AdListener( onAdLoaded: (ad) => print('Ad loaded: ${ad.adUnitId}'), onAdClosed: (ad) => print('Ad closed: ${ad.adUnitId}'), onAdFailedToLoad: (ad, error) => print('Ad failed to load: ${ad.adUnitId}, $error'), onAdOpened: (ad) => print('Ad opened: ${ad.adUnitId}'), onAppEvent: (ad, name, data) => print('App event: ${ad.adUnitId}, $name, $data'), onApplicationExit: (ad) => print('App Exit: ${ad.adUnitId}'), onNativeAdClicked: (nativeAd) => print('Native ad clicked: ${nativeAd.adUnitId}'), onNativeAdImpression: (nativeAd) => print('Native ad impression: ${nativeAd.adUnitId}'), onRewardedAdUserEarnedReward: (ad, reward) => print('User rewarded: ${ad.adUnitId}'), ); AdListener _adListenerInterstitial = AdListener( onAdLoaded: (ad) => print('Ad loaded: ${ad.adUnitId}'), onAdClosed: (ad) { print('Ad closed: ${ad.adUnitId}'); ad.dispose(); }, onAdFailedToLoad: (ad, error) { print('Ad failed to load: ${ad.adUnitId}, $error'); ad.dispose(); }, onAdOpened: (ad) => print('Ad opened: ${ad.adUnitId}'), onAppEvent: (ad, name, data) => print('App event: ${ad.adUnitId}, $name, $data'), onApplicationExit: (ad) => print('App Exit: ${ad.adUnitId}'), onNativeAdClicked: (nativeAd) => print('Native ad clicked: ${nativeAd.adUnitId}'), onNativeAdImpression: (nativeAd) => print('Native ad impression: ${nativeAd.adUnitId}'), onRewardedAdUserEarnedReward: (ad, reward) => print('User rewarded: ${ad.adUnitId}'), );}
Ignore the incorrect AdIDs for IOs; I am using test ads and only testing on Android right now.
android/app/src/main/AndroidManifest.xml :
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="klein.kodes.quench"><application android:label="Quench" android:icon="@mipmap/ic_launcher"><activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"><!-- Specifies an Android theme to apply to this Activity as soon as the Android process has started. This theme is visible to the user while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --><meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /><!-- Displays an Android View that continues showing the launch screen Drawable until Flutter paints its first frame, then this splash screen fades out. A splash screen is useful to avoid any visual gap between the end of Android's launch screen and the painting of Flutter's first frame. --><meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" /><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity><!-- Don't delete the meta-data below. This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --><meta-data android:name="flutterEmbedding" android:value="2" /><!-- Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 --><meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-8898143771871274~9426656973"/></application></manifest>
android/app/build.gradle
def localProperties = new Properties()def localPropertiesFile = rootProject.file('local.properties')if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) }}def flutterRoot = localProperties.getProperty('flutter.sdk')if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")}def flutterVersionCode = localProperties.getProperty('flutter.versionCode')if (flutterVersionCode == null) { flutterVersionCode = '1'}def flutterVersionName = localProperties.getProperty('flutter.versionName')if (flutterVersionName == null) { flutterVersionName = '1.0'}apply plugin: 'com.android.application'apply plugin: 'kotlin-android'apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"android { compileSdkVersion 30 sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "klein.kodes.quench" minSdkVersion 19 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } }}flutter { source '../..'}dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'com.google.android.gms:play-services-ads:20.1.0'}
android/build.gradle:
buildscript { ext.kotlin_version = '1.3.50' repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:4.1.0' classpath 'com.google.gms:google-services:4.2.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" }}allprojects { repositories { google() jcenter() }}rootProject.buildDir = '../build'subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}"}subprojects { project.evaluationDependsOn(':app')}task clean(type: Delete) { delete rootProject.buildDir}
Debug Log:
Launching lib\main.dart on SM J600G in debug mode...Parameter format not correct -Note: Some input files use or override a deprecated API.Note: Recompile with -Xlint:deprecation for details.√ Built build\app\outputs\flutter-apk\app-debug.apk.Connecting to VM Service at ws://127.0.0.1:61558/sMmjrllrJ40=/wsI/in.kodes.quenc(26619): The ClassLoaderContext is a special shared library.I/chatty (26619): uid=10217(klein.kodes.quench) identical 1 lineI/in.kodes.quenc(26619): The ClassLoaderContext is a special shared library.I/DynamiteModule(26619): Considering local module com.google.android.gms.ads.dynamite:0 and remote module com.google.android.gms.ads.dynamite:210890500I/DynamiteModule(26619): Selected remote version of com.google.android.gms.ads.dynamite, version >= 210890500D/DynamitePackage(26619): Instantiated singleton DynamitePackage.D/DynamitePackage(26619): Instantiating com.google.android.gms.ads.ChimeraMobileAdsSettingManagerCreatorImplD/ConnectivityManager(26619): requestNetwork; CallingUid : 10217, CallingPid : 26619I/Ads (26619): Updating ad debug logging enablement.I/WebViewFactory(26619): Loading com.android.chrome version 89.0.4389.105 (code 438910520)W/in.kodes.quenc(26619): Accessing hidden method Landroid/os/Trace;->isTagEnabled(J)Z (light greylist, reflection)W/in.kodes.quenc(26619): Accessing hidden method Landroid/os/Trace;->traceBegin(JLjava/lang/String;)V (light greylist, reflection)W/in.kodes.quenc(26619): Accessing hidden method Landroid/os/Trace;->traceEnd(J)V (light greylist, reflection)W/in.kodes.quenc(26619): Accessing hidden method Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V (light greylist, reflection)W/in.kodes.quenc(26619): Accessing hidden method Landroid/os/Trace;->asyncTraceEnd(JLjava/lang/String;I)V (light greylist, reflection)I/cr_LibraryLoader(26619): Loaded native library version number "89.0.4389.105"I/cr_CachingUmaRecorder(26619): Flushed 4 samples from 4 histograms.W/in.kodes.quenc(26619): Accessing hidden method Landroid/content/Context;->bindServiceAsUser(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/Handler;Landroid/os/UserHandle;)Z (light greylist, reflection)D/NetworkManagementSocketTagger(26619): tagSocket(127) with statsTag=0x108, statsUid=-1D/ConnectivityManager(26619): requestNetwork; CallingUid : 10217, CallingPid : 26619D/NetworkManagementSocketTagger(26619): tagSocket(145) with statsTag=0x108, statsUid=-1D/ConnectivityManager(26619): requestNetwork; CallingUid : 10217, CallingPid : 26619D/NetworkManagementSocketTagger(26619): tagSocket(145) with statsTag=0x108, statsUid=-1W/in.kodes.quenc(26619): Accessing hidden method Landroid/media/AudioManager;->getOutputLatency(I)I (light greylist, reflection)W/cr_media(26619): Requires BLUETOOTH permissionW/Ads (26619): Update ad debug logging enablement as falseD/NetworkManagementSocketTagger(26619): tagSocket(159) with statsTag=0xffffffff, statsUid=-1D/NetworkManagementSocketTagger(26619): tagSocket(167) with statsTag=0xffffffff, statsUid=-1I/flutter (26619): same dayI/flutter (26619): check 4D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1I/ (26619): Increase max job count 40D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 0D/ViewRootImpl@c380cd1[MainActivity](26619): ViewPostIme pointer 1I/flutter (26619): Max Streak : 0, 2021-05-06 10:56:32.980484E/AndroidRuntime(26619): FATAL EXCEPTION: mainE/AndroidRuntime(26619): Process: klein.kodes.quench, PID: 26619E/AndroidRuntime(26619): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/ads/InterstitialAd;E/AndroidRuntime(26619): at io.flutter.plugins.googlemobileads.FlutterInterstitialAd.load(FlutterInterstitialAd.java:70)E/AndroidRuntime(26619): at io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.onMethodCall(GoogleMobileAdsPlugin.java:299)E/AndroidRuntime(26619): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)E/AndroidRuntime(26619): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)E/AndroidRuntime(26619): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:819)E/AndroidRuntime(26619): at android.os.MessageQueue.nativePollOnce(Native Method)E/AndroidRuntime(26619): at android.os.MessageQueue.next(MessageQueue.java:326)E/AndroidRuntime(26619): at android.os.Looper.loop(Looper.java:181)E/AndroidRuntime(26619): at android.app.ActivityThread.main(ActivityThread.java:7081)E/AndroidRuntime(26619): at java.lang.reflect.Method.invoke(Native Method)E/AndroidRuntime(26619): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)E/AndroidRuntime(26619): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)E/AndroidRuntime(26619): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.ads.InterstitialAd" on path: DexPathList[[zip file "/data/app/klein.kodes.quench-yIS9R3wjPZR-N464Be9ATw==/base.apk"],nativeLibraryDirectories=[/data/app/klein.kodes.quench-yIS9R3wjPZR-N464Be9ATw==/lib/arm, /data/app/klein.kodes.quench-yIS9R3wjPZR-N464Be9ATw==/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]E/AndroidRuntime(26619): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)E/AndroidRuntime(26619): at java.lang.ClassLoader.loadClass(ClassLoader.java:379)E/AndroidRuntime(26619): at java.lang.ClassLoader.loadClass(ClassLoader.java:312)E/AndroidRuntime(26619): ... 12 moreLost connection to device.Exited (sigterm)
Any and all help is greatly appreciated. Thanks.