How To Add AdMob To Flutter App Quick Tutorial
This tutorial shows you a quick way to add AdMob ad to your Flutter app. It's inspired by this article Adding AdMob ads to a Flutter app , a great example.
In AdMob, you need to provide your app's specific app ID and ad unit ID. But we use test IDs in this tutorial code. And always use test IDs to try out first when you implement your AdMob.
Otherwise lots of things will happen unexpectedly. Ads might not show up after several hours, several days, or even several weeks. Ads might show up in emulator but not in real devices. Ads might not show up until you settle down your AdMob payment. Ads might show up only after you publish app to play store.
By using test IDs, when your AdMob is working everywhere, you know you did everything right. If after replacing with your own IDs, AdMob doesn't work properly, you know it's AdMob's issue.
So let's get started.
Open Android Studio and create a new Flutter project. Then we get this famous Flutter "incrementCounter" example.
We'll add a bottom banner to this Android app. Once you know how to do this, you can easily add Interstitial and Rewarded ads or apply it to IOS apps.
1. Add Firebase_AdMob Dependency To File pubspec.yaml
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.3
# TODO: Add the following line
firebase_admob: ^0.9.3
Click "Pub get" to download it.
2. Update AndroidManifest.xml
Locate file AndroidManifest.xml here:
...
<!-- Add this meta-data here.
This is test ID. Replace with your AdMob app ID later. -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~4354546703"/>
</application>
</manifest>
3. Create New Dart File ad_manager.dart
Right click "lib" - "new" - "dart file". Enter "ad_manager.dart" to create new dart file.
import 'dart:io';
class AdManager {
// TODO: These are all TEST IDs. Replace with your own IDs later.
static String get appId {
if (Platform.isAndroid) {
return "ca-app-pub-3940256099942544~4354546703";
} else if (Platform.isIOS) {
return "ca-app-pub-3940256099942544~2594085930";
} else {
throw new UnsupportedError("Unsupported platform");
}
}
static String get bannerAdUnitId {
if (Platform.isAndroid) {
return "ca-app-pub-3940256099942544/8865242552";
} else if (Platform.isIOS) {
return "ca-app-pub-3940256099942544/4339318960";
} else {
throw new UnsupportedError("Unsupported platform");
}
}
static String get interstitialAdUnitId {
if (Platform.isAndroid) {
return "ca-app-pub-3940256099942544/7049598008";
} else if (Platform.isIOS) {
return "ca-app-pub-3940256099942544/3964253750";
} else {
throw new UnsupportedError("Unsupported platform");
}
}
static String get rewardedAdUnitId {
if (Platform.isAndroid) {
return "ca-app-pub-3940256099942544/8673189370";
} else if (Platform.isIOS) {
return "ca-app-pub-3940256099942544/7552160883";
} else {
throw new UnsupportedError("Unsupported platform");
}
}
}
4. Import Packages
In your main.dart:
import 'package:flutter/material.dart';
// TODO: Import ad_manager.dart,replace with your package name
import 'package:flutter_admob_tutorial/ad_manager.dart';
// TODO: Import firebase_admob.dart
import 'package:firebase_admob/firebase_admob.dart';
5. Initialize AdMob
AdMob takes time to load. So initialize it in the beginning.
void main() {
// TODO: Add these 2 lines to Initialize AdMob SDK
WidgetsFlutterBinding.ensureInitialized();
_initAdMob();
runApp(MyApp());
}
// TODO: Add right after main()
Future<void> _initAdMob() {
return FirebaseAdMob.instance.initialize(appId: AdManager.appId);
}
6. Add Banner Ad
If you have multiple pages/routes in your app, you need to add the following codes to each page where you want to place an ad.
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
// TODO: Add _bannerAd
BannerAd _bannerAd;
// TODO Add initState() if not exist
@override
void initState() {
super.initState();
// TODO: Initialize _bannerAd
_bannerAd = BannerAd(
adUnitId: AdManager.bannerAdUnitId,
size: AdSize.banner,
);
// TODO: Load a Banner Ad
_bannerAd
..load()
..show(anchorType: AnchorType.bottom);
}
// TODO: Dispose BannerAd object
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
} // end of TODO
That's it. Run the demo. You'll see a test banner ad at the bottom.
(Note: if you have some error/warning, try to follow some extra steps at the end of this article.)
Well there's a problem here. The banner ad overlaps with the floating action button. To fix it, we can lift up the floating button 50 pixels by wrapping it with a Padding.
In main.dart, find FloatingActionButton in blue font. Click it and from the left light bulb select "Wrap with Padding".
Then change padding EdgeInsets to "only bottom 50".
floatingActionButton: Padding(
padding: const EdgeInsets.only(bottom: 50),
child: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
Now run the app. You'll see the floating action button is above the banner ad.
Another good practice is making your content scroll-able by using ListView etc.
7. Obtain Your App ID And Ad Unit ID
Now follow the above mentioned article Adding AdMob ads to a Flutter app until you download your google-services.json file
and get the app ID and ad unit IDs for your own app. Replace those test IDs in AndroidManifest.xml and ad_manager.dart.
Below is the complete main.dart code:
import 'package:flutter/material.dart';
// TODO: Import ad_manager.dart,replace with your package name
import 'package:flutter_admob_tutorial/ad_manager.dart';
// TODO: Import firebase_admob.dart
import 'package:firebase_admob/firebase_admob.dart';
void main() {
// TODO: Add these 2 lines to Initialize AdMob SDK
WidgetsFlutterBinding.ensureInitialized();
_initAdMob();
runApp(MyApp());
}
// TODO: Add right after main()
Future<void> _initAdMob() {
return FirebaseAdMob.instance.initialize(appId: AdManager.appId);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter AdMob Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
// TODO: Add _bannerAd
BannerAd _bannerAd;
// TODO Add initState() if not exist
@override
void initState() {
super.initState();
// TODO: Initialize _bannerAd
_bannerAd = BannerAd(
adUnitId: AdManager.bannerAdUnitId,
size: AdSize.banner,
);
// TODO: Load a Banner Ad
_bannerAd
..load()
..show(anchorType: AnchorType.bottom);
}
// TODO: Dispose BannerAd object
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
} // end of TODO
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: Padding(
padding: const EdgeInsets.only(bottom: 50),
child: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
}
If the console give you some error/warning, try these steps:
1. Click top menu "File" - "Project Structure...".
Make sure Android API 29 is selected and nothing under "Problems".
2. Update android/settings.gradle
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
3.Update 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 FileNotFoundException("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 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.haoc.flutter_admob_tutorial"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
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.android.support:multidex:1.0.3'
}
// The End
very nice! would be nice to extend this tutorial as well for iOS :)
ReplyDelete