Flutter 应用添加 AdMob 广告教程 2020
这个教程讲解在 Flutter 应用中快速添加 AdMob 广告。主要参考了这篇文章:Adding AdMob ads to a Flutter app , 予以感谢。
要添加 AdMob 广告,你要先去 AdMob 注册你的应用,得到你的应用 ID 和广告单元 ID。这个教程里我们使用测试用 ID。你在添加 AdMob 广告时也要尽量先用测试 ID 来检测你的程序。
如果不用测试 ID ,很多意想不到的情况会发生。广告部件可能在几小时,几天甚至几个星期后才出现。广告可能会在模拟器上出现,真实设备上却完全没有。广告可能在你解决好 AdMob 支付设置后才会出现。广告也可能当你在 play store 发布你的应用后才会出现。
如果你用测试 ID,而且你的 AdMob 广告都运行正常,你就知道你每个地方都做对了。如果换上真实 ID 后广告没有正常运转,你就知道这不是你的问题,是 AdMob 那边有问题。
那么就让我们开始吧。
打开 Android Studio 并新建一个 Flutter 项目,我们就会进入著名的 Flutter 演示程序 "incrementCounter" 。
我们会在这个安卓应用底部添加一个长条 banner 广告。如果你弄明白了如何添加 banner 广告,你就能很容易添加 Interstitial(全屏)广告和 Rewarded(奖励)广告,也可以应用于 IOS 应用。
1. 添加 Firebase_AdMob Dependency 到文件 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: 添加这一行
firebase_admob: ^0.9.3
点 "Pub get" 下载。
2. 更新 AndroidManifest.xml 文件
AndroidManifest.xml 文件在这里:
...<!-- 这里添加 meta-data.
这个是测试ID. 成功后再替换为你自己的AdMob应用ID. -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~4354546703"/>
</application>
</manifest>
3. 创建一个新 Dart 文件 ad_manager.dart
右击 "lib" - "new" - "dart file". 输入 "ad_manager.dart" 以建立新文件。
import 'dart:io';
class AdManager {
// TODO: 这里全是测试ID. 成功后替换为你的ID.
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. 导入 Packages
在文件 main.dart 里:
import 'package:flutter/material.dart';
// TODO: 导入ad_manager.dart文件,目录改为你的package名字
import 'package:flutter_admob_tutorial/ad_manager.dart';
// TODO: 导入 firebase_admob.dart
import 'package:firebase_admob/firebase_admob.dart';
5. 初始化 AdMob
AdMob 要花时间启动。所以程序一开始就初始化。
void main() {
// TODO: 这2行启动AdMob SDK
WidgetsFlutterBinding.ensureInitialized();
_initAdMob();
runApp(MyApp());
}
// TODO: 在 main()后添加这个函数
Future<void> _initAdMob() {
return FirebaseAdMob.instance.initialize(appId: AdManager.appId);
}
6. 添加横幅 Banner 广告
如果你的应用不止一页,每一页都要添加这些代码。
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
// TODO: 声明变量
BannerAd _bannerAd;
// TODO:如果没有 initState() 就新建一个
@override
void initState() {
super.initState();
// TODO: 初始化 _bannerAd
_bannerAd = BannerAd(
adUnitId: AdManager.bannerAdUnitId,
size: AdSize.banner,
);
// TODO: 加载 Banner 广告
_bannerAd
..load()
..show(anchorType: AnchorType.bottom); // 位置可以是顶部,底部等
}
// TODO: 关闭 BannerAd
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
} // end of TODO
这样就全部做好了。运行一下,底部有了一个 banner 广告。
(注意:如果出现红色错误/警告,试一下本文末尾的解决方法。)
这里有一个问题,banner 广告和原来的蓝色按钮重叠了。解决它很容易,只要把按钮包在一个 Padding 里,让按钮升高50像素。
回到 main.dart,找到蓝色字体的 FloatingActionButton 并点击,在左边的灯泡中选择 "Wrap with Padding"。
把 padding 的 EdgeInsets 参数改为 "only bottom 50"。
floatingActionButton: Padding(
padding: const EdgeInsets.only(bottom: 50),
child: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
现在运行一下程序,可以看到没有重叠了。
另外一种解决方法是让页面内容上下可滑动,比如使用 ListView 部件等。
7. 获得你的应用 ID 和广告单元 ID
回到上面提到的文章 Adding AdMob ads to a Flutter app ,跟着里面的步骤做,直到你下载了 google-services.json 文件,并获得了应用 ID 和广告单元 ID。用这些 ID 替换AndroidManifest.xml 和 ad_manager.dart 文件里测试 ID。
下面是 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';
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),
),
),
);
}
}
附:
运行时如果系统提示有错误/警告,试一下这些方法:
1. 打开菜单 "File" - "Project Structure...".
确保 Android API 29 已被选择,"Problems" 下没有如何条目。
2. 更新 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.更新 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'
}
// 完


评论
发表评论