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 Web2APK Generator#

In the generator app:

  1. Enable 'Ads' toggle in Step 3
  2. Select ad placement (Top or Bottom)
  3. Paste your AdMob Banner Ad Unit ID
  4. Continue with other settings and generate your APK
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:

  1. Toggle ON 'Enable Interstitial Ad' in Step 3
  2. Enter your Interstitial Ad Unit ID (or leave empty for test ads)
  3. Choose a 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.

โš ๏ธ You can enable either Interstitial OR Rewarded - not both at the same time.

Example: Action Count = 4

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:

  1. Toggle ON 'Enable Rewarded Ad' in Step 3
  2. Enter your Rewarded Ad Unit ID (or leave empty for test ads)
  3. Choose a trigger mode:

๐Ÿ”„ After Navigations (default):
Similar to interstitial - the ad shows after every N page loads. Set the 'Action Count' to control frequency. Default is 4.

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

๐Ÿ’ก What is Action Count?
The number of page navigations between each ad. 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. For a 'watch ad to earn' button with no automatic ads, use On Demand.

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 Action Count:
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-09-20.