in_house_ads 1.5.0 copy "in_house_ads: ^1.5.0" to clipboard
in_house_ads: ^1.5.0 copied to clipboard

PlatformAndroid

Reusable in-house (cross-promo) native, banner, interstitial, and rewarded ads for Android Flutter apps.

in_house_ads #

Reusable Android-only Flutter package for cross-promo (in-house) native, banner, and interstitial ads.

Consuming apps supply their own apps.json asset and configure theming / analytics via InHouseAds.configure.

Setup #

1. Add the dependency #

dependencies:
  in_house_ads: ^1.0.0

2. Bundle your ads JSON #

Keep an apps.json asset in the host app (schema below) and declare it in the host pubspec.yaml:

flutter:
  assets:
    - assets/in_house_ads/

3. Configure once at startup #

Call before using any repository / widget APIs (typically in main() before runApp):

import 'package:in_house_ads/in_house_ads.dart';

InHouseAds.configure(
  InHouseAdsConfig(
    assetPath: 'assets/in_house_ads/apps.json',
    currentAppId: 'com.example.myapp', // filtered out of rotation
    theme: const InHouseAdsTheme(
      cardColor: Color(0xFFFFFFFF),
      borderColor: Color(0xFFBBF7D0),
      badgeBackground: Color(0xFFDCFCE7),
      accentColor: Color(0xFF16A34A),
      ctaTextColor: Color(0xFFFFFFFF),
      textColor: Color(0xFF000000),
      secondaryTextColor: Color(0xFF616161),
    ),
    onAdClicked: ({required type, required title}) {
      // Optional analytics hook
    },
    // Optional: remote-configurable routing (see below).
    remoteUrl: 'https://your-host.example/in-app-ads-data.json',
    remoteRefreshInterval: Duration(hours: 6),
    // Optional: open store links in an in-app browser tab (Chrome Custom
    // Tabs on Android, SFSafariViewController on iOS) instead of the
    // external app/browser.
    linkMode: InHouseAdLinkMode.inAppBrowser,
  ),
);

Usage #

Native ad #

final ad = await InHouseAdRepository.pickForSlot('home_0');
if (ad != null) {
  return InHouseNativeAdView(ad: ad);
}
final ad = await InHouseAdRepository.pickForSlot('banner_0');
if (ad != null) {
  return InHouseBannerAdView(ad: ad);
}

Interstitial #

final ad = await InHouseAdRepository.pickNext();
if (ad != null && context.mounted) {
  await InHouseInterstitial.show(
    context: context,
    ad: ad,
    onComplete: () {},
  );
}

apps.json schema #

Top-level JSON array. Each entry:

Field Type Required Notes
title string yes App title
icon string yes Icon image URL
appId string yes Play Store package id
summary / description string no Body copy (summary preferred)
developer string no Developer name
headerImage string no Hero / banner image
screenshots string[] no Additional media URLs
url string no Store URL (defaults to Play Store for appId)
free bool no Default true
priceText string no CTA when free is false
rating number no Star rating
installs string no Install count label
ctaColor string no #RRGGBB, #AARRGGBB, or 0xAARRGGBB
imageOnly bool no See Image-only ad entries below
nativeImage / bannerImage / interstitialImage string or string[] no Static creative image(s) per placement, used when imageOnly is true. A single string or a JSON array of strings — multiple images rotate across separate impressions

The bundled local asset (assetPath) is always treated as this bare-array shape — it never carries routing information (see below).

Remote routing (optional) #

Instead of (or alongside) the bundled local asset, you can point the package at a hosted JSON file that lets you control, remotely and without an app update, which promoted apps show in which host app:

InHouseAdsConfig(
  assetPath: 'assets/in_house_ads/apps.json', // offline bootstrap / first-run fallback
  remoteUrl: 'https://your-host.example/in-app-ads-data.json',
  remoteRefreshInterval: Duration(hours: 6),
)

The remote URL must serve a JSON object with two keys:

{
  "apps": [ /* same per-entry schema as apps.json above */ ],
  "routing": {
    "com.example.hostAppA": ["com.example.promotedApp1", "com.example.promotedApp2"]
  }
}
  • apps is the full ad pool, same schema as the local apps.json.
  • routing maps a host app's currentAppId to the list of promoted appIds it's allowed to show. A host app with no entry in routing shows every ad except itself (opt-out default) — add an entry only for apps whose ad set you want to restrict or curate.

Fetch/cache behavior: on every launch, the package resolves ads immediately from whichever source is available (never blocking on a network call): the last successfully fetched remote payload if one has ever been persisted, otherwise the bundled assetPath asset. In the background, if the persisted payload is missing or older than remoteRefreshInterval, the package fetches remoteUrl and — only if the response is valid — persists it for use starting on the next app launch. A failed fetch is silently ignored and the previously persisted data is left untouched, so there's never a mid-session change or flicker.

Image-only ad entries #

For partner placements that only supply a static creative image with no app-store-style metadata (e.g. game-portal partners), set "imageOnly": true on that entry and supply nativeImage / bannerImage / interstitialImage (each falls back to headerImage/screenshots/icon if omitted). Native, banner, and interstitial views render just the image plus a small "Ad" disclosure badge — no title, description, rating, or CTA text. Image-only entries are excluded from rewarded rotation (InHouseRewarded/pickNextRewarded), since rewarded's detail screen needs the full metadata.

Each of nativeImage / bannerImage / interstitialImage accepts either a single URL string or a JSON array of URL strings:

{
  "title": "Qureka",
  "icon": "https://example.com/qureka/icon.png",
  "appId": "com.qureka",
  "imageOnly": true,
  "nativeImage": ["https://example.com/qureka/native1.png", "https://example.com/qureka/native2.png"],
  "bannerImage": ["https://example.com/qureka/banner1.png", "https://example.com/qureka/banner2.png"],
  "interstitialImage": "https://example.com/qureka/interstitial1.png",
  "url": "https://play.google.com/store/apps/details?id=com.qureka"
}

When more than one image is supplied for a placement, the package rotates through them one at a time across separate impressions (each pickForSlot/pickNext call) rather than showing them all at once — a single string is equivalent to a one-item list.

Public API #

  • InHouseAds / InHouseAdsConfig / InHouseAdsTheme
  • InHouseAd / InHouseAdRepository
  • InHouseNativeAdView
  • InHouseInterstitial / InHouseInterstitialView

Platform support #

Designed and tested for Android only.

0
likes
160
points
12
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Reusable in-house (cross-promo) native, banner, interstitial, and rewarded ads for Android Flutter apps.

Repository (GitHub)

Topics

#ads #cross-promo #android

License

MIT (license)

Dependencies

cached_network_image, flutter, flutter_cache_manager, http, shared_preferences, url_launcher

More

Packages that depend on in_house_ads