Giles  Goodwin

Giles Goodwin

1600761954

Why is database continuous integration important?

Why is database continuous integration important?

A very common tenet used when building out a DevOps style approach to automated deployment is the concept of failing fast. You want to identify issues with the changes in your code and structures as early as possible to protect the production environment. One of the most common methods to meet this requirement is setting up a Continuous Integration (CI) environment. The need for CI is not only for application code. Integrating changes to database code and components as often as possible and testing the results of those changes makes problems visible early and fast.

CI doesn’t get rid of bugs, but it does make them dramatically easier to find and remove if the team can be sure that the cause is one of the changes that were made since the last successful integration. If a developer’s code has introduced an error or has caused another developer’s previously working piece of code to fail, then the team knows immediately. No further integrations occur until the issue is fixed.

Why is integration so important?

All applications are made up of components. Even an application hand-crafted from procedural code will depend on third-party components, frameworks, libraries, operating-system interfaces, data sources and databases. At the other extreme, the custom application could be a mashup of standard off-the-shelf applications.

All components are liable to upgrades and changes, especially during active development. Each time any component of an application changes to a new version, you must perform a complete build on all parts of the application that rely on that component, followed by integration, with its integration tests. With a rapidly changing application, integration must be continuous to prove, continuously, that nothing has been broken as a result of any change.

Any change to the application code requires integration, as does any change to a third-party component. Where does the database fit? From the application-perspective, the database is just another component, and a typical corporate application can be dependent on a handful of databases. A database change merely triggers the same work as any other component. The application integration tests must prove that all database access methods continue to perform correctly, according to the database interface specification.

From the database perspective, it is, in effect, an application, with its own hierarchy of components on which it depends. Just as for an application, any change to the database code or components should prompt a fresh build, followed by integration and its tests.

The purpose of Database CI, then, is precisely the same as for application CI. The development team establish a working version of the database very early in the development cycle and then continue to verify regularly that it remains in a working state as they expand and refactor the schema and database code objects. Developers integrate new and changed code into a shared version control repository several times a day. Development proceeds in small steps. Developers first write the tests that, if passed, will prove that a small new piece of functionality works. They then implement the code to make the tests pass. When the tests pass, they commit the code to “trunk” in the shared VCS, and their “commit tests” are added to the broader suite of tests for the application. Each commit, or check-in, is then verified by an automated database build or migration, and subsequent testing, allowing teams to detect problems early.

#devops #editorials #homepage #automate #automated delivery #automation #continuous integration #devops

What is GEEK

Buddha Community

Why is database continuous integration important?
Kole  Haag

Kole Haag

1602404645

What is database continuous integration?

Have you ever longed for a way of making the delivery of databases more visible, predictable and measurable? Do you ever wish that they would be of better quality, quicker to change, and cost less? Grant Fritchey explains some of the secrets of doing Continuous Integration for Databases to relieve some of the pain-points of the Database Delivery process.

Continuous Integration (CI) is an essential step of application development for DevOps organisations. Whenever a developer commits code, a build is kicked off. The code must compile and pass automated testing before it is merged into the main branch. Developers have been working this way for years, but including the database in CI has lagged behind. Leaving the database out of CI has caused it to become the bottleneck that slows down the delivery of new features. Even though it’s more difficult to execute, many organizations have successfully implemented database CI with the right tools.

The purpose of Database CI is exactly the same as for application CI. The development team establish a working version of the database very early in the development cycle, and then continue to verify regularly that it remains in a working state as they expand and refactor the schema and database code objects. Developers integrate new and changed code into a shared version control repository several times a day. Development proceeds in small steps. Developers first write the tests that, if passed, will prove that a small new piece of functionality works. They then implement the code to make the tests pass. When the tests pass, they commit the code to “trunk” in the shared VCS, and their “commit tests” are added to the broader suite of tests for the application. Each commit, or check-in, is then verified by an automated database build or migration, and subsequent testing, allowing teams to detect problems early.

Where do you start with database CI? There are several requirements outlined here.

Maintain the database in version control

The first prerequisite for Database CI is that the source of “truth” for the database CI process and all subsequent database deployments must be the build and migration scripts in a version control system (VCS), such as Git or Subversion. In other words, the database CI process must always be triggered from the VCS. There must be no ad-hoc builds or database modifications that bypass this formal process.

There are several CI management software services available. Each one I’ve worked with has hooks into various version control systems. With these hooks you can set up mechanisms for automating your database CI processes.

#database delivery #database devops #continuous integration #database #dlm_ebook #sql

Ruth  Nabimanya

Ruth Nabimanya

1620633584

System Databases in SQL Server

Introduction

In SSMS, we many of may noticed System Databases under the Database Folder. But how many of us knows its purpose?. In this article lets discuss about the System Databases in SQL Server.

System Database

Fig. 1 System Databases

There are five system databases, these databases are created while installing SQL Server.

  • Master
  • Model
  • MSDB
  • Tempdb
  • Resource
Master
  • This database contains all the System level Information in SQL Server. The Information in form of Meta data.
  • Because of this master database, we are able to access the SQL Server (On premise SQL Server)
Model
  • This database is used as a template for new databases.
  • Whenever a new database is created, initially a copy of model database is what created as new database.
MSDB
  • This database is where a service called SQL Server Agent stores its data.
  • SQL server Agent is in charge of automation, which includes entities such as jobs, schedules, and alerts.
TempDB
  • The Tempdb is where SQL Server stores temporary data such as work tables, sort space, row versioning information and etc.
  • User can create their own version of temporary tables and those are stored in Tempdb.
  • But this database is destroyed and recreated every time when we restart the instance of SQL Server.
Resource
  • The resource database is a hidden, read only database that holds the definitions of all system objects.
  • When we query system object in a database, they appear to reside in the sys schema of the local database, but in actually their definitions reside in the resource db.

#sql server #master system database #model system database #msdb system database #sql server system databases #ssms #system database #system databases in sql server #tempdb system database

Siphiwe  Nair

Siphiwe Nair

1625133780

SingleStore: The One Stop Shop For Everything Data

  • SingleStore works toward helping businesses embrace digital innovation by operationalising “all data through one platform for all the moments that matter”

The pandemic has brought a period of transformation across businesses globally, pushing data and analytics to the forefront of decision making. Starting from enabling advanced data-driven operations to creating intelligent workflows, enterprise leaders have been looking to transform every part of their organisation.

SingleStore is one of the leading companies in the world, offering a unified database to facilitate fast analytics for organisations looking to embrace diverse data and accelerate their innovations. It provides an SQL platform to help companies aggregate, manage, and use the vast trove of data distributed across silos in multiple clouds and on-premise environments.

**Your expertise needed! **Fill up our quick Survey

#featured #data analytics #data warehouse augmentation #database #database management #fast analytics #memsql #modern database #modernising data platforms #one stop shop for data #singlestore #singlestore data analytics #singlestore database #singlestore one stop shop for data #singlestore unified database #sql #sql database

Flutter Foreground Service on The Android Platform

This plugin is used to implement a foreground service on the Android platform.

Features

  • Can perform repetitive task with foreground service notification.
  • Provides useful utilities (minimizeApp, wakeUpScreen, etc.) that can use when performing task.
  • Provides a widget that prevents the app from closing when a foreground task is running.
  • Provides a widget that can start a foreground task when trying to minimize or close the app.
  • Can automatically resume foreground task at boot time.

Getting started

To use this plugin, add flutter_foreground_task as a dependency in your pubspec.yaml file. For example:

dependencies:
  flutter_foreground_task: ^2.2.1

After adding the flutter_foreground_task plugin to the flutter project, we need to specify the permissions and services to use for this plugin to work properly.

:baby_chick: Android

Since this plugin is based on a foreground service, we need to add the following permission to the AndroidManifest.xml file. Open the AndroidManifest.xml file and specify it between the <manifest> and <application> tags.

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

And we need to add this permission to automatically resume foreground task at boot time.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

And specify the service inside the <application> tag as follows.

<service android:name="com.pravera.flutter_foreground_task.service.ForegroundService" />

:baby_chick: iOS

We can also launch flutter_foreground_task on iOS platform. However, it has the following limitations.

  • Works only on iOS 10.0 or later.
  • If the app is forcibly closed, the task will not work.
  • Task cannot be started automatically on device reboot.

Objective-C:

To use this plugin developed in Swift language in a project using Objective-C, you need to add a bridge header. If you don't have an ios/Runner/Runner-Bridging-Header.h file in your project, check this page.

Open the ios/Runner/AppDelegate.swift file and add the commented code.

#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"

// here
#import <flutter_foreground_task/FlutterForegroundTaskPlugin.h>

// here
void registerPlugins(NSObject<FlutterPluginRegistry>* registry) {
  [GeneratedPluginRegistrant registerWithRegistry:registry];
}

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  [FlutterForegroundTaskPlugin setPluginRegistrantCallback:registerPlugins];  // here
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

Swift:

  1. Declare the import statement below in the ios/Runner/Runner-Bridging-Header.h file.
#import <flutter_foreground_task/FlutterForegroundTaskPlugin.h>
  1. Open the ios/Runner/AppDelegate.swift file and add the commented code.
import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    SwiftFlutterForegroundTaskPlugin.setPluginRegistrantCallback(registerPlugins)   // here
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

// here
func registerPlugins(registry: FlutterPluginRegistry) {
  GeneratedPluginRegistrant.register(with: registry)
}

How to use

This plugin has two ways to start a foreground task. There are two ways to start the foreground task manually and to start it when the app is minimized or closed by the WillStartForegroundTask widget.

:hatched_chick: Start manually

  1. Initialize the FlutterForegroundTask. FlutterForegroundTask.init() provides notification and task options, detailed options are as follows:
  • androidNotificationOptions: Notification options for Android platform.
  • iosNotificationOptions: Notification options for iOS platform.
  • foregroundTaskOptions: Options for setting the foreground task behavior in detail.
  • printDevLog: Whether to show the developer log. If this value is set to true, you can see logs of the activity (start, stop, etc) of the flutter_foreground_task plugin. It does not work in release mode. The default is false.
void _initForegroundTask() {
  FlutterForegroundTask.init(
    androidNotificationOptions: AndroidNotificationOptions(
      channelId: 'notification_channel_id',
      channelName: 'Foreground Notification',
      channelDescription: 'This notification appears when a foreground task is running.',
      channelImportance: NotificationChannelImportance.LOW,
      priority: NotificationPriority.LOW,
      iconData: NotificationIconData(
        resType: ResourceType.mipmap,
        resPrefix: ResourcePrefix.ic,
        name: 'launcher',
      ),
    ),
    iosNotificationOptions: IOSNotificationOptions(
      showNotification: true,
      playSound: false,
    ),
    foregroundTaskOptions: ForegroundTaskOptions(
      interval: 5000,
      autoRunOnBoot: true,
    ),
    printDevLog: true,
  );
}

@override
void initState() {
  super.initState();
  _initForegroundTask();
}
  1. Add WithForegroundTask widget to prevent the app from closing when a foreground task is running.
@override
Widget build(BuildContext context) {
  return MaterialApp(
    // A widget that prevents the app from closing when a foreground task is running.
    // Declare on top of the [Scaffold] widget.
    home: WithForegroundTask(
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Foreground Task'),
          centerTitle: true,
        ),
        body: buildContentView(),
      ),
    ),
  );
}
  1. Write a foreground task start callback function and start the FlutterForegroundTask. FlutterForegroundTask.start() provides the following options:
  • notificationTitle: The title that will be displayed in the notification.
  • notificationText: The text that will be displayed in the notification.
  • callback: A top-level function that calls the initDispatcher function.
// The callback function should always be a top-level function.
void startCallback() {
  // The initDispatcher function must be called to handle the task in the background.
  // And the code to be executed except for the variable declaration
  // must be written inside the initDispatcher function.
  FlutterForegroundTask.initDispatcher((timestamp, sendPort) async {
    final strTimestamp = timestamp.toString();
    print('timestamp: $strTimestamp');

    // Send data to the main isolate.
    sendPort?.send(timestamp);
  }, onDestroy: (timestamp) async {
    print('Dispatcher is dead.. x_x');
  });
}

class ExampleApp extends StatefulWidget {
  @override
  _ExampleAppState createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
  ReceivePort? _receivePort;

  // ...

  void _startForegroundTask() async {
    _receivePort = FlutterForegroundTask.start(
      notificationTitle: 'Foreground task is running',
      notificationText: 'Tap to return to the app',
      callback: startCallback,
    );

    _receivePort?.listen((message) {
      if (message is DateTime)
        print('receive timestamp: $message');
    });
  }

  @override
  void dispose() {
    _receivePort?.close();
    super.dispose();
  }
}

If the plugin you want to use provides a stream, use it like this:

void startCallback() {
  final positionStream = Geolocator.getPositionStream();
  StreamSubscription<Position>? streamSubscription;

  FlutterForegroundTask.initDispatcher((timestamp, sendPort) async {
    if (streamSubscription != null) return;

    streamSubscription = positionStream.listen((event) {
      print('timestamp: ${timestamp.toString()}');

      FlutterForegroundTask.update(
          notificationTitle: 'Current Position',
          notificationText: '${event.latitude}, ${event.longitude}');
    });
  }, onDestroy: (timestamp) async {
    await streamSubscription?.cancel();
    print('Dispatcher is dead.. x_x');
  });
}
  1. Use FlutterForegroundTask.update() to update the foreground task. The options are the same as the start function.
// The callback function should always be a top-level function.
void startCallback() {
  int updateCount = 0;

  FlutterForegroundTask.initDispatcher((timestamp, sendPort) async {
    final strTimestamp = timestamp.toString();
    print('startCallback - timestamp: $strTimestamp');

    FlutterForegroundTask.update(
        notificationTitle: 'startCallback',
        notificationText: strTimestamp,
        callback: updateCount >= 10 ? updateCallback : null);

    updateCount++;
  }, onDestroy: (timestamp) async {
    print('Dispatcher is dead.. x_x');
  });
}

void updateCallback() {
  FlutterForegroundTask.initDispatcher((timestamp, sendPort) async {
    final strTimestamp = timestamp.toString();
    print('updateCallback - timestamp: $strTimestamp');

    FlutterForegroundTask.update(
        notificationTitle: 'updateCallback',
        notificationText: strTimestamp);
  }, onDestroy: (timestamp) async {
    print('Dispatcher is dead.. x_x');
  });
}
  1. When you have completed the required foreground task, call FlutterForegroundTask.stop().
void _stopForegroundTask() {
  FlutterForegroundTask.stop();
}

:hatched_chick: Start with WillStartForegroundTask widget

@override
Widget build(BuildContext context) {
  return MaterialApp(
    // A widget used when you want to start a foreground task when trying to minimize or close the app.
    // Declare on top of the [Scaffold] widget.
    home: WillStartForegroundTask(
      onWillStart: () {
        // Please return whether to start the foreground task.
        return true;
      },
      androidNotificationOptions: AndroidNotificationOptions(
        channelId: 'notification_channel_id',
        channelName: 'Foreground Notification',
        channelDescription: 'This notification appears when a foreground task is running.',
        channelImportance: NotificationChannelImportance.LOW,
        priority: NotificationPriority.LOW,
        iconData: NotificationIconData(
          resType: ResourceType.mipmap,
          resPrefix: ResourcePrefix.ic,
          name: 'launcher',
        ),
      ),
      iosNotificationOptions: IOSNotificationOptions(
        showNotification: true,
        playSound: false,
      ),
      foregroundTaskOptions: ForegroundTaskOptions(
        interval: 5000,
        autoRunOnBoot: false,
      ),
      printDevLog: true,
      notificationTitle: 'Foreground task is running',
      notificationText: 'Tap to return to the app',
      callback: callback,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Foreground Task'),
          centerTitle: true,
        ),
        body: buildContentView(),
      ),
    ),
  );
}

Models

:chicken: AndroidNotificationOptions

Notification options for Android platform.

PropertyDescription
channelIdUnique ID of the notification channel.
channelNameThe name of the notification channel. This value is displayed to the user in the notification settings.
channelDescriptionThe description of the notification channel. This value is displayed to the user in the notification settings.
channelImportanceThe importance of the notification channel. The default is NotificationChannelImportance.DEFAULT.
priorityPriority of notifications for Android 7.1 and lower. The default is NotificationPriority.DEFAULT.
enableVibrationWhether to enable vibration when creating notifications. The default is false.
playSoundWhether to play sound when creating notifications. The default is false.
showWhenWhether to show the timestamp when the notification was created in the content view. The default is false.
visibilityControl the level of detail displayed in notifications on the lock screen. The default is NotificationVisibility.VISIBILITY_PUBLIC.
iconDataThe data of the icon to display in the notification. If the value is null, the app launcher icon is used.

:chicken: NotificationIconData

Data for setting the notification icon.

PropertyDescription
resTypeThe resource type of the notification icon. If the resource is in the drawable folder, set it to ResourceType.drawable, if the resource is in the mipmap folder, set it to ResourceType.mipmap.
resPrefixThe resource prefix of the notification icon. If the notification icon name is ic_simple_notification, set it to ResourcePrefix.ic and set name to simple_notification.
nameNotification icon name without prefix.

:chicken: ResourceType

The resource type of the notification icon.

ValueDescription
drawableA resources in the drawable folder. The drawable folder is where all kinds of images are stored.
mipmapA resources in the mipmap folder. The mipmap folder is usually where the launcher icon image is stored.

:chicken: ResourcePrefix

The resource prefix of the notification icon.

ValueDescription
icA resources with the ic_ prefix.
imgA resources with the img_ prefix.

:chicken: IOSNotificationOptions

Notification options for iOS platform.

PropertyDescription
showNotificationWhether to show notifications. The default is true.
playSoundWhether to play sound when creating notifications. The default is false.

:chicken: ForegroundTaskOptions

Data class with foreground task options.

PropertyDescription
intervalThe task call interval in milliseconds. The default is 5000.
autoRunOnBootWhether to automatically run foreground task on boot. The default is false

:chicken: NotificationChannelImportance

The importance of the notification channel. See https://developer.android.com/training/notify-user/channels?hl=ko#importance

ValueDescription
NONEA notification with no importance: does not show in the shade.
MINMin notification importance: only shows in the shade, below the fold.
LOWLow notification importance: shows in the shade, and potentially in the status bar (see shouldHideSilentStatusBarIcons()), but is not audibly intrusive.
DEFAULTDefault notification importance: shows everywhere, makes noise, but does not visually intrude.
HIGHHigher notification importance: shows everywhere, makes noise and peeks. May use full screen intents.
MAXMax notification importance: same as HIGH, but generally not used.

:chicken: NotificationPriority

Priority of notifications for Android 7.1 and lower.

ValueDescription
MINNo sound and does not appear in the status bar.
LOWNo sound.
DEFAULTMakes a sound.
HIGHMakes a sound and appears as a heads-up notification.
MAXSame as HIGH, but used when you want to notify notification immediately.

:chicken: NotificationVisibility

The level of detail displayed in notifications on the lock screen.

ValueDescription
VISIBILITY_PUBLICShow this notification in its entirety on all lockscreens.
VISIBILITY_SECRETDo not reveal any part of this notification on a secure lockscreen.
VISIBILITY_PRIVATEShow this notification on all lockscreens, but conceal sensitive or private information on secure lockscreens.

Utility methods

:lollipop: minimizeApp

Minimize the app to the background.

import 'package:flutter_foreground_task/flutter_foreground_task.dart';

void function() {
  FlutterForegroundTask.minimizeApp();
}

:lollipop: wakeUpScreen

Wake up the screen of a device that is turned off.

import 'package:flutter_foreground_task/flutter_foreground_task.dart';

void function() {
  FlutterForegroundTask.wakeUpScreen();
}

:lollipop: isIgnoringBatteryOptimizations

Returns whether the app has been excluded from battery optimization.

import 'package:flutter_foreground_task/flutter_foreground_task.dart';

void function() async {
  var isIgnoring = await FlutterForegroundTask.isIgnoringBatteryOptimizations;
}

:lollipop: openIgnoreBatteryOptimizationSettings

Open the settings page where you can set ignore battery optimization.

import 'package:flutter_foreground_task/flutter_foreground_task.dart';

void function() async {
  var isIgnoring = await FlutterForegroundTask.openIgnoreBatteryOptimizationSettings();
}

Support

If you find any bugs or issues while using the plugin, please register an issues on GitHub. You can also contact us at hwj930513@naver.com.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add flutter_foreground_task

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):


dependencies:
  flutter_foreground_task: ^2.2.1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:flutter_foreground_task/flutter_foreground_task.dart'; 

example/lib/main.dart

import 'dart:isolate';

import 'package:flutter/material.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';

void main() => runApp(ExampleApp());

// The callback function should always be a top-level function.
void startCallback() {
  int updateCount = 0;

  // The initDispatcher function must be called to handle the task in the background.
  // And the code to be executed except for the variable declaration
  // must be written inside the initDispatcher function.
  FlutterForegroundTask.initDispatcher((timestamp, sendPort) async {
    final strTimestamp = timestamp.toString();
    print('startCallback - timestamp: $strTimestamp');

    FlutterForegroundTask.update(
        notificationTitle: 'startCallback',
        notificationText: strTimestamp,
        callback: updateCount >= 10 ? updateCallback : null);

    // Send data to the main isolate.
    sendPort?.send(timestamp);
    sendPort?.send(updateCount);

    updateCount++;
  }, onDestroy: (timestamp) async {
    print('Dispatcher is dead.. x_x');
  });
}

void updateCallback() {
  FlutterForegroundTask.initDispatcher((timestamp, sendPort) async {
    final strTimestamp = timestamp.toString();
    print('updateCallback - timestamp: $strTimestamp');

    FlutterForegroundTask.update(
        notificationTitle: 'updateCallback',
        notificationText: strTimestamp);
  }, onDestroy: (timestamp) async {
    print('Dispatcher is dead.. x_x');
  });
}

class ExampleApp extends StatefulWidget {
  @override
  _ExampleAppState createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
  ReceivePort? _receivePort;

  void _initForegroundTask() {
    FlutterForegroundTask.init(
      androidNotificationOptions: AndroidNotificationOptions(
        channelId: 'notification_channel_id',
        channelName: 'Foreground Notification',
        channelDescription: 'This notification appears when a foreground task is running.',
        channelImportance: NotificationChannelImportance.LOW,
        priority: NotificationPriority.LOW,
        iconData: NotificationIconData(
          resType: ResourceType.mipmap,
          resPrefix: ResourcePrefix.ic,
          name: 'launcher',
        ),
      ),
      iosNotificationOptions: IOSNotificationOptions(
        showNotification: true,
        playSound: false,
      ),
      foregroundTaskOptions: ForegroundTaskOptions(
        interval: 5000,
        autoRunOnBoot: true,
      ),
      printDevLog: true,
    );
  }

  void _startForegroundTask() async {
    _receivePort = await FlutterForegroundTask.start(
      notificationTitle: 'Foreground task is running',
      notificationText: 'Tap to return to the app',
      callback: startCallback,
    );

    _receivePort?.listen((message) {
      if (message is DateTime)
        print('receive timestamp: $message');
      else if (message is int)
        print('receive updateCount: $message');
    });
  }
  
  void _stopForegroundTask() {
    FlutterForegroundTask.stop();
  }

  @override
  void initState() {
    super.initState();
    _initForegroundTask();
  }

  @override
  void dispose() {
    _receivePort?.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // A widget that prevents the app from closing when a foreground task is running.
      // Declare on top of the [Scaffold] widget.
      home: WithForegroundTask(
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Flutter Foreground Task'),
            centerTitle: true,
          ),
          body: _buildContentView(),
        ),
      ),
    );
  }

  Widget _buildContentView() {
    final buttonBuilder = (String text, {VoidCallback? onPressed}) {
      return ElevatedButton(
        child: Text(text),
        onPressed: onPressed,
      );
    };

    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          buttonBuilder('start', onPressed: _startForegroundTask),
          buttonBuilder('stop', onPressed: _stopForegroundTask),
        ],
      ),
    );
  }
}

Download Details:

Author: Dev-hwang

Source Code: https://github.com/Dev-hwang/flutter_foreground_task

#flutter #foreground 

Flutter Dev

Flutter Dev

1630146472

A Flutter Plugin for the Google Mobile Ads SDK

Google Mobile Ads for Flutter

This guide is intended for publishers who want to monetize a Flutter app.

Integrating Google Mobile Ads SDK into a Flutter app, which you will do here, is the first step towards displaying AdMob ads and earning revenue. Once the integration is complete, you can choose an ad format to get detailed implementation steps.

The Google Mobile Ads SDK for Flutter currently supports loading and displaying banner, interstitial (full-screen), native ads, and rewarded video ads.

Note: This plugin also contains support for Google Ad Manager. If you are interested in creating and loading an Ad with Ad Manager, you may follow the same prerequisites, platform setup, mobile ads SDK initialization steps outlined in this doc, and then see creating and loading an ad with Ad Manager for further instructions.

See also the codelab for inline ads in Flutter for a detailed guide on setting inline banner and native ads.

Prerequisites

  • Flutter 1.22.0 or higher
  • Android
    • Android Studio 3.2 or higher
    • Target Android API level 19 or higher
    • Set compileSdkVersion to 28 or higher
    • Android Gradle Plugin 4.1 or higher (this is the version supported by Flutter out of the box)
  • Ios
  • Recommended: Create an AdMob account and register an Android and/or iOS app (To show live ads on a published app, it is required to register that app).

Import the Mobile Ads SDK

Platform Specific Setup

iOS

Update your Info.plist

Update your app's ios/Runner/Info.plist file to add two keys:

  • A GADApplicationIdentifier key with a string value of your AdMob app ID (identified in the AdMob UI).
  • A SKAdNetworkItems key with Google's SKAdNetworkIdentifier value of cstr6suwn9.skadnetwork.
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
<key>SKAdNetworkItems</key>
  <array>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>cstr6suwn9.skadnetwork</string>
    </dict>
  </array>

See https://developers.google.com/admob/ios/quick-start#update_your_infoplist for more information about configuring Info.plist and setting up your App ID.

Android

Update AndroidManifest.xml

The AdMob App ID must be included in the AndroidManifest.xml. Failure to do so will result in a crash on launch of an app.

Add the AdMob App ID (identified in the AdMob UI) to the app's android/app/src/main/AndroidManifest.xml file by adding a <meta-data> tag with name com.google.android.gms.ads.APPLICATION_ID, as shown below. You can find your App ID in the AdMob UI. For android:value insert your own AdMob App ID in quotes, as shown below.

<manifest>
    <application>
        <!-- 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-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
    </application>
</manifest>

The same value when you initialize the plugin in your Dart code.

See https://goo.gl/fQ2neu for more information about configuring AndroidManifest.xml and setting up the App ID.

Initialize the Mobile Ads SDK

Before loading ads, have your app initialize the Mobile Ads SDK by calling MobileAds.instance.initialize() which initializes the SDK and returns a Future that finishes once initialization is complete (or after a 30-second timeout). This needs to be done only once, ideally right before running the app.

import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter/material.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();

  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    // Load ads.
  }
}

Select an Ad Format

The Mobile Ads SDK is now imported and you're ready to implement an ad. AdMob offers a number of different ad formats, so you can choose the one that best fits your app's user experience.

  • Banner
    • Rectangular ads that appear at the top or bottom of the device screen. Banner ads stay on screen while users are interacting with the app, and can refresh automatically after a certain period of time. If you're new to mobile advertising, they're a great place to start.
  • Interstitial
    • Full-screen ads that cover the interface of an app until closed by the user. They're best used at natural pauses in the flow of an app's execution, such as between levels of a game or just after a task is completed.
  • Native Ads
    • Customizable ads that match the look and feel of your app. You decide how and where they're placed, so the layout is more consistent with your app's design.
  • Rewarded
    • Ads that reward users for watching short videos and interacting with playable ads and surveys. Good for monetizing free-to-play users.

Banner Ads

Banner ads occupy a spot within an app's layout, either at the top or bottom of the device screen. They stay on screen while users are interacting with the app, and can refresh automatically after a certain period of time.

This guide shows you how to integrate banner ads from AdMob into a Flutter app. In addition to code snippets and instructions, it also includes information about sizing banners properly and links to additional resources.

See also the codelab for inline ads in Flutter for a detailed guide on setting up banner ads.

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for banners:

  • Android: https://developers.google.com/admob/android/test-ads#sample_ad_units
  • iOS: https://developers.google.com/admob/ios/test-ads#demo_ad_units

It's been specially configured to return test ads for every request, and you're free to use it in your own apps while coding, testing, and debugging. Just make sure you replace it with your own ad unit ID before publishing your app.

Instantiate a Banner Ad

A BannerAd requires an adUnitId, an AdSize, an AdRequest, and a BannerAdListener. An example is shown below as well as more information on each parameter following.

final BannerAd myBanner = BannerAd(
  adUnitId: '<ad unit id>',
  size: AdSize.banner,
  request: AdRequest(),
  listener: BannerAdListener(),
);

Banner Sizes

The table below lists the standard banner sizes.

Size in dp (WxH)DescriptionAdSize Constant
320x50Standard Bannerbanner
320x100Large BannerlargeBanner
320x250Medium RectanglemediumRectangle
468x60Full-Size BannerfullBanner
728x90Leaderboardleaderboard
Screen width x 32|50|90Smart BannerUse getSmartBanner(Orientation)
Provided width x Adaptive heightAdaptive BannerUse getAnchoredAdaptiveBannerAdSize(Orientation, int)

To define a custom banner size, set your desired AdSize, as shown here:

final AdSize adSize = AdSize(300, 50);

Banner Ad Events

Through the use of BannerAdListener, you can listen for lifecycle events, such as when an ad is loaded. This example implements each method and logs a message to the console:

final BannerAdListener listener = BannerAdListener(
 // Called when an ad is successfully received.
 onAdLoaded: (Ad ad) => print('Ad loaded.'),
 // Called when an ad request failed.
 onAdFailedToLoad: (Ad ad, LoadAdError error) {
   // Dispose the ad here to free resources.
   ad.dispose();
   print('Ad failed to load: $error');
 },
 // Called when an ad opens an overlay that covers the screen.
 onAdOpened: (Ad ad) => print('Ad opened.'),
 // Called when an ad removes an overlay that covers the screen.
 onAdClosed: (Ad ad) => print('Ad closed.'),
 // Called when an impression occurs on the ad.
 onAdImpression: (Ad ad) => print('Ad impression.'),
);

Load Banner Ad

After a BannerAd is instantiated, load() must be called before it can be shown on the screen.

myBanner.load();

Display a Banner Ad

To display a BannerAd as a widget, you must instantiate an AdWidget with a supported ad after calling load(). You can create the widget before calling load(), but load() must be called before adding it to the widget tree.

final AdWidget adWidget = AdWidget(ad: myBanner);

AdWidget inherits from Flutter's Widget class and can be used as any other widget. On iOS, make sure you place the widget in a widget with a specified width and height. Otherwise, your Ad may not be displayed. A BannerAd can be placed in a container with a size that matches the ad:

final Container adContainer = Container(
  alignment: Alignment.center,
  child: adWidget,
  width: myBanner.size.width.toDouble(),
  height: myBanner.size.height.toDouble(),
);

Once an Ad has called load(), it must call dispose() when access to it is no longer needed. The best practice for when to call dispose() is either after the AdWidget is removed from the widget tree or in the AdListener.onAdFailedToLoad callback.

That's it! Your app is now ready to display banner ads.

Interstitial Ad

Interstitial ads are full-screen ads that cover the interface of their host app. They're typically displayed at natural transition points in the flow of an app, such as between activities or during the pause between levels in a game. When an app shows an interstitial ad, the user has the choice to either tap on the ad and continue to its destination or close it and return to the app.

This guide explains how to integrate interstitial ads into a Flutter app.

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for interstitials:

  • Android: https://developers.google.com/admob/android/test-ads#sample_ad_units
  • iOS: https://developers.google.com/admob/ios/test-ads#demo_ad_units

It's been specially configured to return test ads for every request, and you're free to use it in your own apps while coding, testing, and debugging. Just make sure you replace it with your own ad unit ID before publishing your app.

Load an Interstitial Ad

Loading an InterstitialAd requires an adUnitId, an AdRequest, and an InterstitialAdLoadCallback. An example is shown below as well as more information on each parameter following.


InterstitialAd.load(
  adUnitId: '<ad unit id>',
  request: AdRequest(),
  adLoadCallback: InterstitialAdLoadCallback(
    onAdLoaded: (InterstitialAd ad) {
      // Keep a reference to the ad so you can show it later.
      this._interstitialAd = ad;
    },
    onAdFailedToLoad: (LoadAdError error) {
      print('InterstitialAd failed to load: $error');
    },
  ));

Interstitial Ad Events

Through the use of FullScreenContentCallback, you can listen for lifecycle events, such as when the ad is shown or dismissed. Set InterstitialAd.fullScreenContentCallback before showing the ad to receive notifications for these events. This example implements each method and logs a message to the console:

interstitialAd.fullScreenContentCallback = FullScreenContentCallback(
  onAdShowedFullScreenContent: (InterstitialAd ad) =>
     print('$ad onAdShowedFullScreenContent.'),
  onAdDismissedFullScreenContent: (InterstitialAd ad) {
    print('$ad onAdDismissedFullScreenContent.');
    ad.dispose();
  },
  onAdFailedToShowFullScreenContent: (InterstitialAd ad, AdError error) {
    print('$ad onAdFailedToShowFullScreenContent: $error');
    ad.dispose();
  },
  onAdImpression: (InterstitialAd ad) => print('$ad impression occurred.'),
);

Display an Interstitial Ad

An InterstitialAd is displayed as an Overlay on top of all app content and is statically placed. Which means it can not be added to the Flutter widget tree. You can choose when to show the ad by calling show().

myInterstitial.show();

Once show() is called, an Ad displayed this way can't be removed programmatically and requires user input. An InterstitialAd can only be shown once. Subsequent calls to show will trigger onAdFailedToShowFullScreenContent.

Once an ad has called load(), it must call dispose() when access to it is no longer needed. The best practice for when to call dispose() is in the FullScreenContentCallback.onAdDismissedFullScreenContent and FullScreenContentCallback.onAdFailedToShowFullScreenContent callbacks.

That's it! Your app is now ready to display interstitial ads.

Next steps

Native Ads

Native ads are ad assets that are presented to users via UI components that are native to the platform. They're shown using the same types of views with which you're already building your layouts, and can be formatted to match the visual design of the user experience in which they live. In coding terms, this means that when a native ad loads, your app receives a NativeAd object that contains its assets, and the app (rather than the Google Mobile Ads SDK) is then responsible for displaying them.

Broadly speaking, there are two parts to successfully implementing Native Ads: loading an ad via the SDK and displaying the ad content in your app. This guide is concerned with using the SDK to load native ads.

See also the codelab for inline ads in Flutter for a detailed guide on setting up native ads.

Platform Setup

Native Ads are presented to users via UI components that are native to the platform. (e.g. A View on Android or a UIView on iOS).

Since Native Ads require UI components native to a platform, this feature requires additional setup for Android and iOS:

Android

The Android implementation of the Google Mobile Ads plugin requires a class that implements a NativeAdFactory. A NativeAdFactory contains a method that takes a NativeAd and custom options and returns a NativeAdView. The NativeAdView is what will be displayed in your app.

You can implement this in your MainActivity.java or create a separate class in the same directory as MainActivity.java as seen below:

package my.app.path;

import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory;
import java.util.Map;

class NativeAdFactoryExample implements NativeAdFactory {
  @Override
  public NativeAdView createNativeAd(
      NativeAd nativeAd, Map<String, Object> customOptions) {
    // Create NativeAdView
  }
}

Each NativeAdFactory needs to be registered with a factoryId, a unique String identifier, in MainActivity.configureFlutterEngine(FlutterEngine). A NativeAdFactory can be implemented and registered for each unique Native ad layout used by your app or a single one can handle all layouts. The NativeAdFactory should also be unregistered in cleanUpFlutterEngine(engine) when building with add-to-app.

MainActivity.java should look similar to:

package my.app.path;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;

public class MainActivity extends FlutterActivity {
  @Override
  public void configureFlutterEngine(FlutterEngine flutterEngine) {
    flutterEngine.getPlugins().add(new GoogleMobileAdsPlugin());
   super.configureFlutterEngine(flutterEngine);

    GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "adFactoryExample", NativeAdFactoryExample());
  }

  @Override
  public void cleanUpFlutterEngine(FlutterEngine flutterEngine) {
    GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "adFactoryExample");
  }
}

When creating the NativeAd in Dart, the factoryId will need to match the one used to add the factory to GoogleMobileAdsPlugin. In the above code snippet, adFactoryExample is the name of the factoryId. An example NativeAdFactory follows:

package io.flutter.plugins.googlemobileadsexample;

import android.graphics.Color;
import android.view.LayoutInflater;
import android.widget.TextView;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory;
import java.util.Map;

// my_native_ad.xml can be found at
/* https://github.com/googleads/googleads-mobile-flutter/tree/master/packages/google_mobile_ads/example/android/app/src/main/res/layout
*/
class NativeAdFactoryExample implements NativeAdFactory {
 private final LayoutInflater layoutInflater;

 NativeAdFactoryExample(LayoutInflater layoutInflater) {
   this.layoutInflater = layoutInflater;
 }

 @Override
 public NativeAdView createNativeAd(
     NativeAd nativeAd, Map<String, Object> customOptions) {
   final NativeAdView adView =
       (NativeAdView) layoutInflater.inflate(R.layout.my_native_ad, null);
   final TextView headlineView = adView.findViewById(R.id.ad_headline);
   final TextView bodyView = adView.findViewById(R.id.ad_body);

   headlineView.setText(nativeAd.getHeadline());
   bodyView.setText(nativeAd.getBody());

   adView.setBackgroundColor(Color.YELLOW);

   adView.setNativeAd(nativeAd);
   adView.setBodyView(bodyView);
   adView.setHeadlineView(headlineView);
   return adView;
 }
}

iOS

The iOS implementation of the Google Mobile Ads plugin requires a class that implements a FLTNativeAdFactory. A FLTNativeAdFactory contains a method that takes a GADNativeAd and custom options and returns a GADNativeAdView. The GADNativeAdView is what will be displayed in your app.

The FLTNativeAdFactory protocol can be implemented by AppDelegate or a separate class could be created as seen below:

/* AppDelegate.m */
#import "FLTGoogleMobileAdsPlugin.h"
@interface NativeAdFactoryExample : NSObject<FLTNativeAdFactory>
@end

@implementation NativeAdFactoryExample
- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
                             customOptions:(NSDictionary *)customOptions {
  // Create GADNativeAdView
}
@end

Each FLTNativeAdFactory needs to be registered with a factoryId, a unique String identifier, in registerNativeAdFactory:factoryId:nativeAdFactory:. A FLTNativeAdFactory can be implemented and registered for each unique Native ad layout used by your app or a single one can handle all layouts. This is done by importing FLTGoogleMobileAdsPlugin.h and calling registerNativeAdFactory:factoryId:nativeAdFactory: with a FlutterPluginRegistry, a unique identifier for the factory, and the factory itself. The factory also MUST be added after [GeneratedPluginRegistrant registerWithRegistry:self]; has been called.

If this is done in AppDelegate.m, it should look similar to:

#import "FLTGoogleMobileAdsPlugin.h"

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];

  NativeAdFactoryExample *nativeAdFactory = [[NativeAdFactoryExample alloc] init];
  [FLTGoogleMobileAdsPlugin registerNativeAdFactory:self
                                        factoryId:@"adFactoryExample"
                                  nativeAdFactory:nativeAdFactory];

  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end

When creating the NativeAd in Dart, the factoryID will need to match the one used to add the factory to FLTGoogleMobileAdsPlugin. In the above code snippet, adFactoryExample is the name of the factoryID.An exampleFLTNativeAdFactory` follows:

// The example NativeAdView.xib can be found at
/* https://github.com/googleads/googleads-mobile-flutter/blob/master/packages/google_mobile_ads/example/ios/Runner/NativeAdView.xib
*/
@interface NativeAdFactoryExample : NSObject <FLTNativeAdFactory>
@end

@implementation NativeAdFactoryExample
- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
                            customOptions:(NSDictionary *)customOptions {
 // Create and place ad in view hierarchy.
 GADNativeAdView *adView =
     [[NSBundle mainBundle] loadNibNamed:@"NativeAdView" owner:nil options:nil].firstObject;

 // Associate the native ad view with the native ad object. This is
 // required to make the ad clickable.
 adView.nativeAd = nativeAd;

 // Populate the native ad view with the native ad assets.
 // The headline is guaranteed to be present in every native ad.
 ((UILabel *)adView.headlineView).text = nativeAd.headline;

 // These assets are not guaranteed to be present. Check that they are before
 // showing or hiding them.
 ((UILabel *)adView.bodyView).text = nativeAd.body;
 adView.bodyView.hidden = nativeAd.body ? NO : YES;

 [((UIButton *)adView.callToActionView) setTitle:nativeAd.callToAction
                                        forState:UIControlStateNormal];
 adView.callToActionView.hidden = nativeAd.callToAction ? NO : YES;

 ((UIImageView *)adView.iconView).image = nativeAd.icon.image;
 adView.iconView.hidden = nativeAd.icon ? NO : YES;

 ((UILabel *)adView.storeView).text = nativeAd.store;
 adView.storeView.hidden = nativeAd.store ? NO : YES;

 ((UILabel *)adView.priceView).text = nativeAd.price;
 adView.priceView.hidden = nativeAd.price ? NO : YES;

 ((UILabel *)adView.advertiserView).text = nativeAd.advertiser;
 adView.advertiserView.hidden = nativeAd.advertiser ? NO : YES;

 // In order for the SDK to process touch events properly, user interaction
 // should be disabled.
 adView.callToActionView.userInteractionEnabled = NO;

 return adView;
}
@end

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for native ads:

  • Android: https://developers.google.com/admob/android/test-ads#sample_ad_units
  • iOS: https://developers.google.com/admob/ios/test-ads#demo_ad_units

It's been specially configured to return test ads for every request, and you're free to use it in your own apps while coding, testing, and debugging. Just make sure you replace it with your own ad unit ID before publishing your app.

Instantiate a Native Ad

A NativeAd requires an adUnitId, a factoryId, an AdRequest, and a NativeAdListener. An example is shown below as well as more information on each parameter following.

final NativeAd myNative = NativeAd(
  adUnitId: '<test id or account id>',
  factoryId: 'adFactoryExample',
  request: AdRequest(),
  listener: NativeAdListener(),
);

Factory Id

The factoryId will need to match the one used to add the factory to GoogleMobileAdsPlugin on Android and/or the FLTGoogleMobileAdsPlugin on iOS. The same factoryId can be used by both platforms or each can have their own.

Native Ad Events

Through the use of NativeAdListener, you can listen for lifecycle events, such as when an ad is closed or the user leaves the app. This example implements each method and logs a message to the console:

final NativeAdListener listener = NativeAdListener(
 // Called when an ad is successfully received.
 onAdLoaded: (Ad ad) => print('Ad loaded.'),
 // Called when an ad request failed.
 onAdFailedToLoad: (Ad ad, LoadAdError error) {
   // Dispose the ad here to free resources.
   ad.dispose();
   print('Ad failed to load: $error');
 },
 // Called when an ad opens an overlay that covers the screen.
 onAdOpened: (Ad ad) => print('Ad opened.'),
 // Called when an ad removes an overlay that covers the screen.
 onAdClosed: (Ad ad) => print('Ad closed.'),
 // Called when an impression occurs on the ad.
 onAdImpression: (Ad ad) => print('Ad impression.'),
 // Called when a click is recorded for a NativeAd.
 onNativeAdClicked: (NativeAd ad) => print('Ad clicked.'),
);

NativeAdOptions

NativeAds have an optional argument, nativeAdOptions, which can be used to set specific options on the native ad.

shouldReturnUrlsForImageAssets

If set to `true`, the SDK will not load image asset content and native ad image URLs can be used to fetch content. Defaults to false.

shouldRequestMultipleImages

Some image assets will contain a series of images rather than just one. By setting this value to true, your app indicates that it's prepared to display all the images for any assets that have more than one. By setting it to false (the default) your app instructs the SDK to provide just the first image for any assets that contain a series.

If no NativeadOptions are passed in when initializing a NativeAd, the default value for each property will be used.

 

adChoicesPlacement

The [AdChoices overlay](https://developers.google.com/admob/android/native/advanced#adchoices_overlay) is set to the top right corner by default. Apps can change which corner this overlay is rendered in by setting this property to one of the following:

  • AdChoicesPlacement.topRightCorner
  • AdChoicesPlacement.topLeftCorner
  • AdChoicesPlacement.bottomRightCorner
  • AdChoicesPlacement.bottomLeftCorner

 

videoOptions

Can be used to set video options for video assets returned as part of a native ad.

mediaAspectRatio

This sets the aspect ratio for image or video to be returned for the native ad. Setting NativeMediaAspectRatio to one of the following constants will cause only ads with media of the specified aspect ratio to be returned:

  • MediaAspectRatio.landscape
  • MediaAspectRatio.portrait
  • MediaAspectRatio.square
  • MediaAspectRatio.any

If not set, ads with any aspect ratio will be returned.

 

Load Native Ad

After a NativeAd is instantiated, load() must be called before it can be shown on the screen.

myNative.load();

Display a Native Ad

To display a NativeAd as a widget, you must instantiate an AdWidget with a supported ad after calling load(). You can create the widget before calling load(), but load() must be called before adding it to the widget tree.

final AdWidget adWidget = AdWidget(ad: myBanner);

AdWidget inherits from Flutter's Widget class and can be used as any other widget. On iOS, make sure you place the widget in a widget with a specified width and height. Otherwise, your Ad may not be displayed.

final Container adContainer = Container(
  alignment: Alignment.center,
  child: adWidget,
  width: 500,
  height: 500,
);

Once an Ad has called load(), it must call dispose() when access to it is no longer needed. The best practice for when to call dispose() is either after the AdWidget is removed from the widget tree or in the AdListener.onAdFailedToLoad callback.

That's it! Your app is now ready to display native ads.

Next steps

Rewarded Ads

Rewarded ads are ads that users have the option of interacting with in exchange for in-app rewards. This guide shows you how to integrate rewarded ads from AdMob into a Flutter app.

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for rewarded:

  • Android: https://developers.google.com/admob/android/test-ads#sample_ad_units
  • iOS: https://developers.google.com/admob/ios/test-ads#demo_ad_units

It's been specially configured to return test ads for every request, and you're free to use it in your own apps while coding, testing, and debugging. Just make sure you replace it with your own ad unit ID before publishing your app.

Load a Rewarded Ad

Loading a RewardedAd requires an adUnitId, an AdRequest, and a RewardedAdLoadCallback. An example is shown below as well as more information on each parameter following.

RewardedAd.load(
  adUnitId: '<test id or account id>',
  request: AdRequest(),
  rewardedAdLoadCallback: RewardedAdLoadCallback(
    onAdLoaded: (RewardedAd ad) {
      print('$ad loaded.');
      // Keep a reference to the ad so you can show it later.
      this._rewardedAd = ad;
    },
    onAdFailedToLoad: (LoadAdError error) {
      print('RewardedAd failed to load: $error');
    },
);

Rewarded Ad Events

Through the use of FullScreenContentCallback, you can listen for lifecycle events, such as when the ad is shown or dismissed. Set RewardedAd.fullScreenContentCallback before showing the ad to receive notifications for these events. This example implements each method and logs a message to the console:

rewardedAd.fullScreenContentCallback = FullScreenContentCallback(
  onAdShowedFullScreenContent: (RewardedAd ad) =>
     print('$ad onAdShowedFullScreenContent.'),
  onAdDismissedFullScreenContent: (RewardedAd ad) {
    print('$ad onAdDismissedFullScreenContent.');
    ad.dispose();
  },
  onAdFailedToShowFullScreenContent: (RewardedAd ad, AdError error) {
    print('$ad onAdFailedToShowFullScreenContent: $error');
    ad.dispose();
  },
  onAdImpression: (RewardedAd ad) => print('$ad impression occurred.'),
);

Display a RewardedAd

A RewardedAd is displayed as an Overlay is displayed on top of all app content and is statically placed. Which means it can not be displayed this way can't be added to the Flutter widget tree. You can choose when to show the ad by calling show(). RewardedAd.show() takes an OnUserEarnedRewardCallback, which is invoked when the user earns a reward. Be sure to implement this and reward the user for watching an ad.

myRewarded.show(onUserEarnedReward: (RewardedAd ad, RewardItem rewardItem) {
  // Reward the user for watching an ad.
});

Once show() is called, an Ad displayed this way can't be removed programmatically and require user input. An RewardedAd can only be shown once. Subsequent calls to show will trigger onAdFailedToShowFullScreenContent.

Once an ad has called load(), it must call dispose() when access to it is no longer needed. The best practice for when to call dispose() is in the FullScreenContentCallback.onAdDismissedFullScreenContent and FullScreenContentCallback.onAdFailedToShowFullScreenContent callbacks.

That's it! Your app is now ready to display rewarded ads.

Creating and Loading an Ad with Ad Manager

This section shows how to create and load ads with Google Ad Manager.

Select an Ad Format

  • Banner
    • Rectangular ads that appear at the top or bottom of the device screen. Banner ads stay on screen while users are interacting with the app, and can refresh automatically after a certain period of time. If you're new to mobile advertising, they're a great place to start.
  • Interstitial
    • Full-screen ads that cover the interface of an app until closed by the user. They're best used at natural pauses in the flow of an app's execution, such as between levels of a game or just after a task is completed.
  • Native Ads
    • Customizable ads that match the look and feel of your app. You decide how and where they're placed, so the layout is more consistent with your app's design.
  • Rewarded
    • Ads that reward users for watching short videos and interacting with playable ads and surveys. Good for monetizing free-to-play users.

AdManagerAdRequest

For Ad Manager you will be using AdManagerAdRequest instead of AdRequest. AdManagerAdRequest is similar to AdRequest but has two additional properties: customTargeting and customTargetingLists, which are used to support custom targeting.

final AdManagerAdRequest request = AdManagerAdRequest(
  keywords: <String>['flutterio', 'beautiful apps'],
  contentUrl: 'https://flutter.dev',
  customTargeting: <String, String>{'some': 'targeting'},
  customTargetingLists: <String, List<String>>{'favoriteColors': <String>['red', 'yellow']},
);

Ad Manager Banner Ads

Banner ads occupy a spot within an app's layout, either at the top or bottom of the device screen. They stay on screen while users are interacting with the app, and can refresh automatically after a certain period of time.

This guide shows you how to integrate banner ads from Ad Manager into a Flutter app. In addition to code snippets and instructions, it also includes information about sizing banners properly and links to additional resources.

See also the codelab for inline ads in Flutter for a detailed guide on setting up banner ads.

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for banners:

  • Android: https://developers.google.com/ad-manager/mobile-ads-sdk/android/test-ads#sample_ad_units
  • iOS: https://developers.google.com/ad-manager/mobile-ads-sdk/ios/test-ads#demo_ad_units

It's been specially configured to return test ads for every request, and you're free to use it in your own apps while coding, testing, and debugging. Just make sure you replace it with your own ad unit ID before publishing your app.

Instantiate a Banner Ad

A AdManagerBannerAd requires an adUnitId, an AdSize, an AdRequest, and an AdListener. An example is shown below as well as more information on each parameter following.

final AdManagerBannerAd myBanner = AdManagerBannerAd(
  adUnitId: '<ad unit id>',
  size: AdSize.banner,
  request: AdManagerAdRequest(),
  listener: AdManagerBannerAdListener(),
);

Banner Sizes

The table below lists the standard banner sizes.

Size in dp (WxH)DescriptionAdSize Constant
320x50Standard Bannerbanner
320x100Large BannerlargeBanner
320x250Medium RectanglemediumRectangle
468x60Full-Size BannerfullBanner
728x90Leaderboardleaderboard
Screen width x 32|50|90Smart BannerUse getSmartBanner(Orientation)

To define a custom banner size, set your desired AdSize, as shown here:

final AdSize adSize = AdSize(300, 50);

Banner Ad Events

Through the use of AdManagerBannerAdListener, you can listen for lifecycle events, such as when an ad is closed. This example implements each method and logs a message to the console:

final AdManagerBannerAdListener listener = AdManagerBannerAdListener(
 // Called when an ad is successfully received.
 onAdLoaded: (Ad ad) => print('Ad loaded.'),
 // Called when an ad request failed.
 onAdFailedToLoad: (Ad ad, LoadAdError error) {
   // Dispose the ad here to free resources.
   ad.dispose();
   print('Ad failed to load: $error');
 },
 // Called when an ad opens an overlay that covers the screen.
 onAdOpened: (Ad ad) => print('Ad opened.'),
 // Called when an ad removes an overlay that covers the screen.
 onAdClosed: (Ad ad) => print('Ad closed.'),
 // Called when an impression occurs on the ad.
 onAdImpression: (Ad ad) => print('Ad impression.'),
);

Load Banner Ad

After a AdManagerBannerAd is instantiated, load() must be called before it can be shown on the screen.

myBanner.load();

Display a Banner Ad

To display a AdManagerBannerAd as a widget, you must instantiate an AdWidget with a supported ad after calling load(). You can create the widget before calling load(), but load() must be called before adding it to the widget tree.

final AdWidget adWidget = AdWidget(ad: myBanner);

AdWidget inherits from Flutter's Widget class and can be used as any other widget. On iOS, make sure you place the widget in a widget with a specified width and height. Otherwise, your Ad may not be displayed. A AdManagerBannerAd can be placed in a container with a size that matches the ad:

final Container adContainer = Container(
  alignment: Alignment.center,
  child: adWidget,
  width: myBanner.size.width.toDouble(),
  height: myBanner.size.height.toDouble(),
);

Once an Ad has called load(), it must call dispose() when access to it is no longer needed. The best practice for when to call dispose() is either after the AdWidget is removed from the widget tree or in the AdManagerBannerAdListener.onAdFailedToLoad callback.

That's it! Your app is now ready to display banner ads.

Ad Manager Interstitial Ad

Interstitial ads are full-screen ads that cover the interface of their host app. They're typically displayed at natural transition points in the flow of an app, such as between activities or during the pause between levels in a game. When an app shows an interstitial ad, the user has the choice to either tap on the ad and continue to its destination or close it and return to the app.

This guide explains how to integrate interstitial ads into a Flutter app.

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for interstitials:

  • Android: https://developers.google.com/ad-manager/mobile-ads-sdk/android/test-ads#sample_ad_units
  • iOS: https://developers.google.com/ad-manager/mobile-ads-sdk/ios/test-ads#demo_ad_units

It's been specially configured to return test ads for every request, and you're free to use it in your own apps while coding, testing, and debugging. Just make sure you replace it with your own ad unit ID before publishing your app.

Load an Interstitial Ad

Loading an AdManagerInterstitialAd requires an adUnitId, an AdRequest, and an AdManagerInterstitialAdLoadCallback. An example is shown below as well as more information on each parameter following.

AdManagerInterstitialAd.load(
  adUnitId: '<ad unit id>',
  request: AdRequest(),
  adLoadCallback: AdManagerInterstitialAdLoadCallback(
    onAdLoaded: (AdManagerInterstitialAd ad) {
      // Keep a reference to the ad so you can show it later.
      this._interstitialAd = ad;
    },
    onAdFailedToLoad: (LoadAdError error) {
      print('InterstitialAd failed to load: $error');
    },
  ));

Interstitial Ad Events

Through the use of FullScreenContentCallback, you can listen for lifecycle events, such as when the ad is shown or dismissed. Set AdManagerInterstitialAd.fullScreenContentCallback before showing the ad to receive notifications for these events. This example implements each method and logs a message to the console:

interstitialAd.fullScreenContentCallback = FullScreenContentCallback(
  onAdShowedFullScreenContent: (InterstitialAd ad) =>
     print('$ad onAdShowedFullScreenContent.'),
  onAdDismissedFullScreenContent: (InterstitialAd ad) {
    print('$ad onAdDismissedFullScreenContent.');
    ad.dispose();
  },
  onAdFailedToShowFullScreenContent: (InterstitialAd ad, AdError error) {
    print('$ad onAdFailedToShowFullScreenContent: $error');
    ad.dispose();
  },
  onAdImpression: (InterstitialAd ad) => print('$ad impression occurred.'),
);

Display an Interstitial Ad

A AdManagerInterstitialAd is displayed as an Overlay on top of all app content and is statically placed. Which means it can not be added to the Flutter widget tree. You can choose when to show the ad by calling show().

myInterstitial.show();

Once show() is called, an Ad displayed this way can't be removed programmatically and requires user input. An InterstitialAd can only be shown once. Subsequent calls to show will trigger onAdFailedToShowFullScreenContent.

Once an ad has called load(), it must call dispose() when access to it is no longer needed. The best practice for when to call dispose() is in the FullScreenContentCallback.onAdDismissedFullScreenContent and FullScreenContentCallback.onAdFailedToShowFullScreenContent callbacks.

That's it! Your app is now ready to display interstitial ads.

Next steps

Ad Manager Native Ads

Native ads are ad assets that are presented to users via UI components that are native to the platform. They're shown using the same types of views with which you're already building your layouts, and can be formatted to match the visual design of the user experience in which they live. In coding terms, this means that when a native ad loads, your app receives a NativeAd object that contains its assets, and the app (rather than the Google Mobile Ads SDK) is then responsible for displaying them.

Broadly speaking, there are two parts to successfully implementing Native Ads: loading an ad via the SDK and displaying the ad content in your app. This guide is concerned with using the SDK to load native ads.

See also the codelab for inline ads in Flutter for a detailed guide on setting up native ads.

Platform Setup

Native Ads are presented to users via UI components that are native to the platform. (e.g. A View on Android or a UIView on iOS).

Since Native Ads require UI components native to a platform, this feature requires additional setup for Android and iOS:

Android

The Android implementation of the Google Mobile Ads plugin requires a class that implements a NativeAdFactory. A NativeAdFactory contains a method that takes a NativeAd and custom options and returns a NativeAdView. The NativeAdView is what will be displayed in your app.

You can implement this in your MainActivity.java or create a separate class in the same directory as MainActivity.java as seen below:

package my.app.path;

import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory;
import java.util.Map;

class NativeAdFactoryExample implements NativeAdFactory {
  @Override
  public NativeAdView createNativeAd(
      NativeAd nativeAd, Map<String, Object> customOptions) {
    // Create NativeAdView
  }
}

Each NativeAdFactory needs to be registered with a factoryId, a unique String identifier, in MainActivity.configureFlutterEngine(FlutterEngine). A NativeAdFactory can be implemented and registered for each unique Native ad layout used by your app or a single one can handle all layouts. The NativeAdFactory should also be unregistered in cleanUpFlutterEngine(engine) when building with add-to-app.

MainActivity.java should look similar to:

package my.app.path;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;

public class MainActivity extends FlutterActivity {
  @Override
  public void configureFlutterEngine(FlutterEngine flutterEngine) {
    flutterEngine.getPlugins().add(new GoogleMobileAdsPlugin());
   super.configureFlutterEngine(flutterEngine);

    GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "adFactoryExample", NativeAdFactoryExample());
  }

  @Override
  public void cleanUpFlutterEngine(FlutterEngine flutterEngine) {
    GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "adFactoryExample");
  }
}

When creating the NativeAd in Dart, the factoryId will need to match the one used to add the factory to GoogleMobileAdsPlugin. In the above code snippet, adFactoryExample is the name of the factoryId. An example NativeAdFactory follows:

package io.flutter.plugins.googlemobileadsexample;

import android.graphics.Color;
import android.view.LayoutInflater;
import android.widget.TextView;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory;
import java.util.Map;

// my_native_ad.xml can be found at
/* https://github.com/googleads/googleads-mobile-flutter/tree/master/packages/google_mobile_ads/example/android/app/src/main/res/layout
*/
class NativeAdFactoryExample implements NativeAdFactory {
 private final LayoutInflater layoutInflater;

 NativeAdFactoryExample(LayoutInflater layoutInflater) {
   this.layoutInflater = layoutInflater;
 }

 @Override
 public NativeAdView createNativeAd(
     NativeAd nativeAd, Map<String, Object> customOptions) {
   final NativeAdView adView =
       (NativeAdView) layoutInflater.inflate(R.layout.my_native_ad, null);
   final TextView headlineView = adView.findViewById(R.id.ad_headline);
   final TextView bodyView = adView.findViewById(R.id.ad_body);

   headlineView.setText(nativeAd.getHeadline());
   bodyView.setText(nativeAd.getBody());

   adView.setBackgroundColor(Color.YELLOW);

   adView.setNativeAd(nativeAd);
   adView.setBodyView(bodyView);
   adView.setHeadlineView(headlineView);
   return adView;
 }
}

iOS

The iOS implementation of the Google Mobile Ads plugin requires a class that implements a FLTNativeAdFactory. A FLTNativeAdFactory contains a method that takes a GADNativeAd and custom options and returns a GADNativeAdView. The GADNativeAdView is what will be displayed in your app.

The FLTNativeAdFactory protocol can be implemented by AppDelegate or a separate class could be created as seen below:

/* AppDelegate.m */
#import "FLTGoogleMobileAdsPlugin.h"
@interface NativeAdFactoryExample : NSObject<FLTNativeAdFactory>
@end

@implementation NativeAdFactoryExample
- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
                             customOptions:(NSDictionary *)customOptions {
  // Create GADNativeAdView
}
@end

Each FLTNativeAdFactory needs to be registered with a factoryId, a unique String identifier, in registerNativeAdFactory:factoryId:nativeAdFactory:. A FLTNativeAdFactory can be implemented and registered for each unique Native ad layout used by your app or a single one can handle all layouts. This is done by importing FLTGoogleMobileAdsPlugin.h and calling registerNativeAdFactory:factoryId:nativeAdFactory: with a FlutterPluginRegistry, a unique identifier for the factory, and the factory itself. The factory also MUST be added after [GeneratedPluginRegistrant registerWithRegistry:self]; has been called.

If this is done in AppDelegate.m, it should look similar to:

#import "FLTGoogleMobileAdsPlugin.h"

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];

  NativeAdFactoryExample *nativeAdFactory = [[NativeAdFactoryExample alloc] init];
  [FLTGoogleMobileAdsPlugin registerNativeAdFactory:self
                                        factoryId:@"adFactoryExample"
                                  nativeAdFactory:nativeAdFactory];

  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end

When creating the NativeAd in Dart, the factoryID will need to match the one used to add the factory to FLTGoogleMobileAdsPlugin. In the above code snippet, adFactoryExample is the name of the factoryID.An exampleFLTNativeAdFactory` follows:

// The example NativeAdView.xib can be found at
/* https://github.com/googleads/googleads-mobile-flutter/blob/master/packages/google_mobile_ads/example/ios/Runner/NativeAdView.xib
*/
@interface NativeAdFactoryExample : NSObject <FLTNativeAdFactory>
@end

@implementation NativeAdFactoryExample
- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
                            customOptions:(NSDictionary *)customOptions {
 // Create and place ad in view hierarchy.
 GADNativeAdView *adView =
     [[NSBundle mainBundle] loadNibNamed:@"NativeAdView" owner:nil options:nil].firstObject;

 // Associate the native ad view with the native ad object. This is
 // required to make the ad clickable.
 adView.nativeAd = nativeAd;

 // Populate the native ad view with the native ad assets.
 // The headline is guaranteed to be present in every native ad.
 ((UILabel *)adView.headlineView).text = nativeAd.headline;

 // These assets are not guaranteed to be present. Check that they are before
 // showing or hiding them.
 ((UILabel *)adView.bodyView).text = nativeAd.body;
 adView.bodyView.hidden = nativeAd.body ? NO : YES;

 [((UIButton *)adView.callToActionView) setTitle:nativeAd.callToAction
                                        forState:UIControlStateNormal];
 adView.callToActionView.hidden = nativeAd.callToAction ? NO : YES;

 ((UIImageView *)adView.iconView).image = nativeAd.icon.image;
 adView.iconView.hidden = nativeAd.icon ? NO : YES;

 ((UILabel *)adView.storeView).text = nativeAd.store;
 adView.storeView.hidden = nativeAd.store ? NO : YES;

 ((UILabel *)adView.priceView).text = nativeAd.price;
 adView.priceView.hidden = nativeAd.price ? NO : YES;

 ((UILabel *)adView.advertiserView).text = nativeAd.advertiser;
 adView.advertiserView.hidden = nativeAd.advertiser ? NO : YES;

 // In order for the SDK to process touch events properly, user interaction
 // should be disabled.
 adView.callToActionView.userInteractionEnabled = NO;

 return adView;
}
@end

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for native ads:

  • Android: https://developers.google.com/ad-manager/mobile-ads-sdk/android/test-ads#sample_ad_units
  • iOS: https://developers.google.com/ad-manager/mobile-ads-sdk/ios/test-ads#demo_ad_units

It's been specially configured to return test ads for every request, and you're free to use it in your own apps while coding, testing, and debugging. Just make sure you replace it with your own ad unit ID before publishing your app.

Instantiate a Native Ad

A NativeAd requires an adUnitId, a factoryId, an AdRequest, and an AdListener. An example is shown below as well as more information on each parameter following.

final NativeAd myNative = NativeAd.fromAdManagerRequest(
  adUnitId: '<test id or account id>',
  factoryId: 'adFactoryExample',
  adManagerRequest: AdManagerAdRequest(),
  listener: NativeAdListener(),
);

Factory Id

The factoryId will need to match the one used to add the factory to GoogleMobileAdsPlugin on Android and/or the FLTGoogleMobileAdsPlugin on iOS. The same factoryId can be used by both platforms or each can have their own.

Native Ad Events

Through the use of NativeAdListener, you can listen for lifecycle events, such as when an ad is closed or the user leaves the app. This example implements each method and logs a message to the console:

final NativeAdListener listener = NativeAdListener(
 // Called when an ad is successfully received.
 onAdLoaded: (Ad ad) => print('Ad loaded.'),
 // Called when an ad request failed.
 onAdFailedToLoad: (Ad ad, LoadAdError error) {
   // Dispose the ad here to free resources.
   ad.dispose();
   print('Ad failed to load: $error');
 },
 // Called when an ad opens an overlay that covers the screen.
 onAdOpened: (Ad ad) => print('Ad opened.'),
 // Called when an ad removes an overlay that covers the screen.
 onAdClosed: (Ad ad) => print('Ad closed.'),
 // Called when an impression occurs on the ad.
 onAdImpression: (Ad ad) => print('Ad impression.'),
 // Called when a click is recorded for a NativeAd.
 onNativeAdClicked: (NativeAd ad) => print('Ad clicked.'),
);

NativeAdOptions

NativeAds have an optional argument, nativeAdOptions, which can be used to set specific options on the native ad.

shouldReturnUrlsForImageAssets

If set to `true`, the SDK will not load image asset content and native ad image URLs can be used to fetch content. Defaults to false.

shouldRequestMultipleImages

Some image assets will contain a series of images rather than just one. By setting this value to true, your app indicates that it's prepared to display all the images for any assets that have more than one. By setting it to false (the default) your app instructs the SDK to provide just the first image for any assets that contain a series.

If no NativeadOptions are passed in when initializing a NativeAd, the default value for each property will be used.

 

adChoicesPlacement

The [AdChoices overlay](https://developers.google.com/admob/android/native/advanced#adchoices_overlay) is set to the top right corner by default. Apps can change which corner this overlay is rendered in by setting this property to one of the following:

  • AdChoicesPlacement.topRightCorner
  • AdChoicesPlacement.topLeftCorner
  • AdChoicesPlacement.bottomRightCorner
  • AdChoicesPlacement.bottomLeftCorner

 

videoOptions

Can be used to set video options for video assets returned as part of a native ad.

mediaAspectRatio

This sets the aspect ratio for image or video to be returned for the native ad. Setting NativeMediaAspectRatio to one of the following constants will cause only ads with media of the specified aspect ratio to be returned:

  • MediaAspectRatio.landscape
  • MediaAspectRatio.portrait
  • MediaAspectRatio.square
  • MediaAspectRatio.any

If not set, ads with any aspect ratio will be returned.

 

Load Native Ad

After a NativeAd is instantiated, load() must be called before it can be shown on the screen.

myNative.load();

Display a Native Ad

To display a NativeAd as a widget, you must instantiate an AdWidget with a supported ad after calling load(). You can create the widget before calling load(), but load() must be called before adding it to the widget tree.

final AdWidget adWidget = AdWidget(ad: myBanner);

AdWidget inherits from Flutter's Widget class and can be used as any other widget. On iOS, make sure you place the widget in a widget with a specified width and height. Otherwise, your Ad may not be displayed.

final Container adContainer = Container(
  alignment: Alignment.center,
  child: adWidget,
  width: 500,
  height: 500,
);

Once an Ad has called load(), it must call dispose() when access to it is no longer needed. The best practice for when to call dispose() is either after the AdWidget is removed from the widget tree or in the AdListener.onAdFailedToLoad callback.

That's it! Your app is now ready to display native ads.

Next steps

Ad Manager Rewarded Ads

Rewarded ads are ads that users have the option of interacting with in exchange for in-app rewards. This guide shows you how to integrate rewarded ads from Ad Manager into a Flutter app.

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for rewarded:

  • Android: https://developers.google.com/ad-manager/mobile-ads-sdk/android/test-ads#sample_ad_units
  • iOS: https://developers.google.com/ad-manager/mobile-ads-sdk/ios/test-ads#demo_ad_units

It's been specially configured to return test ads for every request, and you're free to use it in your own apps while coding, testing, and debugging. Just make sure you replace it with your own ad unit ID before publishing your app.

Load a Rewarded Ad

Loading a RewardedAd requires an adUnitId, an AdManagerAdRequest, and a RewardedAdLoadCallback. An example is shown below as well as more information on each parameter following.

RewardedAd.loadWithAdManagerAdRequest(
  adUnitId: '<test id or account id>',
  adManagerRequest: AdManagerAdRequest(),
  rewardedAdLoadCallback: RewardedAdLoadCallback(
    onAdLoaded: (RewardedAd ad) {
      print('$ad loaded.');
      // Keep a reference to the ad so you can show it later.
      this._rewardedAd = ad;
    },
    onAdFailedToLoad: (LoadAdError error) {
      print('RewardedAd failed to load: $error');
    },
);

Rewarded Ad Events

Through the use of FullScreenContentCallback, you can listen for lifecycle events, such as when the ad is shown or dismissed. Set RewardedAd.fullScreenContentCallback before showing the ad to receive notifications for these events. This example implements each method and logs a message to the console:

rewardedAd.fullScreenContentCallback = FullScreenContentCallback(
  onAdShowedFullScreenContent: (RewardedAd ad) =>
     print('$ad onAdShowedFullScreenContent.'),
  onAdDismissedFullScreenContent: (RewardedAd ad) {
    print('$ad onAdDismissedFullScreenContent.');
    ad.dispose();
  },
  onAdFailedToShowFullScreenContent: (RewardedAd ad, AdError error) {
    print('$ad onAdFailedToShowFullScreenContent: $error');
    ad.dispose();
  },
  onAdImpression: (RewardedAd ad) => print('$ad impression occurred.'),
);

Display a RewardedAd

A RewardedAd is displayed as an Overlay is displayed on top of all app content and is statically placed. Which means it can not be displayed this way can't be added to the Flutter widget tree. You can choose when to show the ad by calling show(). A RewardedAd can only be shown once. Subsequent calls to show will trigger onAdFailedToShowFullScreenContent. RewardedAd.show() takes an OnUserEarnedRewardCallback, which is invoked when the user earns a reward. Be sure to implement this and reward the user for watching an ad.

myRewarded.show(onUserEarnedReward: (RewardedAd ad, RewardItem rewardItem) {
  // Reward the user for watching an ad.
});

Once show() is called, an Ad displayed this way can't be removed programmatically and require user input. Do not call show() more than once for a loaded RewardedAd. Instead you should load a new ad.

Once an ad has called load(), it must call dispose() when access to it is no longer needed. The best practice for when to call dispose() is in the FullScreenContentCallback.onAdDismissedFullScreenContent and FullScreenContentCallback.onAdFailedToShowFullScreenContent callbacks.

That's it! Your app is now ready to display rewarded ads.

Next Steps

Targeting

The RequestConfiguration object collects the global configuration for every ad request and is applied byMobileAds.instance.updateRequestConfiguration().

Child-directed setting

For purposes of the Children's Online Privacy Protection Act (COPPA), there is a setting called "tag for child-directed treatment."

As an app developer, you can indicate whether you want Google to treat your content as child-directed when you make an ad request. If you indicate that you want Google to treat your content as child-directed, we take steps to disable IBA and remarketing ads on that ad request. The setting can be used with all versions of the Google Play services SDK viaRequestConfiguration.tagForChildDirectedTreatment():

  • Use the argument TagForChildDirectedTreatment.yes to indicate that you want your content treated as child-directed for the purposes of COPPA.
  • Use the argument TagForChildDirectedTreatment.no to indicate that you don't want your content treated as child-directed for the purposes of COPPA.
  • Use the argument TagForChildDirectedTreatment.unspecified or do not set this tag if you do not wish to indicate how you would like your content treated with respect to COPPA in ad requests.

The following example indicates that you want your content treated as child-directed for purposes of COPPA:

final RequestConfiguration requestConfiguration = RequestConfiguration(
  tagForChildDirectedTreatment: TagForChildDirectedTreatment.yes);
MobileAds.instance.updateRequestConfiguration(requestConfiguration);

Users under the age of consent

You can mark your ad requests to receive treatment for users in the European Economic Area (EEA) under the age of consent. This feature is designed to help facilitate compliance with the General Data Protection Regulation (GDPR). Note that you may have other legal obligations under GDPR. Please review the European Union’s guidance and consult with your own legal counsel. Please remember that Google's tools are designed to facilitate compliance and do not relieve any particular publisher of its obligations under the law. Learn more about how the GDPR affects publishers.

When using this feature, a Tag For Users under the Age of Consent in Europe (TFUA) parameter will be included in the ad request. This parameter disables personalized advertising, including remarketing, for that specific ad request. It also disables requests to third-party ad vendors, such as ad measurement pixels and third-party ad servers.

The setting can be used via RequestConfiguration.tagForUnderAgeOfConsent():

  • Use the argument TagForUnderAgeOfConsent.yes to indicate that you want the request configuration to be handled in a manner suitable for users under the age of consent.
  • Use the argument TagForUnderAgeOfConsent.no to indicates that you don't want the request configuration to be handled in a manner suitable for users under the age of consent.
  • Use the argument TagForUnderAgeOfConsent.unspecified or do not set this tag to indicate that you have not specified whether the ad request should receive treatment for users in the European Economic Area (EEA) under the age of consent. The following example indicates that you want TFUA included in your ad request:
final RequestConfiguration requestConfiguration = RequestConfiguration(
  tagForUnderAgeOfConsent: TagForUnderAgeOfConsent.yes);
MobileAds.instance.updateRequestConfiguration(requestConfiguration);

The tags to enable the Child-directed setting and setTagForUnderAgeOfConsent should not both simultaneously be set to true. If they are, the child-directed setting takes precedence.

Ad Content Filtering

The setting can be set viaRequestConfiguration.maxAdContentRating():

AdMob ads returned for these requests have a content rating at or below that level. The possible values for this network extra are based on digital content label classifications, and should be one of the followingMaxAdContentRating objects:

  • MaxAdContentRating.g
  • MaxAdContentRating.pg
  • MaxAdContentRating.t
  • MaxAdContentRating.ma

The following code configures aRequestConfiguration object to specify that ad content returned should correspond to a digital content label designation no higher than G:

final RequestConfiguration requestConfiguration = RequestConfiguration(
  maxAdContentRating: MaxAdContentRating.g);
MobileAds.instance.updateRequestConfiguration(requestConfiguration);

Response Info

For debugging and logging purposes, LoadAdErrors and successfully loaded ads provide a ResponseInfo object. This object contains information about the ad it loaded. Each ad format class has a property Ad.responseInfo which is populated after it loads.

Properties on the ResponseInfo object include:

mediationAdapterClassName : The class name of the ad network that fetched the current ad.

responseId : The response identifier is a unique identifier for the ad response. This identifier can be used to identify and block the ad in the Ads Review Center (ARC).

adapterResponses : The list of AdapterResponseInfo containing metadata for each adapter included in the ad response. Can be used to debug the mediation waterfall execution.

For each ad network in the waterfall, AdapterResponseInfo provides the following properties:

PropertyDescription
adapterClassNameA class name that identifies the ad network.
credentialsA string description of adapter credentials specified in the AdMob or Ad Manager UI.
adErrorError associated with the request to the network. Null if the network successfully loaded an ad or if the network was not attempted.
latencyMillisAmount of time the ad network spent loading an ad. 0 if the network was not attempted.
descriptionA log friendly string version of the AdapterResponseInfo.

Ad Load Errors

When an ad fails to load, a failure callback is called which provides a LoadAdError object.

The following code snippet retrieves error information when a rewarded ad fails to load:

onAdFailedToLoad: (ad, loadAdError) {
  // Gets the domain from which the error came.
  String domain = loadAdError.domain;

  // Gets the error code. See
  // https://developers.google.com/android/reference/com/google/android/gms/ads/AdRequest
  // and https://developers.google.com/admob/ios/api/reference/Enums/GADErrorCode
  // for a list of possible codes.
  int code = loadAdError.code;
  
  // A log friendly string summarizing the error.
  String message = loadAdError.message;
  
  // Get response information, which may include results of mediation requests.
  ResponseInfo? responseInfo = loadAdError.responseInfo;
}

This information can be used to more accurately determine what caused the ad load to fail. In particular, for errors under the domain com.google.admob on iOS and com.google.android.gms.ads on Android, the GetMessage() can be looked up in this help center article for a more detailed explanation and possible actions that can be taken to resolve the issue.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add google_mobile_ads

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):


dependencies:
  google_mobile_ads: ^0.13.4

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:google_mobile_ads/google_mobile_ads.dart';

example/lib/main.dart

// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ignore_for_file: public_member_api_docs

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'reusable_inline_example.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();
  runApp(MyApp());
}

// You can also test with your own ad unit IDs by registering your device as a
// test device. Check the logs for your device's ID value.
const String testDevice = 'YOUR_DEVICE_ID';
const int maxFailedLoadAttempts = 3;

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  static final AdRequest request = AdRequest(
    keywords: <String>['foo', 'bar'],
    contentUrl: 'http://foo.com/bar.html',
    nonPersonalizedAds: true,
  );

  InterstitialAd? _interstitialAd;
  int _numInterstitialLoadAttempts = 0;

  RewardedAd? _rewardedAd;
  int _numRewardedLoadAttempts = 0;

  BannerAd? _anchoredBanner;
  bool _loadingAnchoredBanner = false;

  @override
  void initState() {
    super.initState();
    _createInterstitialAd();
    _createRewardedAd();
  }

  void _createInterstitialAd() {
    InterstitialAd.load(
        adUnitId: InterstitialAd.testAdUnitId,
        request: request,
        adLoadCallback: InterstitialAdLoadCallback(
          onAdLoaded: (InterstitialAd ad) {
            print('$ad loaded');
            _interstitialAd = ad;
            _numInterstitialLoadAttempts = 0;
            _interstitialAd!.setImmersiveMode(true);
          },
          onAdFailedToLoad: (LoadAdError error) {
            print('InterstitialAd failed to load: $error.');
            _numInterstitialLoadAttempts += 1;
            _interstitialAd = null;
            if (_numInterstitialLoadAttempts <= maxFailedLoadAttempts) {
              _createInterstitialAd();
            }
          },
        ));
  }

  void _showInterstitialAd() {
    if (_interstitialAd == null) {
      print('Warning: attempt to show interstitial before loaded.');
      return;
    }
    _interstitialAd!.fullScreenContentCallback = FullScreenContentCallback(
      onAdShowedFullScreenContent: (InterstitialAd ad) =>
          print('ad onAdShowedFullScreenContent.'),
      onAdDismissedFullScreenContent: (InterstitialAd ad) {
        print('$ad onAdDismissedFullScreenContent.');
        ad.dispose();
        _createInterstitialAd();
      },
      onAdFailedToShowFullScreenContent: (InterstitialAd ad, AdError error) {
        print('$ad onAdFailedToShowFullScreenContent: $error');
        ad.dispose();
        _createInterstitialAd();
      },
    );
    _interstitialAd!.show();
    _interstitialAd = null;
  }

  void _createRewardedAd() {
    RewardedAd.load(
        adUnitId: RewardedAd.testAdUnitId,
        request: request,
        rewardedAdLoadCallback: RewardedAdLoadCallback(
          onAdLoaded: (RewardedAd ad) {
            print('$ad loaded.');
            _rewardedAd = ad;
            _numRewardedLoadAttempts = 0;
          },
          onAdFailedToLoad: (LoadAdError error) {
            print('RewardedAd failed to load: $error');
            _rewardedAd = null;
            _numRewardedLoadAttempts += 1;
            if (_numRewardedLoadAttempts <= maxFailedLoadAttempts) {
              _createRewardedAd();
            }
          },
        ));
  }

  void _showRewardedAd() {
    if (_rewardedAd == null) {
      print('Warning: attempt to show rewarded before loaded.');
      return;
    }
    _rewardedAd!.fullScreenContentCallback = FullScreenContentCallback(
      onAdShowedFullScreenContent: (RewardedAd ad) =>
          print('ad onAdShowedFullScreenContent.'),
      onAdDismissedFullScreenContent: (RewardedAd ad) {
        print('$ad onAdDismissedFullScreenContent.');
        ad.dispose();
        _createRewardedAd();
      },
      onAdFailedToShowFullScreenContent: (RewardedAd ad, AdError error) {
        print('$ad onAdFailedToShowFullScreenContent: $error');
        ad.dispose();
        _createRewardedAd();
      },
    );

    _rewardedAd!.setImmersiveMode(true);
    _rewardedAd!.show(onUserEarnedReward: (RewardedAd ad, RewardItem reward) {
      print('$ad with reward $RewardItem(${reward.amount}, ${reward.type}');
    });
    _rewardedAd = null;
  }

  Future<void> _createAnchoredBanner(BuildContext context) async {
    final AnchoredAdaptiveBannerAdSize? size =
        await AdSize.getAnchoredAdaptiveBannerAdSize(
      Orientation.portrait,
      MediaQuery.of(context).size.width.truncate(),
    );

    if (size == null) {
      print('Unable to get height of anchored banner.');
      return;
    }

    final BannerAd banner = BannerAd(
      size: size,
      request: request,
      adUnitId: Platform.isAndroid
          ? 'ca-app-pub-3940256099942544/6300978111'
          : 'ca-app-pub-3940256099942544/2934735716',
      listener: BannerAdListener(
        onAdLoaded: (Ad ad) {
          print('$BannerAd loaded.');
          setState(() {
            _anchoredBanner = ad as BannerAd?;
          });
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          print('$BannerAd failedToLoad: $error');
          ad.dispose();
        },
        onAdOpened: (Ad ad) => print('$BannerAd onAdOpened.'),
        onAdClosed: (Ad ad) => print('$BannerAd onAdClosed.'),
      ),
    );
    return banner.load();
  }

  @override
  void dispose() {
    super.dispose();
    _interstitialAd?.dispose();
    _rewardedAd?.dispose();
    _anchoredBanner?.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Builder(builder: (BuildContext context) {
        if (!_loadingAnchoredBanner) {
          _loadingAnchoredBanner = true;
          _createAnchoredBanner(context);
        }
        return Scaffold(
          appBar: AppBar(
            title: const Text('AdMob Plugin example app'),
            actions: <Widget>[
              PopupMenuButton<String>(
                onSelected: (String result) {
                  switch (result) {
                    case 'InterstitialAd':
                      _showInterstitialAd();
                      break;
                    case 'RewardedAd':
                      _showRewardedAd();
                      break;
                    default:
                      throw AssertionError('unexpected button: $result');
                  }
                },
                itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
                  PopupMenuItem<String>(
                    value: '$InterstitialAd',
                    child: Text('$InterstitialAd'),
                  ),
                  PopupMenuItem<String>(
                    value: '$RewardedAd',
                    child: Text('$RewardedAd'),
                  ),
                ],
              ),
            ],
          ),
          body: SafeArea(
            child: Stack(
              alignment: AlignmentDirectional.bottomCenter,
              children: <Widget>[
                ReusableInlineExample(),
                if (_anchoredBanner != null)
                  Container(
                    color: Colors.green,
                    width: _anchoredBanner!.size.width.toDouble(),
                    height: _anchoredBanner!.size.height.toDouble(),
                    child: AdWidget(ad: _anchoredBanner!),
                  ),
              ],
            ),
          ),
        );
      }),
    );
  }
}

Download Details:
 

Author: googleads

Download The Source Code : https://github.com/googleads/googleads-mobile-flutter/archive/refs/heads/master.zip 

GITHUB: https://github.com/googleads/googleads-mobile-flutter