Highfivve Advertising Flutter Plugin

A Flutter plugin to integrate Highfivve GmbH's native advertising SDKs for both Android and iOS, enabling you to display various ad formats within your Flutter application.

⚠️ Disclaimer: Official Highfivve GmbH Advertising SDK

This is the official Highfivve GmbH Advertising Software Development Kit (SDK) delivered as a Flutter Plugin. This plugin utilizes our native advertising_android(visit on github) and advertising_ios(visit on github) SDKs.

Important Usage Requirements:

  • Customer Status: To utilize this SDK and the Highfivve advertising services, you or your organization must be an active and approved customer of Highfivve GmbH.
  • Authorization: Access to and use of our advertising platform through this SDK require prior authorization and agreement with Highfivve GmbH's terms of service.
  • Contact for Access: If you are not yet a customer or wish to inquire about using our advertising services, please contact us to discuss your needs and begin the onboarding process.

Contact Information:

For new customer inquiries, SDK support or any questions regarding the use of this SDK, please reach out to us at:

team@highfivve.com

Using this SDK without being an authorized customer of Highfivve GmbH is a violation of our terms and may result in a lack of service or functionality.


Supported Platforms:

  • Android
  • iOS

Supported Ad Formats:

  • Banner Ads
  • Interstitial Ads

Table of Contents

Getting Started

Prerequisites

  • Flutter SDK: Version >= 3.3.0
  • Dart SDK: Version >= 3.4.3
  • Active Customer Status with Highfivve GmbH (See disclaimer above).

Installation

  1. Add this to your package's pubspec.yaml file:
dependencies:
  highfivve_advertising: ^0.0.1+5
  1. Install packages from the command line:
flutter pub get

Platform Specific Setup

Android

This plugin already depends on the native com.highfivve.sdk:advertising Android SDK itself - you don't need to (and shouldn't) add it again in your app's android/app/build.gradle, since declaring it twice risks resolving to two different versions.

  1. Google AdMob Integration To enable Google AdMob ads, add your AdMob App ID to your AndroidManifest.xml as shown below. This is required for Google ad serving to work correctly. Add the following inside the <application> tag in your android/app/src/main/AndroidManifest.xml:
<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-****************~**********"/>

Replace ca-app-pub-****************~********** with your actual AdMob App ID.

iOS

  1. Permissions: Add necessary permission strings to your ios/Runner/Info.plist file. For example, for App Tracking Transparency:

<key>NSUserTrackingUsageDescription</key><string>This identifier will be used to deliverpersonalized
ads to you.
</string>
  1. Add Google AdMob App ID:

To use Google AdMob with the Highfivve Advertising Flutter plugin on iOS, you must add your AdMob App ID to your app's Info.plist. Add the following inside the <dict> section of your ios/Runner/Info.plist:


<key>GADApplicationIdentifier</key><string>ca-app-pub-****************~**********</string>

Replace ca-app-pub-****************~********** with your actual AdMob App ID.

  1. SKAdNetwork Identifiers: To support ad attribution for ad networks participating in Apple's SKAdNetwork framework, you need to include their SKAdNetwork identifiers in your ios/Runner/Info.plist. For Google, you will add an entry for Google's SKAdNetwork identifier.

    Add the SKAdNetworkItems key with an array of dictionaries, where each dictionary contains a SKAdNetworkIdentifier key.

<key>SKAdNetworkItems</key>
<array>
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>cstr6suwn9.skadnetwork</string>
  </dict>
  <!-- Add more SKAdNetworkIdentifier entries as needed -->
</array>

This SKAdNetworkItems are needed for this sdk:

Google


<key>SKAdNetworkIdentifier</key><string>cstr6suwn9.skadnetwork</string>
  • Google's SKAdNetwork ID:
    • **More Information from Apple: ** Configuring a Source App for SKAdNetwork
    • **More Information from Google: ** Google Mobile Ads SDK iOS - SKAdNetwork ( Often covered within the Get Started or advanced setup pages for iOS 14+)
    • Note: Highfivve GmbH may provide an updated or consolidated list of SKAdNetworkIdentifier values to include, especially if mediating multiple networks. Always refer to the latest guidance from Highfivve and the respective ad networks.
  1. PrivacyInfo.xcprivacy: This plugin (and the native iOS SDK it wraps) already bundles its own PrivacyInfo.xcprivacy declaring the data it collects and the APIs it uses, as required by Apple. When you archive your app, Xcode aggregates privacy manifests from all included SDKs - make sure your app's own privacy details on App Store Connect accurately reflect this plugin's declarations plus any other third-party SDKs you integrate. If you enable other ad networks through this SDK, consult their own documentation for their privacy manifest details.

  2. Platform Version: Ensure your Podfile in ios/Podfile targets a compatible iOS version ( e.g., platform :ios, '15.0'). This plugin requires iOS 15.0+.

  3. Podfile Configuration: Ensure your Podfile is configured to use frameworks.

target 'Runner' do
  use_frameworks! :linkage => :static #<-- Ensure this line is present

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
  target 'RunnerTests' do
    inherit! :search_paths
  end
end

Usage

Initializing the SDK

It's crucial to initialize the HighfivveAdManager at the start of your application, preferably in your main.dart.

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:highfivve_advertising/highfivve_advertising.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  try {
    await HighfivveAdManager.instance.initialize(
      // When the bundle name is the same for both platforms, you don´t need this differentiation. 
      bundleName: Platform.isAndroid
          ? 'com.example.your_bundle_name_android' // Replace with your actual Android app ID
          : 'com.example.your_bundle_name_ios', // Replace with your actual iOS app ID
      publisherCode: 'your-publisher-code', // Provided by Highfivve GmbH
    );
    print("HighfivveAdManager initialized successfully.");
  } catch (e) {
    print("Failed to initialize HighfivveAdManager: $e");
  }
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  @override Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Advertising SDK Example',
      home: Scaffold(
        appBar: AppBar(title: Text('Advertising Example')),
        body: Center(child: Text('Welcome to the app!')),
      ),
    );
  }
}

The SDK is built to work with any Consent Management Platform (CMP) - it does not assume you use a specific one. There are two ways consent reaches the SDK, and you can rely on either or combine both:

If your CMP is IAB TCF/GPP-compliant (virtually all commercial CMPs are, including Google's own User Messaging Platform), it already writes consent to the standard keys - IABTCF_TCString, IABTCF_gdprApplies, IABGPP_HDR_GppString, IABGPP_GppSID - in SharedPreferences (Android) / UserDefaults (iOS). The SDK's Prebid integration and Google Ad Manager both read these directly. You don't have to call anything - just make sure your CMP flow has run before ads are requested.

2. Explicit: updateConsent

Call this when you want to be explicit, when your CMP doesn't write the standard keys, or to supply signals the standard keys don't cover:

import 'package:highfivve_advertising/highfivve_advertising.dart';

await
HighfivveAdManager.instance.updateConsent
(
ConsentInfo(
personalizationState: AdPersonalizationState.personalizedAllowed, // or .nonPersonalizedOnly / .adsDisallowed / .unknown
gdprApplies: true,
tcString: myCmp.tcString,
gppString: myCmp.gppString,
gppApplicableSections: myCmp.gppApplicableSections,
acString:
myCmp
.
additionalConsentString
, // see the Meta note below
)
,
);

Call this again whenever consent changes (e.g. the user updates their choice), not just once at startup.

Every field is independent and additive - leave a field unset if you don't have that signal. The SDK only overrides a given ad network's own implicit consent detection when the corresponding field is non-null, so calling updateConsent for one purpose (e.g. only supplying acString) never clobbers signals you didn't set. In particular: if you don't pass tcString, Prebid's own implicit read of the on-device TCF string is left completely untouched.

personalizationState drives two things: whether the SDK requests non-personalized/contextual ads instead of personalized ones, and - for .adsDisallowed - whether it skips ad requests entirely. Map a "no valid consent decision yet" state (timeout, error, not yet answered) to .nonPersonalizedOnly rather than .adsDisallowed: contextual ads are still legally servable in that case, and .adsDisallowed should be reserved for a genuine, confirmed objection to all ad requests.

Meta Audience Network is not on the IAB Global Vendor List, so it isn't covered by the standard TC-string auto-detection - it needs the separate IAB "Additional Consent" (AC) string via the acString field if you mediate through Meta.

Displaying a Banner Ad (HighfivveBannerAdWidget)

The HighfivveBannerAdWidget is a stateful widget used to display banner ads. It automatically adjusts its height based on the ad size received from the server.

import 'package:highfivve_advertising/highfivve_advertising.dart';

// Inside your widget's build method: 
HighfivveBannerAdWidget
(
position: 'content_1', // Unique identifier for this ad placement 
showWidget: true, // Optional: Control visibility - default is true
pageType: 'article_list', // Optional: context for the ad  
maxHeight: 300 //Optional: to allocate a fixed height of the widget 
onAdNotFound: () {print('Ad not found');} //Optional: this method is triggered when a ad for a specific position is not found
)

Parameters for HighfivveBannerAdWidget:

  • position (required): String - A unique identifier for this ad slot position.
  • showWidget (optional): bool - Controls if the widget attempts to load and show an ad. Defaults to true.
  • pageType (optional): String - An optional string to specify the type or context of the page where the ad is displayed.
  • maxHeight (optional): int - to allocate a fixed max height of the widget.
  • onAdNotFound (optional): Function() - Callback for when an ad position is not found.
  • autoRefreshEnabled (optional): bool - Whether the banner automatically reloads on an interval. Defaults to true.
  • refreshInterval (optional): Duration - Overrides the reload interval used when autoRefreshEnabled is true. Defaults to the SDK's built-in interval (30 seconds) when unset.

A client-side reload is used (rather than relying on Google Ad Manager's server-side refresh) so that header bidding runs a fresh auction on every reload.

Displaying an Interstitial Ad

Use HighfivveInterstitialAd rather than a widget - it wraps loading/showing and tracks isLoading/isLoaded state for you. Construct it once per placement, load it ahead of time, and show it when appropriate:

import 'package:highfivve_advertising/highfivve_advertising.dart';

final interstitialAd = HighfivveInterstitialAd();

await
interstitialAd.load
('interstitial_main
'
, pageType: 'article_list'); // pageType is optional

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

(Internally this delegates to HighfivveAdManager.instance.loadInterstitialAd/ showInterstitialAd, which you can also call directly if you want to manage load state yourself.)

By default, the SDK automatically preloads the next interstitial as soon as the current one is dismissed. Configure this via:

// Disable automatic preloading, or add a delay before it happens:
await
HighfivveAdManager.instance.setInterstitialAutoReloadEnabled
(false);await HighfivveAdManager.instance.setInterstitialReloadDelay(const Duration(seconds:
5
)
);

Handling Ad Events

Listen to the global HighfivveAdManager.instance.adEvent stream to observe ad lifecycle events (loaded, failed, opened, closed, clicked, impression, not found, disabled, blocked by consent) for both banners and interstitials:

import 'dart:async';
import 'package:highfivve_advertising/highfivve_advertising.dart';

late final StreamSubscription<AdEvent> _adEventSubscription;

@override
void initState() {
  super.initState();
  _adEventSubscription = HighfivveAdManager.instance.adEvent.listen((event) {
    print('Ad event: ${event.eventType}, data: ${event.data}');
    if (event.eventType == AdEventType.clicked) {
      // Handle ad click
    }
  });
}

@override
void dispose() {
  _adEventSubscription.cancel();
  super.dispose();
}

HighfivveBannerAdWidget already listens to this stream internally to size itself and to hide itself on notFound/failedToLoad - you only need to listen directly for events not already covered by a widget's own callbacks (e.g. interstitial events, or global analytics).

API Reference

Full API documentation for this package is available here.

Example

An example application demonstrating the plugin's features can be found in the /example directory of this package.

License

This plugin is released under the Apache 2.0 License. See the LICENSE file for more details.