Solution 1 :
Make sure you added the following in your AndroidManifest.xml
<meta-data
android_name="com.google.android.gms.ads.APPLICATION_ID"
android_value="ca-app-pub-Your-app-id~must-be-here-provided-by-admob" />
Problem :
I’m pretty new to the Android developling scene, I’ve been building a soundboard app from various tutorials and self-teaching. I’ve gotten the app to run fairly well, and have a banner test ad running so far.
I’d like to get an interstital ad to show on every 5 presses, however how the app is coded at the moment to show on any button press as I’m just trying to see if I can trigger the Interstital.
I cannot seem to get an Interstital ad to show, although I think it is loading.
Any advice on how to best investigate/resolve this?
(Unable to add logcat due to character limit.)
Many Thanks,
Main Activity
package com.FoxOne.BritishFartsSoundboard;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.InterstitialAd;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.RequestConfiguration;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.material.snackbar.Snackbar;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SoundboardActivity
extends AppCompatActivity implements LoaderManager.LoaderCallbacks<ArrayList<SoundObject>> {
// ADMOB
private AdView adView;
@SuppressLint("WrongViewCast")
/** Called when leaving the activity */
@Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
/** Called when returning to the activity */
@Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
// END ADMOB
/**
* Main Activity. Inflates main activity xml and child fragments.
*/
// Define a tag that is used to log any kind of error or comment
private static final String LOG_TAG = SoundboardActivity.class.getSimpleName();
// Declare a mToolbar to use instead of the system standard mToolbar
private Toolbar mToolbar;
// Declare an ArrayList that you fill with SoundObjects
private ArrayList<SoundObject> mSoundList = new ArrayList<>();
// Declare a RecyclerView and its components
// You can assign the RecyclerView.Adapter right away
private RecyclerView mRecyclerView;
private SoundboardRecyclerAdapter mRecyclerAdapter;
private RecyclerView.LayoutManager mLayoutManager;
// Declare a View that will contain the layout of the activity and serves as the parent of a Snackbar
private View mLayout;
// Declare a DatabaseHandler to support database usage
private DatabaseHandler mDatabaseHandler;
// DECLARE ADMOB INTERSTITIAL
private InterstitialAd mInterstitialAd;
private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/1033173712";
// END ADMOB
@SuppressLint("WrongViewCast")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_soundboard);
// Assign an instance to the DatabaseHandler
mDatabaseHandler = DatabaseHandler.getInstance(this);
// If the gets an update or runs for the first time fill the database with all SoundObjects
if (appUpdate()) {
mDatabaseHandler.createSoundCollection();
mDatabaseHandler.updateFavourites();
}
// Assign layout view
// Take a look at activity_soundboard.xml change the id
mLayout = findViewById(R.id.activity_soundboard);
// Assign mToolbar to the Toolbar item declared in activity_soundboard.xml
mToolbar = (Toolbar) findViewById(R.id.soundboard_toolbar);
// Set mToolbar as new action bar
setSupportActionBar(mToolbar);
// Assign mRecyclerView to the RecyclerView item declared in activity_soundboard.xml
mRecyclerView = (RecyclerView) findViewById(R.id.soundboard_RecyclerView);
// Define the RecyclerView.LayoutManager to have 3 columns
mLayoutManager = new GridLayoutManager(this, 3);
// Set the RecyclerView.LayoutManager
mRecyclerView.setLayoutManager(mLayoutManager);
// Initialize recycler adapter
mRecyclerAdapter = new SoundboardRecyclerAdapter(this, mSoundList);
// Set the RecyclerView.Adapter
mRecyclerView.setAdapter(mRecyclerAdapter);
// Calls a method that handles all permission events
requestPermissions();
// Calls a method that adds data from a database to the mSoundList
getSupportLoaderManager().initLoader(R.id.common_soundlist_loader_id, null, this);
//ADMOB BANNER
// Initialize the Mobile Ads SDK.
MobileAds.initialize(this, new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {}
});
// Set your test devices. Check your logcat output for the hashed device ID to
// get test ads on a physical device. e.g.
// "Use RequestConfiguration.Builder().setTestDeviceIds(Arrays.asList("ABCDEF012345"))
// to get test ads on this device."
MobileAds.setRequestConfiguration(
new RequestConfiguration.Builder().setTestDeviceIds(Arrays.asList("E6B987D1F47C6213E36D3F8896AA4DE8",AdRequest.DEVICE_ID_EMULATOR))
.build());
// Gets the ad view defined in layout/ad_fragment.xml with ad unit ID set in
// values/strings.xml.
adView = findViewById(R.id.adView);
//Banner Advert Size
AdSize adSize = new AdSize(320, 50);
// Create an ad request.
AdRequest adRequest = new AdRequest.Builder().build();
// Start loading the ad in the background.
adView.loadAd(adRequest);
// END ADMOB BANNER
// ADMOB INTERSTITIAL
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId(AD_UNIT_ID );
//Create Ad Request
mInterstitialAd.loadAd(new AdRequest.Builder().build());
// Begin loading your interstitial.
new RequestConfiguration.Builder().setTestDeviceIds(Arrays.asList("E6B987D1F47C6213E36D3F8896AA4DE8",AdRequest.DEVICE_ID_EMULATOR))
.build();
List <String> testDeviceIds = Arrays.asList("E6B987D1F47C6213E36D3F8896AA4DE8");
RequestConfiguration configuration =
new RequestConfiguration.Builder().setTestDeviceIds(testDeviceIds).build();
MobileAds.setRequestConfiguration(configuration);
// ADMOB INTERSTITIAL END
// ADMOB INTERSTITIAL
mInterstitialAd.setAdListener(
new AdListener() {
@Override
public void onAdLoaded() {
Toast.makeText(SoundboardActivity.this, "onAdLoaded()", Toast.LENGTH_SHORT).show();
System.out.println("onAdLoaded() CALLBACK");
}
@Override
public void onAdFailedToLoad(LoadAdError loadAdError) {
String error =
String.format(
"domain: %s, code: %d, message: %s",
loadAdError.getDomain(), loadAdError.getCode(), loadAdError.getMessage());
System.out.println("onAdFailedToLoad() CALLBACK");
Toast.makeText(SoundboardActivity.this, "onAdFailedToLoad() with error: " + error, Toast.LENGTH_SHORT)
.show();
}
@Override
public void onAdOpened() {
// Code to be executed when the ad is displayed.
Toast.makeText(SoundboardActivity.this, "onAdOpened()", Toast.LENGTH_SHORT).show();
System.out.println("onAdLoaded() CALLBACK");
}
@Override
public void onAdClosed() {
// Load the next interstitial.
System.out.println("onAdClosed() CALLBACK");
mInterstitialAd.loadAd(new AdRequest.Builder().build());}
});
// ADMOB INTERSITIAL END
};
// Create an options menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the layout
getMenuInflater().inflate(R.menu.toolbar_menu, menu);
// Define a SearchView to provide a search function and define its behaviour
MenuItem menuItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
/*
* Searches for sound objects that begin with the
* entered string and displays them on submit of the search.
*/
mRecyclerAdapter.queryData(query);
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
menuItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
getSupportLoaderManager()
.restartLoader(R.id.common_soundlist_loader_id,
null,
SoundboardActivity.this);
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_favorite_show) {
this.startActivity(new Intent(this, FavouriteActivity.class));
}
switch (item.getItemId()) {
case R.id.action_favourite:
startActivity(new Intent(this, FavouriteActivity.class));
break;
default:
}
return super.onOptionsItemSelected(item);
}
// Takes care of some things when the user closes the activity
@Override
protected void onDestroy() {
super.onDestroy();
// Calls a method that releases all data from the used MediaPlayer instance
EventHandlerClass.releaseMediaPlayer();
//Admob
if (adView != null) {
adView.destroy();
}
super.onDestroy();
// End Admob
}
/** Called before the activity is destroyed */
/**
* Handles all permission events on startup.
*/
private void requestPermissions() {
// Check if the users Android version is equal to or higher than Android 6 (Marshmallow)
// Since Android 6 you have to request permissions at runtime to provide a better security
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Check if the permission to write and read the users external storage is not granted
// You need this permission if you want to share sounds via WhatsApp or the like
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// If the permission is not granted request it
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
0);
}
// Check if the permission to write the users settings is not granted
// You need this permission to set a sound as ringtone or the like
if (!Settings.System.canWrite(this)) {
/*
* Searches for sound objects that begin with the
* entered string and displays them on submit of the search.
*/
Snackbar.make(mLayout, "The app needs access to your settings", Snackbar.LENGTH_INDEFINITE)
.setAction("OK",
new View.OnClickListener() {
private void startInterstitial() {
// Request a new ad if one isn't already loaded.
if (!mInterstitialAd.isLoading() && !mInterstitialAd.isLoaded()) {
AdRequest adRequest = new AdRequest.Builder().build();
mInterstitialAd.loadAd(adRequest);
}
}
private void showInterstitial() {
// Show the ad if it's ready. Otherwise toast and restart.
if (mInterstitialAd.isLoaded() ) {
mInterstitialAd.show();
} else {
Toast.makeText(SoundboardActivity.this, "Ad did not load", Toast.LENGTH_SHORT).show();
startInterstitial();
}
}
public int counter = 0;
@Override
// Define a tag that is used to log any kind of error or comment
public void onClick(View v) {
counter++;
Context context = v.getContext();
Toast.makeText(SoundboardActivity.this, "Current Counter:"+ String.valueOf(counter) , Toast.LENGTH_SHORT).show(); //This doesn't show
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
//startInterstitial();
if (counter == counter) { //Change back to 5 after testing
//run process for interstitial
showInterstitial();
}else{
Log.d("TAG", "The interstitial wasn't loaded yet.");
System.out.println("Interstital wasn't loaded () CALLBACK");
}
}
}).show();
}
}
}
/**
* Checks if the app has been updated by looking at the versionCode defined in the modules build.gradle.
*
* @return True if the app has been updated.
*/
private boolean appUpdate() {
/*
* We are saving the current app version into a preference file.
* There are two ways to get a handle to a SharedPreferences,
* we are creating a unique preference file that is not bound to a context.
* Check the android developer documentation if you want to find out more.
*/
// Define a name for the preference file and a key name to save the version code to it
final String prefsName = "VersionPref";
final String prefVersionCodeKey = "version_code";
// Define a value that is set if the key does not exist
final int doesntExist = -1;
// Get the current version code from the package
int currentVersionCode = 0;
try {
currentVersionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
Log.e(LOG_TAG, e.getMessage());
}
// Get the SharedPreferences from the preference file
// Creates the preference file if it does not exist
SharedPreferences prefs = getSharedPreferences(prefsName, MODE_PRIVATE);
// Get the saved version code or set it if it does not exist
int savedVersionCode = prefs.getInt(prefVersionCodeKey, doesntExist);
// Create an editor to edit the shared preferences on app update
SharedPreferences.Editor edit = prefs.edit();
//Check for updates
if (savedVersionCode == doesntExist) {
mDatabaseHandler.appUpdate();
// First run of the app
// Set the saved version code to the current version code
edit.putInt(prefVersionCodeKey, currentVersionCode);
edit.apply();
return true;
} else if (currentVersionCode > savedVersionCode) {
// App update
mDatabaseHandler.appUpdate();
edit.putInt(prefVersionCodeKey, currentVersionCode);
edit.apply();
return true;
}
return false;
}
@NonNull
@Override
public Loader<ArrayList<SoundObject>> onCreateLoader(int id, @Nullable Bundle args) {
return new SoundListLoader(getApplicationContext()) {
@Override
public ArrayList<SoundObject> loadInBackground() {
return DatabaseHandler.getInstance(SoundboardActivity.this).getSoundCollection();
}
};
}
@Override
public void onLoadFinished(@NonNull Loader<ArrayList<SoundObject>> loader, ArrayList<SoundObject> data) {
mRecyclerAdapter.swapData(data);
}
@Override
public void onLoaderReset(@NonNull Loader<ArrayList<SoundObject>> loader) {
mRecyclerAdapter.swapData(new ArrayList<SoundObject>());
}
}
Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns_android="http://schemas.android.com/apk/res/android"
xmlns_app="http://schemas.android.com/apk/res-auto"
xmlns_tools="http://schemas.android.com/tools"
android_layout_width="match_parent"
android_layout_height="match_parent"
tools_context=".SoundboardActivity"
android_background="@color/grey"
android_id="@+id/activity_soundboard">
<include
layout="@layout/toolbar"
android_id="@+id/soundboard_toolbar" />
<!-- Admob -->
<androidx.recyclerview.widget.RecyclerView
android_id="@+id/soundboard_RecyclerView"
android_layout_width="match_parent"
android_layout_height="match_parent"
android_layout_below="@id/soundboard_toolbar"
android_layout_alignParentStart="true"
android_layout_above="@+id/adView"
>
</androidx.recyclerview.widget.RecyclerView>
<com.google.android.gms.ads.AdView
android_id="@+id/adView"
android_layout_width="match_parent"
android_layout_height="60dp"
android_layout_alignParentBottom="true"
android_layout_centerHorizontal="true"
android_visibility="visible"
app_adSize="BANNER"
app_adUnitId="@string/ad_banner_id"
tools_visibility="visible"
/>
<!-- Admob -->
</RelativeLayout>
Comments
Comment posted by Andrew Chelix
When did you create the ad on admob?
Comment posted by FoxOne
A few weeks ago, but I’m using the test IDs not my actual IDs yet.
Comment posted by FoxOne
Hi Tahir, it is in there with the test Application ID.