Prerequisites

  • Flutter 2 or later.
  • Xcode 12.5 or later.
  • iOS 9 or later.
  • Android 4.0 (Ice Cream Sandwich - API Version 14) or later.
  • Enable AndroidX in your project. For more information.
  • Application Id provided in Admost Mediation Dashboard.
  • Zone Id(s) provided in Admost Mediation Dashboard.

For testing you can use following Ids;

IOS Test Ids

Application Id: "15066ddc-9c18-492c-8185-bea7e4c7f88c"
Banner Zone Id: "b4009772-de04-42c4-bbaa-c18da9e4a1ab"
Interstitial Zone Id: "39f74377-5682-436a-9338-9d1c4df410bd"
RewardedVideo Zone Id: "2bdefd44-5269-4cbc-b93a-373b74a2f067"
                
Android Test Ids

Application Id: "6cc8e89a-b52a-4e9a-bb8c-579f7ec538fe"
Banner Zone Id: "9fb970db-7d96-4ef2-ac8c-d88ec22270ff"
Interstitial Zone Id: "f99e409b-f9ab-4a2e-aa9a-4d143e6809ae"
RewardedVideo Zone Id: "88cfcfd0-2f8c-4aba-9f36-cc0ac99ab140"
                

Setup

You can install the AMR SDK in your Flutter app by adding the following under dependencies: in your pubspec.yaml file:

 
                admost_flutter_plugin: "^1.2.5"
                
                

Then navigate to your project's directory in terminal and run:

 
                flutter pub get
                
                
pubdev version

Please refer to following table for required and optional packages for your target.

Status Name Download Links

IOS Setup Notes


Required Files

With your selections you are going to work with following files;

  • Podfile
  • Info.plist

Flutter ~ Project view | Info.plist and Podfile location

  • android
  • ios
    • Podfile~> HERE
    • Flutter
    • Runner
      • AppDelegate.swift
      • Assets.xcassets
      • Base.lproj
      • GeneratedPluginRegistrant.h
      • GeneratedPluginRegistrant.m
      • Info.plist~> HERE
      • Runner-Bridging-Header.h
    • Runner.xcodeproj
    • Runner.xcworkspace
  • lib
  • pubspec.yaml

  • CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects which automates and simplifies the process of using 3rd-party libraries like AMR in your projects. See getting started guide for more information on installing cocoapods.


Edit Files

At least one mediation adapter is required for AMRSDK to show banners. You can add all adapters (recommended for maximized revenue) or start with a subset of adapters. Consult your AMR agent for further details.

Please select the ad networks you want to install from the list above. Podfile will be updated while you are choosing networks.

To integrate AMR SDK and mediation adapters into your Flutter project using CocoaPods, specify it in your Podfile:


                    PLEASE SELECT ONE OR MORE NETWORKS TO CREATE YOUR PODPSPEC DEPENDENCY LIST.
                

Add following lines to your plist file.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>admost.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>
<key>NSCalendarsUsageDescription</key>
<string>Some ad content may access calendar</string>

SKAdNetwork

With the iOS 14, you need to add SKAdNetwork ids to your Info.plist file to support conversion tracking.

Add following code to your Info.plist file:

PLEASE SELECT ONE OR MORE NETWORKS TO CREATE YOUR SKADNETWORK LIST.

iOS 14

Starting with iOS 14, apps will be required to ask users for permission to access IDFA. In order to ask for this permission and display the App Tracking Transparency authorization request for accessing the IDFA, you will need to add NSUserTrackingUsageDescription key to Info.plist file.


<key>NSUserTrackingUsageDescription</key>
<string>Your awesome message to encourage user to give permission to access IDFA</string>

                    

To present the authorization request, call AdmostATTrackingManager.requestTrackingAuthorization():


import 'package:admost_flutter_plugin/admost_ios_attrackingmanager.dart';

...
if (Platform.isIOS) {
    AdmostATTrackingManager.requestTrackingAuthorization().then((status) {
        // Tracking authorization completed.
    });
}
                    

User is prompted with following popup after requestTrackingAuthorization call.

att-iOS.png

Please see ATTrackingManager.AuthorizationStatus for possible return values.

Android Setup Notes

Required Files

With your selections you are going to work with following files;

  • /build.gradle
  • /app/src/build.gradle
  • gradle.properties
  • AndroidManifest.xml

If you are using proguard you have to edit /app/src/proguard-rules.pro too.

Flutter ~ Project view

  • android
    • app
      • src
        • debug
        • main
          • AndroidManifest.xml~> AndroidManifest.xml
        • profile
      • build.gradle~> /app/src/build.gradle
      • proguard-rules.pro~> /app/src/proguard-rules.pro
    • gradle
    • build.gradle~> /build.gradle
    • gradle.properties~> gradle.properties
  • ios
  • lib
  • pubspec.yaml

Edit Files

Add the following lines inside repositories{} bracelets in /build.gradle file

Add the following lines inside android{} bracelets in /app/src/build.gradlefile

 
                    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

Add the following lines inside dependencies{} bracelets in /app/src/build.gradle file

It is highly recommended to enable AndroidX in your project. Editing gradle.properties file and adding the lines below(if they are not present) is required for most ad-network sdks.


android.useAndroidX=true
android.enableJetifier=true

Starting with Android 9.0 (API level 28), cleartext support is disabled by default. For applications targetSdkVersion higher than 27 must use the following manifest config for AdMost cleartext support.


<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:networkSecurityConfig="@xml/admost_network_security_config"
        ...>
        ...
    </application>
</manifest>
				

Proguard

If you are using proguard. Copy & paste following code snippet in to your /app/src/proguard-rules.pro file


# ADMOST
-keepattributes Exceptions, InnerClasses
-dontwarn admost.sdk.**
-keep class admost.sdk.** {*;}
-dontwarn com.amr.unity.**
-keep class com.amr.unity.** {*;}
-dontwarn admost.adserver.**
-keep class com.adjust.sdk.** {*;}
-dontwarn com.adjust.sdk.**
-keep class com.appsflyer.** {*;}
-dontwarn com.appsflyer.**
-keep class admost.adserver.** { *; }
-dontwarn com.google.android.exoplayer2.**
-keep class com.google.android.exoplayer2.**{ *;}
-keep class android.support.v4.app.DialogFragment { *; }
-keep class android.support.v4.util.LruCache { *; }


# VOLLEY
-keep class com.android.volley.** { *; }
-keep interface com.android.volley.** { *; }
-keep class org.apache.commons.logging.**

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# ADCOLONY
-dontwarn com.adcolony.**
-keep class com.adcolony.** { *; }
-keepclassmembers class * { @android.webkit.JavascriptInterface <methods>; }
-keepclassmembers class com.adcolony.sdk.ADCNative** { *; }

# ADGEM
-keep class com.adgem.** { *; }
-dontwarn com.adgem.**

# ADMOB / ADX / GOOGLE
-keep class com.android.vending.billing.**
-keep public class com.google.android.gms.ads.** { public *; }
-keep public class com.google.ads.** { public *; }
-keep class com.google.android.gms.** { *; }
-dontwarn com.google.android.gms.**
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { public static final *** NULL; }
-keepnames class * implements android.os.Parcelable
-keepclassmembers class * implements android.os.Parcelable { public static final *** CREATOR; }
-keep @interface android.support.annotation.Keep
-keep @android.support.annotation.Keep class *
-keepclasseswithmembers class * { @android.support.annotation.Keep <fields>; }
-keepclasseswithmembers class * { @android.support.annotation.Keep <methods>; }
-keep @interface com.google.android.gms.common.annotation.KeepName
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * { @com.google.android.gms.common.annotation.KeepName *; }
-keep @interface com.google.android.gms.common.util.DynamiteApi
-keep public @com.google.android.gms.common.util.DynamiteApi class * { public <fields>; public <methods>; }
-keep public @com.google.android.gms.common.util.DynamiteApi class * { *; }
-keep class com.google.android.apps.common.proguard.UsedBy*
-keep @com.google.android.apps.common.proguard.UsedBy* class *
-keepclassmembers class * { @com.google.android.apps.common.proguard.UsedBy* *; }
-dontwarn android.security.NetworkSecurityPolicy
-dontwarn android.app.Notification

#ADTIMING
-dontwarn com.aiming.mdt.**.*
-dontoptimize
-dontskipnonpubliclibraryclasses
-keepattributes *Annotation*
#adt
-keep class com.aiming.mdt.**{ *; }
-keepattributes *Annotation*,InnerClasses
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
#R
-keepclassmembers class **.R$* {
public static <fields>;
}

# AMAZON
-dontwarn com.amazon.**
-keep class com.amazon.** { *; }
-dontwarn org.apache.http.**
-keepattributes *Annotation*

# APPLOVIN
-dontwarn com.applovin.**
-keep class com.applovin.** { *; }

# APPNEXT
-keep class com.appnext.** { *; }
-dontwarn com.appnext.**

# APPSAMURAI
-keepclassmembers,allowobfuscation class * {
    @com.google.gson.annotations.SerializedName <fields>;
}

# AVOCARROT - GLISPA
-keep class com.avocarrot.** { *; }
-dontwarn com.avocarrot.**
-keep class com.google.android.exoplayer2.SimpleExoPlayer
-dontwarn com.google.android.exoplayer2.SimpleExoPlayer

# CHARTBOOST
-dontwarn org.apache.http.**
-dontwarn com.chartboost.sdk.impl.**
-keep class com.chartboost.sdk.** { *; }
-keepattributes *Annotation*

# CRITEO
-dontwarn com.criteo.**
-keep class com.criteo.** { *; }

# DISPLAYIO
-keep class io.display.sdk.** { *; }
-dontwarn io.display.sdk.**
-keep class com.brandio.ads.** { *;}
-dontwarn com.brandio.ads.**

# FACEBOOK
-dontwarn com.facebook.ads.**
-dontnote com.facebook.ads.**
-keep class com.facebook.** { *; }
-keepattributes Signature
-keep class com.google.android.exoplayer2.** {*;}
-dontwarn com.google.android.exoplayer2.**

# FLURRY
-keep class com.flurry.** { *; }
-dontwarn com.flurry.**
-keepattributes *Annotation*,EnclosingMethod,Signature
-keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); }
-keep class * extends java.util.ListResourceBundle { protected Object[][] getContents(); }
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { public static final *** NULL; }
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * { @com.google.android.gms.common.annotation.KeepName *; }
-keepnames class * implements android.os.Parcelable { public static final ** CREATOR; }

# FREECORP
-keep class com.fly.** { *; }
-dontwarn com.fly.**

# FYBER
-keep class com.fyber.** { *; }
-dontwarn com.fyber.**
-keep class com.fyber.mediation.MediationConfigProvider { public static *; }
-keep class com.fyber.mediation.MediationAdapterStarter { public static *; }
-keepclassmembers class com.fyber.ads.videos.mediation.** { void setValue(java.lang.String); }

# HUAWEI-ADS
-keep class com.huawei.openalliance.ad.** { *; }
-keep class com.huawei.hms.ads.** { *; }

# INMOBI
-keepattributes SourceFile,LineNumberTable
-keep class com.inmobi.** {*;}
-dontwarn com.inmobi.**
-keep public class com.google.android.gms.**
-dontwarn com.google.android.gms.**
-dontwarn com.squareup.picasso.**
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient{public *;}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info{public *;}
-keep class com.squareup.picasso.** {*;}
-dontwarn com.squareup.picasso.**
-dontwarn com.squareup.okhttp.**
-keep class com.moat.** {*;}
-dontwarn com.moat.**
-keep class com.integralads.avid.library.* {*;}


# INNERACTIVE
-dontwarn com.fyber.**
-keep class com.fyber.** {*;}
-dontwarn com.inneractive.api.ads.**
-keep class com.inneractive.api.ads.** {*;}
-keepclassmembers class com.inneractive.api.ads.** {*;}
-keepclassmembers class com.inneractive.api.ads.sdk.nativead.** {*;}
-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.google.gson.Gson { *; }
-keep class com.google.gson.GsonBuilder { *; }
-keep class com.google.gson.FieldNamingStrategy { *; }

# IRONSOURCE
-dontwarn com.ironsource.**
-keep class com.ironsource.** { *; }
-keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
-keep public class com.google.android.gms.ads.** { public *; }
-keep class com.ironsource.adapters.** { *; }
-dontwarn com.moat.**
-keep class com.moat.** { public protected private *; }

# LOOPME
-dontwarn com.loopme.**
-keep class com.loopme.** { *; }

# MEDIABRIX
-keep class com.mediabrix.** { *; }
-keep class com.moat.** { *; }
-keep class mdos.** { *; }
-dontwarn com.mediabrix.**
-dontwarn com.moat.**
-dontwarn mdos.**

# MILLENNIAL & NEXAGE
-keep class com.millennialmedia.** { *; }
-dontwarn com.millennialmedia.**

# MINTEGRAL
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.mbridge.** {*; }
-keep interface com.mbridge.** {*; }
-keep interface androidx.** { *; }
-keep class androidx.** { *; }
-keep public class * extends androidx.** { *; }
-dontwarn com.mbridge.**
-keep class **.R$* { public static final int mbridge*; }

# MOBFOX
-dontwarn com.mobfox.**
-keep class com.mobfox.** { *; }
-keep class com.mobfox.adapter.** { *; }
-keep class com.mobfox.sdk.** { *; }

# MOPUB
-keepclassmembers class com.mopub.** { public *; }
-dontnote com.mopub.**
-dontwarn com.mopub.**
-keep public class com.mopub.**
-keep class com.mopub.mobileads.** { *; }
-keep class * extends com.mopub.mobileads.CustomEventBanner {}
-keep class * extends com.mopub.mobileads.CustomEventInterstitial {}
-keep class * extends com.mopub.nativeads.CustomEventNative {}
-keep class * extends com.mopub.nativeads.CustomEventRewardedAd {}
-keepclassmembers class ** { @com.mopub.common.util.ReflectionTarget *; }
-keepclassmembers class com.integralads.avid.library.mopub.** { public *; }
-keep public class com.integralads.avid.library.mopub.**
-keepclassmembers class com.moat.analytics.mobile.mpub.** { public *; }
-keep public class com.moat.analytics.mobile.mpub.**
-keep class com.google.android.gms.common.GooglePlayServicesUtil { *; }
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient { *; }
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info { *; }
-keep class * extends java.util.ListResourceBundle { protected Object[][] getContents(); }
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { public static final *** NULL; }
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * { @com.google.android.gms.common.annotation.KeepName *; }
-keepnames class * implements android.os.Parcelable { public static final ** CREATOR; }
-keep public class android.webkit.JavascriptInterface {}

# MYTARGET
-keep class com.my.target.** {*;} 

# NEND
-keep class net.nend.android.** { *; }
-dontwarn net.nend.android.**

# NATIVEX
-dontwarn com.nativex.**
-keep class com.nativex.** { *; }

# OGURY
-dontwarn com.ogury.**
-keep class com.ogury.** { *; }

# OUTBID
-dontwarn outbid.com.outbidsdk.**
-keep class outbid.com.outbidsdk.** { *; }

# QUMPARA
-dontwarn com.qumpara.analytics.**
-keep class com.qumpara.analytics.** { *; }
-dontwarn com.qumpara.offerwall.sdk.**
-keep class com.qumpara.offerwall.sdk.** { *; }

#POLLFISH
-dontwarn com.pollfish.** 
-keep class com.pollfish.** { *; }

# PUBNATIVE
-keepattributes Signature
-keep class net.pubnative.** { *; }
-dontwarn net.pubnative.**
-keep class com.squareup.picasso.** { *; }
-dontwarn com.squareup.picasso.**

# REVMOB
-dontwarn rm.com.android.sdk.**
-keep class rm.com.android.sdk.** { public *; }

# RETROFIT
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}

# SMAATO
-dontwarn com.smaato.**
-keep class com.smaato.** { public *; }
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
}
-keep public class com.smaato.soma.internal.connector.OrmmaBridge { public *; }
-keepattributes *Annotation*
-dontwarn com.smaato.soma.SomaUnityPlugin*
-dontwarn com.millennialmedia**
-dontwarn com.facebook.**

# SMARTAD
-keep class com.smartadserver.** { *; }
-dontwarn com.smartadserver.**


# STARTAPP
-keepattributes Exceptions, InnerClasses, Signature, Deprecated, SourceFile, LineNumberTable, *Annotation*, EnclosingMethod
-dontwarn android.webkit.JavascriptInterface
-keep class com.startapp.** { *; }
-dontwarn com.startapp.**

# TAPJOY
-keep class com.tapjoy.** {*;}
-keep class com.moat.** {*;}
-keepattributes JavascriptInterface
-keepattributes *Annotation*
-keep class * extends java.util.ListResourceBundle {protected Object[][] getContents();}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {public static final *** NULL;}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {@com.google.android.gms.common.annotation.KeepName *;}
-keepnames class * implements android.os.Parcelable {public static final ** CREATOR;}
-keep class com.google.android.gms.ads.identifier.** {*;}
-dontwarn com.tapjoy.**

# TAPPX
-keepattributes *Annotation*
-keepclassmembers class com.google.**.R$* { public static <fields>; }
-keep public class com.google.ads.** {*;}
-keep public class com.google.android.gms.** {*;}
-keep public class com.tappx.** { *; }
-dontwarn com.tappx.**

#TIKTOK
-keep class com.bytedance.sdk.openadsdk.** { *; }
-keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;}
-keep class com.pgl.sys.ces.** {*;}
-keep class com.bytedance.embed_dr.** {*;}
-keep class com.bytedance.embedapplog.** {*;}

# UNITY
-dontwarn com.unity3d.**
-keep class com.unity3d.ads.** { *; }

# Vungle
-dontwarn com.vungle.**
-dontnote com.vungle.**
-keep class com.vungle.** { *; }
-dontwarn com.vungle.warren.error.VungleError$ErrorCode
-keep class com.moat.** { *; }
-dontwarn com.moat.**
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
-keepattributes Signature
-keepattributes InnerClasses
-keepattributes *Annotation*
-dontwarn sun.misc.**
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keep class com.google.android.gms.internal.** { *; }
-dontwarn com.google.android.gms.ads.identifier.**

-keepclassmembers enum com.vungle.warren.** { *; }
-dontwarn kotlin.Unit
-dontwarn retrofit2.-KotlinExtensions
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}
-dontwarn okhttp3.**
-dontwarn javax.annotation.**
-dontwarn org.conscrypt.**
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
-keepclassmembers class * extends com.vungle.warren.persistence.Memorable {
    public <init>(byte[]);
}

#YANDEX
-dontwarn com.yandex.**
-keep class com.yandex.** { *; }                        

# YOUAPPI
-keep class com.google.gson.**{ *;}
-keep class com.google.android.gms.**{*;}
-keep class com.youappi.sdk.**{*;}
-keep interface com.youappi.sdk.**{*;}
-keep enum com.youappi.sdk.**{*;}
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

# VERIZON
-keepclassmembers class com.verizon.ads** {
public *;
}
-keep class com.verizon.ads**

            

Usage

Initialization

To initialize Admost Mediation SDK, import 'package:admost_flutter_plugin/admost.dart'; to your file;

import 'package:admost_flutter_plugin/admost.dart'; 

and initialize AMRSDK with Admost.initialize()


Admost.initialize(
    appId: Platform.isIOS
        ? "15066ddc-9c18-492c-8185-bea7e4c7f88c"
        : "6cc8e89a-b52a-4e9a-bb8c-579f7ec538fe",
    userConsent: "<your_userConsent_value>",
    subjectToGDPR: "<your_subjectToGDPR_value>",
    subjectToCCPA: "<your_subjectToCCPA_value>");
}
                

For testing you can use following Application Id;


IOS Application Id: "15066ddc-9c18-492c-8185-bea7e4c7f88c"
Android Application Id: "6cc8e89a-b52a-4e9a-bb8c-579f7ec538fe"

                

GDPR and CCPA

Once you have collected the user’s consent, you can pass it onto the SDK using the init configuration parameters shown above.

userConsent has a boolean parameter. If you have the user’s consent, set it YES. If you do not have the user's consent, set it NO.

subjectToGDPR has a boolean parameter. If you know the user is subject to GDPR, set it YES. If you know the user is not subject to GDPR, set it NO.

subjectToCCPA has a boolean parameter. If you know the user is subject to CCPA, set it YES. If you know the user is not subject to CCPA, set it NO.

If you don’t pass the user’s consent or subjectToGDPR to the SDK, the rules described in GDPR have been applied.

If you don’t pass the user’s consent or subjectToCCPA to the SDK, the rules described in CCPA have been applied.

Important Default banner size changed from Fullscreen width to 320x50, 728x90 and 300x250.
If you are using 320x90 banner, please contact with your account manager.

There are 3 types of banner size; 320x50, 728x90 and 300x250 banner.

To create and show a banner ad first import 'package:admost_flutter_plugin/admost_banner.dart'; and 'package:admost_flutter_plugin/admost_banner_size.dart'; to your file

Also if you want handle ad events, import 'package:admost_flutter_plugin/admost_ad_events.dart';


// main.dart

import 'package:admost_flutter_plugin/admost_banner.dart';
import 'package:admost_flutter_plugin/admost_banner_size.dart';

import 'package:admost_flutter_plugin/admost_ad_events.dart'

                

Then declare your banner with AdmostBanner and handle ad events with listener:


AdmostBanner(
    adUnitId: Platform.isIOS
        ? "b4009772-de04-42c4-bbaa-c18da9e4a1ab"
        : '9fb970db-7d96-4ef2-ac8c-d88ec22270ff',
    adSize: AdmostBannerSize.LEADERBOARD,
    listener: (AdmostAdEvent event, Map args) {
        if (event == AdmostAdEvent.loaded) {
            // It indicates that the banner ad is loaded.
        }
        if (event == AdmostAdEvent.clicked) {
            // It indicates that the banner ad is clicked.
        }
        if (event == AdmostAdEvent.failedToLoad) {
            // It indicates that the banner ad received no-fill response from all of its placements.
            print("Error code: ${args['errorCode']}");
            print("Error message: ${args['errorMessage']}");
        }
    },
)                          
                

For testing you can use following Banner Zone Id;


IOS Banner Zone Id: "b4009772-de04-42c4-bbaa-c18da9e4a1ab"
Android Banner Zone Id: "9fb970db-7d96-4ef2-ac8c-d88ec22270ff"

                

Optionally you can set the width of the banner, default value is 320px for 50px banner, 728px for 90px banner, 300px for 250px banner.


AdmostBanner(
    .
    .
    adSize: AdmostBannerSize(width:<width>,height:<height>,name:<"SizeName">),
    listener: ..,
) 
                

There are 3 event in AdmostBanner


AdmostBanner(
    ...
    listener: (AdmostAdEvent event, Map args) {
        if (event == AdmostAdEvent.loaded) {
            // It indicates that the banner ad is loaded.
        }
        if (event == AdmostAdEvent.clicked) {
            // It indicates that the banner ad is clicked.
        }
        if (event == AdmostAdEvent.failedToLoad) {
            // It indicates that the banner ad received no-fill response from all of its placements.
        }
    },
) 
                    
loaded state is returned when banner received.

 
if (event == AdmostAdEvent.loaded) {
    // It indicates that the Banner ad is loaded.
}     
clicked state is returned when banner clicked.

 
if (event == AdmostAdEvent.clicked) {
    // It indicates that the banner ad is clicked.
}  
                 

If failedToLoad state is returned investigate error to adress the problem.

 
 if (event == AdmostAdEvent.failedToLoad) {
    // It indicates that the banner ad received no-fill response from all of its placements.
    print("Error code: ${args['errorCode']}");
    print("Error message: ${args['errorMessage']}");
 }     

Customize Native Ad Appearance (Optional)

You can change the appearance of native ads to suit your application's design.

To create and show a native ad you need import 'package:admost_flutter_plugin/admost_native_ad.dart';to your file

 import 'package:admost_flutter_plugin/admost_native_ad.dart';

IOS Native Ad

To add native ads on IOS , download the CustomXibs.zip file and extract in <your project>/ios/Runner path.

You can change the layout and design of following assets;

shadowed image

If you want to use your own layouts you can create a copy and modify one of the custom sized samples (CustomNative150x250.xib, CustomNative200x200.xib or CustomNative300x120.xib) and change their frame to fit your design.

shadowed image

After creating your native xib file on the iOS side, then declare your banner with AdmostNativeAd. You must pass the xibNameForIOS: parameter.


   
        xibNameForIOS: 'AMRNativeAdBaseView250',
     

AdmostNativeAd(
    adUnitId: Platform.isIOS
        ? 'c72a4a52-23c5-4c34-9eb1-7bbc4c08c7e4'
        : 'f3915393-7f42-4b9d-97c3-e7d4017c7591',
    adSize: AdmostBannerSize(width:200,height:200,name:"AMRNativeAdBaseView250"),
    xibNameForIOS: 'AMRNativeAdBaseView250',
    listener: (AdmostAdEvent event, Map args) {
        if (event == AdmostAdEvent.loaded) {
            // It indicates that the banner ad is loaded.
        }
        if (event == AdmostAdEvent.clicked) {
            // It indicates that the banner ad is clicked.
        }
        if (event == AdmostAdEvent.failedToLoad) {
            // Ad is not loaded and can not be shown.
            print("Error code: ${args['errorCode']}");
            print("Error message: ${args['errorMessage']}");
        }
    },
)

Android Native Ad

For Android, you can follow the following steps;

  1. Define a layout file in the android layout folder for your custom native design
  2. 
                            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="match_parent"
                 android:layout_height="120dp"
                 android:background="@android:color/white"
                 android:orientation="horizontal">
    
        <ImageView
            android:id="@+id/admost_flutter_back_image"
            android:layout_width="145dp"
            android:layout_marginLeft="5dp"
            android:adjustViewBounds="true"
            android:layout_gravity="left|center"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:visibility="gone"/>
    
        <ImageView
            android:id="@+id/admost_flutter_main_image"
            android:layout_width="145dp"
            android:layout_marginLeft="5dp"
            android:adjustViewBounds="true"
            android:layout_gravity="left|center"
            android:layout_height="wrap_content"
            android:scaleType="fitXY" />
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginTop="0dp">
    
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|left"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="5dp"
                android:orientation="horizontal">
    
                <ImageView
                    android:id="@+id/admost_flutter_icon"
                    android:layout_width="14dp"
                    android:layout_height="14dp"
                    android:layout_marginRight="4dp"
                    android:layout_marginTop="6dp"
                    android:background="@null"
                    android:scaleType="fitXY" />
    
                <TextView
                    android:id="@+id/admost_flutter_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textStyle="bold"
                    android:layout_marginRight="15dp"
                    android:maxLines="1"
                    android:layout_marginTop="5dp"
                    android:gravity="center_vertical"
                    android:text="Title"
                    android:textColor="#ff000000"
                    android:textSize="14sp" />
            </LinearLayout>
    
            <TextView
                android:id="@+id/admost_flutter_attribution"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|right"
                android:layout_marginTop="30dp"
                android:layout_marginLeft="10dp"
                android:text="Ad"
                android:textColor="#ffacabab"
                android:textSize="12sp" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="35dp"
                android:layout_marginLeft="10dp"
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/admost_flutter_detail"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="10dp"
                    android:layout_marginTop="5dp"
                    android:ellipsize="end"
                    android:lineSpacingExtra="3dp"
                    android:maxLines="2"
                    android:paddingBottom="5dp"
                    android:paddingTop="8dp"
                    android:text="Title Lorem ipsom dolor sit amet consaposod elit"
                    android:textColor="#cc2a2e32"
                    android:textSize="12sp"/>
    
                <Button
                    android:id="@+id/admost_flutter_cta"
                    android:layout_width="match_parent"
                    android:layout_height="36dp"
                    android:layout_marginBottom="12dp"
                    android:layout_marginTop="-10dp"
                    android:layout_gravity="center"
                    android:gravity="center"
                    android:text="Go"
                    android:textStyle="bold"
                    android:textSize="14sp"
                    android:textColor="@android:color/black"/>
    
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/admost_flutter_ad_choices"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:gravity="right"
                android:orientation="vertical"/>
        </RelativeLayout>
    
    </LinearLayout>
                        
  3. Create a AdMostViewBinder object in the MainActivity and assign this object as the static native binder
  4. 
    val binder: AdMostViewBinder = admost.sdk.AdMostViewBinder.Builder(R.layout.custom_layout_flutter)
                    .iconImageId(R.id.cardIcon)
                    .titleId(R.id.cardTitle)
                    .callToActionId(R.id.CallToActionTextView)
                    .textId(R.id.cardDetailText)
                    .attributionId(R.id.cardAttribution)
                    .mainImageId(R.id.cardImage)
                    .backImageId(R.id.cardBack)
                    .privacyIconId(R.id.ad_choices)
                    .isRoundedMode(true)
                    .build()
    
    AdmostFLTNativeAdBinder.getInstance().binder = binder;
                        

Interstitial Ads

To create and show an interstitial ad first import 'package:admost_flutter_plugin/admost_interstitial.dart'; to your file and declare an AdmostInterstitial object;


import 'package:admost_flutter_plugin/admost.dart';
import 'package:admost_flutter_plugin/admost_interstitial.dart';
.
.

class _MyHomePageState extends State<MyHomePage> {

    String interstitialText = 'Load Interstitial';
    AdmostInterstitial interstitialAd;
    .
    .
    .
    if (interstitialAd == null) {
        interstitialAd = AdmostInterstitial(
          zoneId: Platform.isIOS
              ? '39f74377-5682-436a-9338-9d1c4df410bd'
              : 'f99e409b-f9ab-4a2e-aa9a-4d143e6809ae',
          listener:...
    }

    if (await interstitialAd.isLoaded) {
        interstitialAd.show();
    } else {
        interstitialAd.load();
    }
    .
    .
    .
}
                

For testing you can use following Interstitial Zone Id;


IOS Interstitial Zone Id: "39f74377-5682-436a-9338-9d1c4df410bd"
Android Interstitial Zone Id: "f99e409b-f9ab-4a2e-aa9a-4d143e6809ae"
                

There are 6 state in AdmostInterstitial.


AdmostInterstitial(
    zoneId: Platform.isIOS
        ? '39f74377-5682-436a-9338-9d1c4df410bd'
        : 'f99e409b-f9ab-4a2e-aa9a-4d143e6809ae',
    listener: (AdmostAdEvent event, Map args) {
        if (event == AdmostAdEvent.loaded) {
            // It indicates that the interstitial ad is loaded and ready to show.
            print("Interstitial network: ${args['network']}");
            print("Interstitial ecpm: ${args['ecpm']}");
        }
        if (event == AdmostAdEvent.opened) {
            // It indicates that the interstitial ad is showed.
        }
        if (event == AdmostAdEvent.clicked) {
            // It indicates that the interstitial ad is clicked.
        }
        if (event == AdmostAdEvent.failedToLoad) {
            // It indicates that the interstitial ad received no-fill response from all of its placements.
            print("Error code: ${args['errorCode']}");
            print("Error message: ${args['errorMessage']}");
        }
        if (event == AdmostAdEvent.failedToShow) {
            // Indicates that the interstitial ad was received but there was a problem while it was showing.
            print("Error code: ${args['errorCode']}");
            print("Error message: ${args['errorMessage']}");
        }
        if (event == AdmostAdEvent.dismissed) {
            // It indicates that the interstitial ad is dismissed. 
        }
        
    },
);
                

When isLoaded is true just call the .show() method to present interstitial.

  if (await interstitialAd.isLoaded) {
    interstitialAd.show();
} else {
    interstitialAd.load();
}

If failedToLoad state is returned investigate error to adress the problem.

Important Attempting to load a new interstitial from the failedToLoad methods is strongly discouraged.

 if (event == AdmostAdEvent.failedToLoad) {
    print("Error code: ${args['errorCode']}");
    print("Error message: ${args['errorMessage']}");
}

failedToShow event state is returned to inform the application that the received interstitial failed to be shown. This delegate expected to be returned very rarely but if it is returned you should either load another interstitial or resume tasks.

 if (event == AdmostAdEvent.failedToShow) {
    print("Error code: ${args['errorCode']}");
    print("Error message: ${args['errorMessage']}");
}

opened state is returned to inform the application that the received interstital is shown.

 if (event == AdmostAdEvent.opened) {
    // It indicates that the interstitial ad is showed.
}
clicked state is returned when interstital clicked.

if (event == AdmostAdEvent.clicked) {
    // Interstitial Ad clicked. 
    print("Network: ${args['network']}");
}

dismissed state is returned to inform the application that the interstitial is closed by clicking cross button/back button. You can use this callback to resume paused tasks during interstitial presentation.

You can use dismissed callback and reload a interstitial ad.

if (event == AdmostAdEvent.dismissed) {
    // Interstitial Ad dismissed. 
}

Rewarded Video Ads

Rewarded video ads integration is pretty similar to Interstitial ads with 2 additional event. To create and show a rewarded video ad first import 'package:admost_flutter_plugin/admost_rewarded.dart' to your file and declare an AdmostRewarded property;


import 'package:admost_flutter_plugin/admost.dart';
import 'package:admost_flutter_plugin/admost_rewarded.dart';
.
.

class _MyHomePageState extends State<MyHomePage> {

    String rewardedText = 'Load Rewarded';
    AdmostRewarded rewardAd;
    .
    .
    .
    if (rewardAd == null) {
        rewardAd = AdmostRewarded(
          zoneId: Platform.isIOS
              ? '2bdefd44-5269-4cbc-b93a-373b74a2f067'
              : '88cfcfd0-2f8c-4aba-9f36-cc0ac99ab140',
          listener: (AdmostAdEvent event, Map<String, dynamic>args) {
            if (event == AdmostAdEvent.loaded) {
              rewardedText = 'Show Rewarded';
              setState(() {
                rewardedText;
              });
            } else if (event == AdmostAdEvent.dismissed) {
              rewardedText = 'Load Rewarded';
              setState(() {
                rewardedText;
              });
            } else if (event == AdmostAdEvent.failedToLoad) {
                // It indicates that the interstitial ad received no-fill response from all of its placements.
                print("Error code: ${args['errorCode']}");
                print("Error message: ${args['errorMessage']}");
            } else if (event == AdmostAdEvent.completed) {
                // It indicates that the user deserves to receive a reward. You may need to store this information in a variable and give a reward
            }
          },
        );
      }

      if (await rewardAd.isLoaded) {
        rewardAd.show();
      } else {
        rewardAd.load();
      }
    .
    .
    .
}
                

For testing you can use following RewardedVideo Zone Id;


IOS RewardedVideo Zone Id: "2bdefd44-5269-4cbc-b93a-373b74a2f067"
Android RewardedVideo Zone Id: "88cfcfd0-2f8c-4aba-9f36-cc0ac99ab140"
                

There are 7 event methods in AdmostRewarded.


AdmostRewarded(
    zoneId: Platform.isIOS
        ? '2bdefd44-5269-4cbc-b93a-373b74a2f067'
        : '88cfcfd0-2f8c-4aba-9f36-cc0ac99ab140',
    listener: (AdmostAdEvent event, Map args) {
        if (event == AdmostAdEvent.loaded) {
            print("Rewarded network: ${args['network']}");
            print("Rewarded ecpm: ${args['ecpm']}");
        } else if (event == AdmostAdEvent.dismissed) {
            // It indicates that the rewarded ad is dismissed. 
        } else if (event == AdmostAdEvent.failedToLoad) {
            // It indicates that the rewarded ad received no-fill response from all of its placements.
            print("Error code: ${args['errorCode']}");
            print("Error message: ${args['errorMessage']}");
        } else if (event == AdmostAdEvent.failedToShow) {
            // Indicates that the rewarded ad was received but there was a problem while it was showing.
            print("Error code: ${args['errorCode']}");
            print("Error message: ${args['errorMessage']}");
        } else if (event == AdmostAdEvent.clicked) {
            // It indicates that the rewarded ad clicked.
        } else if (event == AdmostAdEvent.opened) {
            // It indicates that the rewarded ad is showed.
        } else if (event == AdmostAdEvent.completed) {
            // It indicates that the user deserves to receive a reward. You may need to store this information in a variable and give a reward
        }
    },
);
                

When isLoaded is true just call the .show() method to present rewarded video.

  if (await rewardAd.isLoaded) {
    rewardAd.show();
} else {
    rewardAd.load();
}

If failedToLoad state is returned investigate error to adress the problem.

Important Attempting to load a new rewarded video from the failedToLoad methods is strongly discouraged.

 if (event == AdmostAdEvent.failedToLoad) {
    // It indicates that the rewarded ad received no-fill response from all of its placements.
    print("Error code: ${args['errorCode']}");
    print("Error message: ${args['errorMessage']}");
}

opened state is returned to inform the application that the received rewarded video is shown.

 if (event == AdmostAdEvent.opened) {
    // It indicates that the rewarded ad is showed.
}

failedToShow event state is returned to inform the application that the received rewarded video failed to be shown. This delegate expected to be returned very rarely but if it is returned you should either load another reward video or resume tasks.

 if (event == AdmostAdEvent.failedToShow) {
    // Indicates that the rewarded ad was received but there was a problem while it was showing.
    print("Error code: ${args['errorCode']}");
    print("Error message: ${args['errorMessage']}");
}

clicked state is returned when rewarded video clicked.

if (event == AdmostAdEvent.clicked) {
    // It indicates that the rewarded ad clicked.
    print("Network: ${args['network']}");
}

completed state is returned to inform the application that the user completed watching the video to a certain point to get the reward. The video may have finished or keep playing after completed is returned. Use this state to reward the user.

Important Attempting to load a new rewarded video from the completed states is strongly discouraged.

if (event == AdmostAdEvent.completed) {
    // It indicates that the user deserves to receive a reward. You may need to store this information in a variable and give a reward
    player.reward();
  }

dismissed state is returned to inform the application that the rewarded video is closed by clicking cross button/back button. You can use this state to resume paused tasks during rewarded video presentation.

You can use dismissed state and reload a new rewarded video ad.

if (event == AdmostAdEvent.dismissed) {
    animation.resume();
} 

Extras

Test Suite

You can use Test Suite to test your ad networks with your zone ids.

To use Test Suite in your application, you can use one of the following codes;


Admost.startTestSuite(Platform.isIOS
    ? "15066ddc-9c18-492c-8185-bea7e4c7f88c"
    : "6cc8e89a-b52a-4e9a-bb8c-579f7ec538fe");
                

Screen Shot

shadowed image

Screen Shot

android-test-suite screenshot

In App Purchase Tracking


IAP IOS

The following method is used to track purchases with receipt validation in ios:


    Admost.trackIAPForIOS(transactionId, currency, amount, ['tag1', 'tag2']);

					
                

Explanation of Parameters:

  • transactionId – Transaction identifier of SKPaymentTransaction.
  • currencyCode – Currency code of transaction.
  • amount – Amount of transaction.
  • tags – You can use to analyze and differentiate the purchases.

IAP Android

The following method is used to track purchases with receipt validation in android:

Admost.trackIAPForAndroid(originalJSON, signature, currency, amount, ['tag1', 'tag2'])
                

Explanation and code samples of parameters:

  • originalJSON – a String in JSON format that contains details about the purchase order. It is returned by the operating system after you make the purchase call.
  • signature – String containing the signature of the purchase data that the developer signed with their private key. It is returned by the operating system after you make the purchase call.
  • currency – Currency code of transaction.
  • amount – Amount of transaction.
  • tags – You can use the purchases to be analyzed and differentiated.

Setting Application User Id

You can use the following method to set application specific user id in Admost Analytics for enhanced tracking of your users. You should to call this method before initialization.


                    Admost.setUserId("applicationUserId");
                

Adjust Integration

Follow the official ADJUST documents to integrate AdjustSDK in to your app.

AppsFlyer Integration

Follow the official APPSFLYER documents to integrate AppsFlyerSDK in to your app.

Privacy Consent Required

You can optionally use isPrivacyConsentRequired property to obtain the user is in a GDPR or CCPA required country.


var privacyConsentStatus = await Admost.isPrivacyConsentRequired;
                

Apple App Privacy (IOS Only)

Starting December 8, 2020, Apple has announced a privacy disclosure for the App Store, You must define which data are collected by your apps and any SDKs you have integrated. To improve the performance of AdMost, the AMRSDK may collect following information from your apps:

  • User ID – If you are using setUserId method to identify users with your custom app user ID, you will need to select 'User ID'
  • Purchases – If you are using in app purchase trackings methods, you will need to select 'Purchases'
  • Coarse Location – To estimate the general location of a device
  • Product Interaction – Analytics purposes
  • Advertising Data – Analytics purposes