Create Free APK

Making money

AdMob Integration

Monetization Setup

1Create AdMob Account#

Sign up for a Google AdMob account. You'll need a Google account to get started. AdMob is Google's mobile advertising platform.

2Add Your App#

In AdMob dashboard:

  • Click 'Apps' in the sidebar
  • Click 'Add App'
  • Select 'No' for 'Is your app listed on a supported app store?'
  • Enter your app name
  • Select 'Android' as platform
  • Click 'Add'

3Get App ID#

After creating your app:

  • Copy the App ID shown (format: ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX)
  • This is different from your Ad Unit ID
  • You'll use this in AndroidManifest.xml
App ID format:
ca-app-pub-1234567890123456~1234567890

4Create Ad Unit (Banner)#

In your AdMob app:

  • Click 'Ad units' tab
  • Click 'Add ad unit'
  • Select 'Banner'
  • Enter ad unit name (e.g., 'Main Banner')
  • Click 'Create ad unit'
  • Copy the Ad Unit ID
Banner Ad Unit ID format:
ca-app-pub-1234567890123456/1234567890

5Setup in AppMint#

In AppMint, Step 3:

  1. Turn ON 'AdMob Ads' and paste your AdMob App ID (the one with ~)
  2. Ad Control: keep 'Automatic' - the app places the ads for you
  3. Turn ON 'Banner Ad', pick the Ad Position (Bottom or Top) and paste your Banner Ad Unit ID (the one with /)
  4. Continue with the other settings and generate your app
Ad Unit ID (not App ID):
ca-app-pub-XXXXXXXXXXXXXXXX/YYYYYYYYYY

6Test Ads in Your App#

During development, use Google's official test IDs to avoid policy violations. Copy-paste these into the generator:

πŸ“‹ AdMob App ID:
ca-app-pub-3940256099942544~3347511713

πŸ“‹ Banner Ad Unit ID:
ca-app-pub-3940256099942544/6300978111

πŸ“‹ Interstitial Ad Unit ID:
ca-app-pub-3940256099942544/1033173712

πŸ“‹ Rewarded Ad Unit ID:
ca-app-pub-3940256099942544/5224354917

πŸ“‹ Publisher ID:
pub-3940256099942544

πŸ“‹ Developer Website:
https://example.com

These test IDs show real-looking ads without generating revenue or violating policies. Replace with your real IDs for production.

Test IDs for Generator:

AdMob App ID:       ca-app-pub-3940256099942544~3347511713
Banner Ad ID:       ca-app-pub-3940256099942544/6300978111
Interstitial ID:    ca-app-pub-3940256099942544/1033173712
Rewarded Ad ID:     ca-app-pub-3940256099942544/5224354917
Publisher ID:       pub-3940256099942544
Developer URL:      https://example.com

7Interstitial Ads#

Interstitial ads are full-screen ads that cover the entire app interface. Users can close them to return to the app.

πŸ“Ί How to Enable (Step 3, Ad Control 'Automatic'):

  1. Turn ON 'Full Screen Ad'
  2. Ad Type: choose 'Interstitial Ad'
  3. Enter your Interstitial Ad Unit ID (or leave empty for test ads)
  4. Choose the Trigger Mode:

πŸ”„ After Navigations (default):
The ad shows after every N page navigations. For example, if set to 4, the ad appears after the 4th, 8th, 12th page load, and so on.

πŸ“± App Open:
The ad shows once immediately after the splash screen, when the app first opens.

πŸ‘† On Demand:
No automatic ads - your page shows one on a tap with WebToApk.showInterstitialAd().

⚠️ Ad Type is one choice: Interstitial OR Rewarded, not both.

Example: every 4 page navigations

Page 1 β†’ No ad
Page 2 β†’ No ad
Page 3 β†’ No ad
Page 4 β†’ πŸ“Ί Interstitial Ad shown!
Page 5 β†’ No ad
Page 6 β†’ No ad
Page 7 β†’ No ad
Page 8 β†’ πŸ“Ί Interstitial Ad shown!
...

8Rewarded Ads#

Rewarded ads are full-screen video ads that users watch in exchange for a reward. They provide higher revenue than banner or interstitial ads.

🎁 How to Enable (Step 3, Ad Control 'Automatic'):

  1. Turn ON 'Full Screen Ad'
  2. Ad Type: choose 'Rewarded Ad'
  3. Enter your Rewarded Ad Unit ID (or leave empty for test ads)
  4. Choose the Trigger Mode:

πŸ”„ After Navigations (default):
Similar to interstitial - the ad shows after every N page loads. 'Show ad after every N page navigations' sets N. Default is 4.

πŸ“± App Open:
The reward video shows once when the app first opens after splash.

πŸ‘† On Demand:
No automatic ads - your page's own 'watch ad to earn' button calls WebToApk.showRewardedAd().

πŸ’‘ How many navigations?
Lower = more ads (more revenue but worse UX). Higher = fewer ads (better UX but less revenue). Recommended: 3-5.

⚠️ Google policy: rewarded ads need the user's OK. In After Navigations and App Open modes your app first shows a 'Watch an ad?' prompt with a 'No thanks' button; the ad plays only if they accept.

Revenue comparison (approximate):

Banner Ads:       $0.10 - $0.50 per 1000 views
Interstitial Ads: $1 - $5 per 1000 views
Rewarded Ads:     $5 - $15 per 1000 views

Recommended N (page navigations per ad):
Aggressive:  2-3 (more ads, more revenue)
Balanced:    4-5 (recommended)
Conservative: 6-10 (fewer ads, better UX)

⚠️ AdMob requires a consent mechanism for users in the EEA, UK, Switzerland, and US states.

This is handled automatically by the generated app using Google's User Messaging Platform (UMP). The app will:

  • Show a consent dialog to EEA/UK/Switzerland users before displaying ads
  • Show an opt-out dialog to users in applicable US states
  • Only request ads after consent is obtained

What YOU must do:

  1. In AdMob console β†’ Privacy & messaging β†’ Create a European regulations message
  2. In AdMob console β†’ Privacy & messaging β†’ Create a US state regulations message
  3. Set your Privacy Policy URL in the generator (Step 3 or Step 4)
  4. Make sure your privacy policy mentions AdMob advertising

⚠️ Without this setup, AdMob may show a policy warning: 'Consent requirement: No CMP'

10Ad Review Process#

After publishing your app:

  • AdMob will review your app (usually takes 24-48 hours)
  • Initially, you'll see test ads
  • Once approved, real ads will start showing
  • Keep your app content policy-compliant

11Enable Payments#

To receive ad revenue:

  • Go to 'Payments' in AdMob dashboard
  • Add payment method (bank account or other options)
  • Verify your address
  • Set up tax information
  • Payments are made monthly after reaching $100 threshold

12Best Practices#

βœ… Banner Placement: Bottom banner is less intrusive and has better user experience

βœ… Interstitial/Rewarded: Choose one, not both. Rewarded ads earn more but require user engagement

βœ… Action Count: Start with 4-5 navigations between ads. Too frequent = bad reviews

βœ… Test First: Always test with test ad units during development

βœ… Monitor Performance: Check AdMob dashboard regularly for earnings and metrics

⚠️ Don't Click: Never click your own ads - this violates AdMob policy

⚠️ Quality Content: Ensure your app provides value and follows AdMob policies

πŸ’‘ Pro Tip: Combine Banner (always visible) + Interstitial or Rewarded (periodic) for maximum revenue

13Troubleshooting#

Common issues and solutions:

  • No ads showing: Check if you're using correct Ad Unit ID (not App ID)
  • Test ads work but real ads don't: Wait for AdMob review to complete
  • Ad request failed: Verify internet connection and AdMob account status
  • Account suspended: Review AdMob policies and appeal if needed

14Developer-controlled ads: place every ad yourself#

Download the complete demo page below (Coin Runner): a banner inside the layout, an interstitial between levels, a 'Watch ad to earn 50 coins' button, a 300Γ—250 rectangle, the app-open switch and a live log of every result. Zip it, upload it as an Offline ZIP, choose Developer-controlled with the prefilled test IDs, build - every button explains itself.

The options above are the Automatic mode: the app shows the banner and the full-page or rewarded ad for you. If you want every AdMob format and the freedom to put each one exactly where your page needs it, choose 'Ad Control β†’ Developer-controlled' in Step 3 instead.

In this mode NOTHING is automatic. Enter one ad unit ID for each format you use - banner, medium rectangle (300Γ—250), interstitial, rewarded, rewarded interstitial, app-open - and leave the rest empty. Your page then drives everything through window.AppMintAds:

  • AppMintAds.banner.attach('#slot', {size:'banner'|'medium_rectangle'}) - a banner placed over the element you name, in a card, between list items, anywhere. It follows the element on scroll; detach() removes it. Up to two at once.
  • await AppMintAds.load('interstitial') β†’ {ok:true} or {ok:false, code:'no_fill'|'network'|'invalid_unit'|'consent'|'ad_free'|'disabled'}
  • await AppMintAds.show('rewarded') β†’ {shown:true, earned:true, reward:{type,amount}} or {shown:false, reason}
  • AppMintAds.isReady('interstitial') - enable your button off this
  • AppMintAds.appOpen.setEnabled(false) - pause the app-open ad while the user is mid-task

AppMintAds exists only inside the installed app - always feature-detect (if (window.AppMintAds) …) so the page still works in a browser. Google's rules still apply and the app enforces them: a rewarded ad only plays from the user's own tap (your 'Watch ad' button IS the opt-in), interstitials keep a 60-second gap, and never put an ad on top of a core action.

// Feature-detect: AppMintAds exists only in the installed app
const ads = window.AppMintAds;

// 1. A banner INSIDE your layout β€” <div id="ad-slot"></div> reserves the space
if (ads) {
  const r = await ads.banner.attach('#ad-slot', { size: 'banner' });
  console.log(r.ok ? 'banner ' + r.width + 'x' + r.height : 'no banner: ' + r.code);
}

// 2. A full-page ad at a natural break (between levels), never on every tap
async function levelFinished() {
  if (ads && ads.isReady('interstitial')) await ads.show('interstitial');
  showNextLevel();          // continues whether or not an ad was shown
}

// 3. A 'Watch ad to earn 50 coins' button β€” the tap is the user's opt-in
watchBtn.onclick = async () => {
  if (!ads) return;                                 // browser: no native ads
  // From a tap the ad plays. Without one (a timer, a route change) the app shows
  // AdMob's "Watch an ad? / No thanks" intro first and answers code 'declined'.
  const r = await ads.show('rewarded');
  if (r.earned) addCoins(r.reward.amount || 50);   // grant ONLY when earned
  else if (r.reason === 'ad_free') addCoins(50);    // premium user: grant without an ad
  else toast('No ad available right now');          // no popup, no Skip button
};

// 4. Preload and keep the button honest
ads?.load('rewarded').then(r => { watchBtn.disabled = !r.ok; });

In the app, this step's button saves these to your phone. Here they are direct downloads.

admob-developer-demo.html HTML Β· 12 KB

15Ad status events: know what happened to every request#

Every developer-controlled ad reports its full life cycle on ONE event, appmint:ad, so you can log fills, react to failures and drive your own UI:

{ type, phase, slot?, code?, adCode?, message?, width?, height?, reward?, earned? }

  • type: banner | mrec | interstitial | rewarded | rewarded_interstitial | app_open
  • phase: loading β†’ loaded | failed β†’ opened β†’ impression β†’ clicked β†’ closed, plus rewarded (a reward was earned) and show_failed
  • code (on failed): no_fill | network | invalid_unit | internal - adCode is AdMob's own number, message its text
  • slot: which banner slot, for banner/mrec

The promises give you the same answer per call; the event gives you everything, including ads you did not call show() for (an app-open ad, a banner refresh). In the Automatic mode AppMintAds still exists but answers code 'automatic_mode' - use the WebToApk.showInterstitialAd()/showRewardedAd() calls and the appmint:reward / appmint:ad-closed / appmint:ad-unavailable events there.

window.addEventListener('appmint:ad', e => {
  const a = e.detail;
  console.log(a.type, a.phase, a.code || '', a.message || '');
  if (a.phase === 'failed' && a.code === 'no_fill') analytics.track('ad_no_fill', a);
  if (a.type === 'rewarded' && a.phase === 'rewarded') console.log('earned', a.reward);
  if (a.type === 'banner' && a.phase === 'loaded') console.log('banner ' + a.width + 'x' + a.height + ' in ' + a.slot);
});

// What can this build serve? (guard it β€” in a browser AppMintAds is undefined)
if (window.AppMintAds) console.log(AppMintAds.config());
// β†’ { control: 'developer', formats: { banner: true, mrec: false, interstitial: true, ... } }

This page is generated from the Integration Guide inside the app itself, so it says exactly what the current build says. Read it as Markdown.

Checked against the shipped guide on 2026-10-22.