I have an admob ad of the "open ad" type.
Which works when the application is started, and unfortunately the application is often rejected because the advertisement is seen before the content of the application ....
So I put Splash_Activity to appear a little and then the ad appears, the method is effective and the application is accepted.
Problem: When the time I set for Splash_Activity expires, the ad disappears with it without the need to press continue for the application, and in this case the ad remains in the background of the application.
Required: The Splash_Activity screen stops when the ad appears and does not disappear unless you close the ad.
AppOpenManager:
public class AppOpenManager implements LifecycleObserver, Application.ActivityLifecycleCallbacks {
private static final String LOG_TAG = "AppOpenManager";
private static final String AD_UNIT_ID = "ca-app-pub-****/****";
private AppOpenAd appOpenAd = null;
private long loadTime = 0;
private AppOpenAd.AppOpenAdLoadCallback loadCallback;
private Activity currentActivity;
private static boolean isShowingAd = false;
private final GlobalVar Splash_Activity;
/**
* Constructor
*/
public AppOpenManager(GlobalVar splash_Activity) {
this.Splash_Activity = splash_Activity;
this.Splash_Activity.registerActivityLifecycleCallbacks(this);
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
/** LifecycleObserver methods */
#OnLifecycleEvent(ON_START)
public void onStart() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
showAdIfAvailable();
}
}, 1500);
Log.d(LOG_TAG, "onStart");
}
/** Shows the ad if one isn't already showing. */
public void showAdIfAvailable() {
// Only show ad if there is not already an app open ad currently showing
// and an ad is available.
if (!isShowingAd && isAdAvailable()) {
Log.d(LOG_TAG, "Will show ad.");
FullScreenContentCallback fullScreenContentCallback =
new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
// Set the reference to null so isAdAvailable() returns false.
AppOpenManager.this.appOpenAd = null;
isShowingAd = false;
fetchAd();
}
#Override
public void onAdFailedToShowFullScreenContent(AdError adError) {}
#Override
public void onAdShowedFullScreenContent() {
isShowingAd = true;
}
};
appOpenAd.setFullScreenContentCallback(fullScreenContentCallback);
appOpenAd.show(currentActivity);
} else {
Log.d(LOG_TAG, "Can not show ad.");
fetchAd();
}
}
/**
* Request an ad
*/
public void fetchAd() {
// Have unused ad, no need to fetch another.
if (isAdAvailable()) {
return;
}
loadCallback =
new AppOpenAd.AppOpenAdLoadCallback() {
/**
* Called when an app open ad has loaded.
*
* #param ad the loaded app open ad.
*/
#Override
public void onAdLoaded(AppOpenAd ad) {
AppOpenManager.this.appOpenAd = ad;
AppOpenManager.this.loadTime = (new Date()).getTime();
}
/**
* Called when an app open ad has failed to load.
*
* #param loadAdError the error.
*/
#Override
public void onAdFailedToLoad(LoadAdError loadAdError) {
// Handle the error.
}
};
AdRequest request = getAdRequest();
AppOpenAd.load(
Splash_Activity, AD_UNIT_ID, request,
AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, loadCallback);
}
// We will implement this below.
/**
* Creates and returns ad request.
*/
private AdRequest getAdRequest() {
return new AdRequest.Builder().build();
}
/**
* Utility method that checks if ad exists and can be shown.
*/
public boolean isAdAvailable() {
return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4);
}
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
#Override
public void onActivityStarted(Activity activity) {
currentActivity = activity;
}
#Override
public void onActivityResumed(Activity activity) {
currentActivity = activity;
}
#Override
public void onActivityStopped(Activity activity) {
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
#Override
public void onActivityDestroyed(Activity activity) {
currentActivity = null;
}
/** Utility method to check if ad was loaded more than n hours ago. */
private boolean wasLoadTimeLessThanNHoursAgo(long numHours) {
long dateDifference = (new Date()).getTime() - this.loadTime;
long numMilliSecondsPerHour = 3600000;
return (dateDifference < (numMilliSecondsPerHour * numHours));
}
}
Splash_Activity
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (go) {
startActivity(new Intent(Splash_Activity.this, home_main.class));
finish();
}
}
}, 4200);
}
First, you need to create a callback listener to know when the ad has been dismissed, and stop further code execution until then.
public interface AdListener {
void onCompleted();
}
Change the code of showAdIfAvailable like below with a parameter of listener.
public void showAdIfAvailable(#NonNull AdListener listener) {
// Only show ad if there is not already an app open ad currently showing
// and an ad is available.
if (!isShowingAd && isAdAvailable()) {
Log.d(LOG_TAG, "Will show ad.");
appOpenAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
// Set the reference to null so isAdAvailable()
this.appOpenAd = null;
isShowingAd = false;
fetchAd();
// Inform caller that we have done
listener.onCompleted();
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
appOpenAd = null;
// Inform caller that we have done
listener.onCompleted();
}
#Override
public void onAdShowedFullScreenContent() {
isShowingAd = true;
}
});
appOpenAd.show(currentActivity);
} else {
Log.d(LOG_TAG, "Can not show ad.");
// Inform caller that we have done
listener.onCompleted();
// Load new ad
fetchAd();
}
}
Call to show app onen ad like below from SplashActivity:
showAdIfAvailable(SplashActivity.this, new AdListener() {
#Override
public void onCompleted() {
// Start your activity from here
}
});
However, this is a demonstration of the process. Change it as you want to use it.
Hope it will help.
Related
I'm creating a cordova plugin that should return the device's position using mapbox. The issue is that LocationEngineResult.getLastLocation() is always returning null.
I use locationEngine to retrieve the location with locationCallback.
Permissions are also checked.
***
LocationEngine locationEngine;
AltGeolocationLocationCallback callback = new AltGeolocationLocationCallback(this);
***
#SuppressLint("MissingPermission")
private void initLocationEngine() {
locationEngine = LocationEngineProvider.getBestLocationEngine(this.cordova.getActivity().getApplicationContext());
LocationEngineRequest request = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
.setMaxWaitTime(DEFAULT_MAX_WAIT_TIME).build();
locationEngine.requestLocationUpdates(request, callback, Looper.getMainLooper());
locationEngine.getLastLocation(callback);
}
private static class AltGeolocationLocationCallback extends Activity
implements LocationEngineCallback<LocationEngineResult> {
private final WeakReference<AltGeolocation> activityWeakReference;
private AltGeolocationLocationCallback contexto = this;
AltGeolocationLocationCallback(AltGeolocation activity) {
this.activityWeakReference = new WeakReference<>(activity);
}
#Override
public void onSuccess(LocationEngineResult result) {
AltGeolocation activity = activityWeakReference.get();
if (activity != null) {
Location location = result.getLastLocation();
Log.d(LOG_TAG, "result: " + location );
}
}
#Override
public void onFailure(#NonNull Exception exception) {
AltGeolocation activity = activityWeakReference.get();
}
#Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
}
}
I am trying out agora sdk sample on android using java. when I run the app on my phone and remote device the audio actually works well but the video shows black screen. How do I solve this issue.
I have tried what was stated on agora docs but non worked for me.
I have checked permissions they are working fine
My front camera is working fine
I enabled the video on my code.
My Code
public class VideoChatViewActivity extends AppCompatActivity {
private static final String TAG = VideoChatViewActivity.class.getSimpleName();
private static final int PERMISSION_REQ_ID = 22;
private static final String[] REQUESTED_PERMISSIONS = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private RtcEngine mRtcEngine;
private boolean mCallEnd;
private boolean mMuted;
private FrameLayout mLocalContainer;
private RelativeLayout mRemoteContainer;
private SurfaceView mLocalView;
private SurfaceView mRemoteView;
private ImageView mCallBtn;
private ImageView mMuteBtn;
private ImageView mSwitchCameraBtn;
// Customized logger view
private LoggerRecyclerView mLogView;
#Override
public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLogView.logI("Join channel success, uid: " + (uid & 0xFFFFFFFFL));
}
});
}
#Override
public void onFirstRemoteVideoDecoded(final int uid, int width, int height, int elapsed) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLogView.logI("First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
setupRemoteVideo(uid);
}
});
}
#Override
public void onUserOffline(final int uid, int reason) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLogView.logI("User offline, uid: " + (uid & 0xFFFFFFFFL));
onRemoteUserLeft();
}
});
}
};
private void setupRemoteVideo(int uid) {
int count = mRemoteContainer.getChildCount();
View view = null;
for (int i = 0; i < count; i++) {
View v = mRemoteContainer.getChildAt(i);
if (v.getTag() instanceof Integer && ((int) v.getTag()) == uid) {
view = v;
}
}
if (view != null) {
return;
}
mRemoteView = RtcEngine.CreateRendererView(getBaseContext());
mRemoteContainer.addView(mRemoteView);
// Initializes the video view of a remote user.
mRtcEngine.setupRemoteVideo(new VideoCanvas(mRemoteView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
mRemoteView.setTag(uid);
}
private void onRemoteUserLeft() {
removeRemoteVideo();
}
private void removeRemoteVideo() {
if (mRemoteView != null) {
mRemoteContainer.removeView(mRemoteView);
}
// Destroys remote view
mRemoteView = null;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_chat_view);
initUI();
// Ask for permissions at runtime.
// This is just an example set of permissions. Other permissions
// may be needed, and please refer to our online documents.
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[2], PERMISSION_REQ_ID)) {
initEngineAndJoinChannel();
}
}
private void initUI() {
mLocalContainer = findViewById(R.id.local_video_view_container);
mRemoteContainer = findViewById(R.id.remote_video_view_container);
mCallBtn = findViewById(R.id.btn_call);
mMuteBtn = findViewById(R.id.btn_mute);
mSwitchCameraBtn = findViewById(R.id.btn_switch_camera);
mLogView = findViewById(R.id.log_recycler_view);
// Sample logs are optional.
showSampleLogs();
}
private void showSampleLogs() {
mLogView.logI("Welcome to Agora 1v1 video call");
mLogView.logW("You will see custom logs here");
mLogView.logE("You can also use this to show errors");
}
private boolean checkSelfPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQ_ID) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED ||
grantResults[1] != PackageManager.PERMISSION_GRANTED ||
grantResults[2] != PackageManager.PERMISSION_GRANTED) {
showLongToast("Need permissions " + Manifest.permission.RECORD_AUDIO +
"/" + Manifest.permission.CAMERA + "/" + Manifest.permission.WRITE_EXTERNAL_STORAGE);
finish();
return;
}
// Here we continue only if all permissions are granted.
// The permissions can also be granted in the system settings manually.
initEngineAndJoinChannel();
}
}
private void showLongToast(final String msg) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
});
}
private void initEngineAndJoinChannel() {
// This is our usual steps for joining
// a channel and starting a call.
initializeEngine();
setupVideoConfig();
setupLocalVideo();
joinChannel();
}
private void initializeEngine() {
try {
mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRtcEventHandler);
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
}
}
private void setupVideoConfig() {
// In simple use cases, we only need to enable video capturing
// and rendering once at the initialization step.
// Note: audio recording and playing is enabled by default.
mRtcEngine.enableVideo();
// Please go to this page for detailed explanation
// https://docs.agora.io/en/Video/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#af5f4de754e2c1f493096641c5c5c1d8f
mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
VideoEncoderConfiguration.VD_640x360,
VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
VideoEncoderConfiguration.STANDARD_BITRATE,
VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT));
}
private void setupLocalVideo() {
mRtcEngine.setupLocalVideo(new VideoCanvas(mLocalView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
}
private void joinChannel() {
String token = getString(R.string.agora_access_token);
if (TextUtils.isEmpty(token) || TextUtils.equals(token, "#YOUR ACCESS TOKEN#")) {
token = null; // default, no token
}
mRtcEngine.joinChannel(token, "demoChannel1", "Extra Optional Data", 0);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (!mCallEnd) {
leaveChannel();
}
/*
Destroys the RtcEngine instance and releases all resources used by the Agora SDK.
This method is useful for apps that occasionally make voice or video calls,
to free up resources for other operations when not making calls.
*/
RtcEngine.destroy();
}
private void leaveChannel() {
mRtcEngine.leaveChannel();
}
public void onLocalAudioMuteClicked(View view) {
mMuted = !mMuted;
// Stops/Resumes sending the local audio stream.
mRtcEngine.muteLocalAudioStream(mMuted);
int res = mMuted ? R.drawable.btn_mute : R.drawable.btn_unmute;
mMuteBtn.setImageResource(res);
}
public void onSwitchCameraClicked(View view) {
// Switches between front and rear cameras.
mRtcEngine.switchCamera();
}
public void onCallClicked(View view) {
if (mCallEnd) {
startCall();
mCallEnd = false;
mCallBtn.setImageResource(R.drawable.btn_endcall);
} else {
endCall();
mCallEnd = true;
mCallBtn.setImageResource(R.drawable.btn_startcall);
}
showButtons(!mCallEnd);
}
private void startCall() {
setupLocalVideo();
joinChannel();
}
private void endCall() {
removeLocalVideo();
removeRemoteVideo();
leaveChannel();
}
private void removeLocalVideo() {
if (mLocalView != null) {
mLocalContainer.removeView(mLocalView);
}
mLocalView = null;
}
private void showButtons(boolean show) {
int visibility = show ? View.VISIBLE : View.GONE;
mMuteBtn.setVisibility(visibility);
mSwitchCameraBtn.setVisibility(visibility);
}
}
I dont really know what is the issue. Anyone have idea on how I can solve this issue?
I found the solution for this
you have to add delay of 10 seconds before running below code
mRtcEngine!!.setClientRole(Constants.CLIENT_ROLE_BROADCASTER)
mRtcEngine!!.joinChannel(
stringToken,
channelName,
"Extra Optional Data",
currentUid
)
so the surface view of current user is loaded properly first and then it tries to join the call.
Simply put, dont join channel before surface view and camera is ready.
I want setOnUtteranceProgressListener should notify a Toast after the speech is completed.It seems not working.
I have used setOnUtteranceProgressListener and on the speak function i have mentioned the paramaters as follows..
Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, MainActivity.this.getPackageName());
I have given a "UniqueId" while calling speak function as follows.
myTTS.speak(message,TextToSpeech.QUEUE_FLUSH,params,"UniqueId");
In My program after the text to speech engine finishes speaking it should run a Toast notifying that it has finished speaking.But the setOnUtteranceProgressListner seems not working.
myTTS.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
}
#Override
public void onDone(String utteranceId) {
Toast.makeText(MainActivity.this,"Finished speaking.",Toast.LENGTH_LONG).show();
}
#Override
public void onError(String utteranceId) {
}
});
The all Code is as follows..
public class MainActivity extends AppCompatActivity {
String message;
private TextToSpeech myTTS;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(myTTS.getEngines().size() == 0){
Toast.makeText(MainActivity.this,"No Engines Installed",Toast.LENGTH_LONG).show();
}else{
myTTS.setLanguage(Locale.US);
if (status == TextToSpeech.SUCCESS){
//Toast.makeText(MainActivity.this,"Status working.",Toast.LENGTH_LONG).show();
message = "How may i help you.";
}
}
}
});
myTTS.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
}
#Override
public void onDone(String utteranceId) {
Toast.makeText(MainActivity.this,"onDone working.",Toast.LENGTH_LONG).show();
}
#Override
public void onError(String utteranceId) {
}
});
}
Please give a solution for this.
The main problems are:
1) Setting the progress listener before the tts is initialized.
2) Trying to make a Toast from a background thread.
I also have some other suggested changes but they are not required:
public class MainActivity extends AppCompatActivity {
String message = "How may I help you?";
String mostRecentUtteranceID;
private TextToSpeech myTTS;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(myTTS.getEngines().size() == 0){
Toast.makeText(MainActivity.this,"No Engines Installed",Toast.LENGTH_LONG).show();
}else{
if (status == TextToSpeech.SUCCESS){
ttsInitialized();
}
}
}
});
}
private void ttsInitialized() {
// *** set UtteranceProgressListener AFTER tts is initialized ***
myTTS.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
}
#Override
// this method will always called from a background thread.
public void onDone(String utteranceId) {
// only respond to the most recent utterance
if (!utteranceId.equals(mostRecentUtteranceID)) {
Log.i("XXX", "onDone() blocked: utterance ID mismatch.");
return;
} // else continue...
boolean wasCalledFromBackgroundThread = (Thread.currentThread().getId() != 1);
Log.i("XXX", "was onDone() called on a background thread? : " + wasCalledFromBackgroundThread);
Log.i("XXX", "onDone working.");
// for demonstration only... avoid references to
// MainActivity (unless you use a WeakReference)
// inside the onDone() method, as it
// can cause a memory leak.
runOnUiThread(new Runnable() {
#Override
public void run() {
// *** toast will not work if called from a background thread ***
Toast.makeText(MainActivity.this,"onDone working.",Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onError(String utteranceId) {
}
});
// set Language
myTTS.setLanguage(Locale.US);
// set unique utterance ID for each utterance
mostRecentUtteranceID = (new Random().nextInt() % 9999999) + ""; // "" is String force
// set params
// *** this method will work for more devices: API 19+ ***
HashMap<String, String> params = new HashMap<>();
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, mostRecentUtteranceID);
myTTS.speak(message,TextToSpeech.QUEUE_FLUSH,params);
}
}
If you want to add the call back OnUtteranceProgressListener you have to implement the speak method like this:
myTTS.speak(message,TextToSpeech.QUEUE_FLUSH, null , TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID);
Then it will call the methods that you've already implemented (onStart, onDone, etc)
I programmed an app named "Trumple Run" for android. Like the name says it is a Jump & Run game and I want to release it soon. Before that I would like to implement Interstitial Ads from AdMob. I followed the official guide for the implementation of Ads but the app always crashes when I tried to show the add. Here is some code from my MainActivity (info: I cut out code which is not relevant for the issue; the method addzeigen() is called from another class)
public class Main_activity extends Activity {
private InterstitialAd mInterstitial;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //Fullscreen
DisplayMetrics metrics = getResources().getDisplayMetrics(); //Display größe herausfinden
V.Bildbreite = metrics.widthPixels;
V.Bildhöhe = metrics.heightPixels;
addladen();
V.v = new View(this);
setContentView(V.v);
}
public void addladen(){
mInterstitial = new InterstitialAd(this);
mInterstitial.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
AdRequest request = new AdRequest.Builder().build();
mInterstitial.loadAd(request);
}
public void addzeigen(){
if(mInterstitial.isLoaded()){
mInterstitial.show();
addladen();
}
}
I looked at the StackTrace to find the reason for the issue and this two lines indicated that the interstitial is not yet instantiated (returning a null value).
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.google.android.gms.ads.InterstitialAd.isLoaded()' on a null object reference
Because of that I added a null checker in my addladen() method to prevent a crash.
public void addzeigen(){
if(mInterstitial != null && mInterstitial.isLoaded()){
mInterstitial.show();
addladen();
}
}
But why is my Interstitial object null? Did I not instantiate it in the right way in my addladen() method? I already searched for a long time in the internet but found no solution and asked the AdMob support but they said I should ask here because it is an implementation problem. How do I have to modify my code to make sure that my Interstitial is not null? I would be really happy if you could help me.
create application to when open app, add immidiate load
public class MyApplication extends Application {
public InterstitialAd mInterstitialAd;
private AppOpenManager appOpenAdManager;
private Activity currentActivity;
private int check = 0;
public AdLoader adLoader;
#Override
public void onCreate() {
super.onCreate();
MobileAds.initialize(
this,
new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(
#NonNull InitializationStatus initializationStatus) {
}
});
appOpenAdManager = new AppOpenManager();
loadInterstitial(AD_UNIT_ID_INTERSTITIAL_ADS);
}
public void loadInterstitial(String id) {
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(
this,
id,
adRequest,
new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
mInterstitialAd = interstitialAd;
interstitialAd.setFullScreenContentCallback(
new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
mInterstitialAd = null;
}
#Override
public void onAdFailedToShowFullScreenContent(AdError adError) {
// Called when fullscreen content failed to show.
// Make sure to set your reference to null so you don't
// show it a second time.
mInterstitialAd = null;
}
#Override
public void onAdShowedFullScreenContent() {
}
});
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
mInterstitialAd = null;
}
});
}
}
then you create class check exception happen when load and open app
public class LoadInterstitialAds {
private static LoadInterstitialAds instance;
private InterstitialAd mInterstitialAd;
public static LoadInterstitialAds getInstance() {
if (instance == null) {
return new LoadInterstitialAds();
}
return instance;
}
public void openAdsThenOpenActivity(Activity activity, InterstitialAdsListener listener) {
Application application = activity.getApplication();
if (application instanceof MyApplication) {
LoadInterstitialAds.this.mInterstitialAd = ((MyApplication) application).mInterstitialAd;
if (LoadInterstitialAds.this.mInterstitialAd != null) {
LoadInterstitialAds.this.mInterstitialAd.show(activity);
LoadInterstitialAds.this.mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
listener.onStartActivity();
((MyApplication) application).loadInterstitial(AD_UNIT_ID_INTERSTITIAL_ADS);
}
#Override
public void onAdFailedToShowFullScreenContent(#NonNull AdError adError) {
((MyApplication) application).loadInterstitial(AD_UNIT_ID_INTERSTITIAL_ADS);
listener.onStartActivity();
}
});
} else {
((MyApplication) application).loadInterstitial(AD_UNIT_ID_INTERSTITIAL_ADS);
listener.onStartActivity();
}
}
}
}
create interface listener tothe convenience of calling
public interface InterstitialAdsListener {
void onStartActivity();
}
and finally, run this code at any where you want to show
LoadInterstitialAds loadInterstitialAds = LoadInterstitialAds.getInstance();
loadInterstitialAds.openAdsThenOpenActivity(getActivity(), ()->{
// your process
});
For demonstration purposes, the app has one activity that simply offers this:
You click a button, view a rewarded video, and you are rewarded with whatever.
The Problem
How can I load the videos? From what I have seen you can only call mAd.loadAd() once. There are 3 videos, each with their own AD UNIT ID. Each ad unit can have its own listener, but only one video loads so it doesn't matter...
When trying to load multiple videos
For example:
mAd1.loadAd("AD_UNIT_1", new AdRequest.Builder().build());
mAd2.loadAd("AD_UNIT_2", new AdRequest.Builder().build());
mAd3.loadAd("AD_UNIT_3", new AdRequest.Builder().build());
results in only the last video being loaded and this in log:
W/Ads: Loading already in progress, saving this object for future refreshes.
onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAd1 = MobileAds.getRewardedVideoAdInstance(this);
mAd2 = MobileAds.getRewardedVideoAdInstance(this);
mAd3 = MobileAds.getRewardedVideoAdInstance(this);
listeners...
mAd1.loadAd() etc
}
Thank you for your help
Edit: It's clear I am thinking about this problem wrong. I have 5+ ad zones that each will play a rewarded video and give a different reward (for example, one gives coins, one gives a level up, and so on..). There is no reason to load 5 videos. I should load one in onCreate(), so it's ready when needed, then load it again after the item is rewarded so it's ready for next time.
So the question remains, if there is just the one video, and thus one ad zone, being loaded onCreate() then how can I track what reward to give?
Here's a simple solution...
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAd = MobileAds.getRewardedVideoAdInstance(this);
mAd.setRewardedVideoAdListener(new RewardedVideoAdListener() {
#Override
public void onRewarded(RewardItem rewardItem) {
switch(Constants.currentAd) {
case("REWARD1"):
//do something
Constants.currentAd = "";
break;
case("REWARD2"):
//do something
Constants.currentAd = "";
break;
case("REWARD3"):
//do something
Constants.currentAd = "";
break;
}
}
});
mAd.loadAd("REWARDED_VIDEO_UNIT_ID", new AdRequest.Builder().build());
}
public void showRewardedVideo() {
if (mAd.isLoaded()) {
mAd.show();
}
}
Constants.java
public class Constants {
public static String currentAd = "";
}
Showing the ad after button click
rewardButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Constants.currentAd = "REWARD1";
dismiss();
((MainActivity) getActivity()).showRewardedVideo();
}
});
REWARDED_VIDEO_UNIT_ID is one ad unit for rewarded video in AdMob...remove the rest. No need for other units, you can track whatever you like in the listener.
Other simple soluction...
AbstractRewardVideo.java
public abstract class AbstractRewardVideo {
private RewardedVideoAd mAd;
private String adId = "ca-app-pub...";
private Activity activity;
abstract protected RewardedVideoAdListener getListener();
public void init(Activity activity) {
this.activity = activity;
mAd = MobileAds.getRewardedVideoAdInstance(activity);
setAdId(adId);
loadRewardedVideoAd();
}
public Activity getActivity(){
return this.activity;
}
public void loadRewardedVideoAd() {
mAd.loadAd(adId, new AdRequest.Builder().build());
}
public void showVideo(){
setListener(getListener());
if (mAd.isLoaded()) {
mAd.show();
} else {
Utils.exibirToast("Don't loaded!");
}
}
public void setAdId(#NonNull String id){
this.adId = id;
}
public void setListener(RewardedVideoAdListener listener){
mAd.setRewardedVideoAdListener(listener);
}
}
Reward1.java
public class Reward1 extends AbstractRewardVideo {
public Reward1(Activity activity) {
init(activity);
}
#Override
protected RewardedVideoAdListener getListener() {
return new Listener();
}
private class Listener implements RewardedVideoAdListener {
#Override
public void onRewarded(RewardItem rewardItem) {
//Do something...
}
public void onRewardedVideoAdLoaded() {}
public void onRewardedVideoAdOpened() {}
public void onRewardedVideoStarted() {}
public void onRewardedVideoAdClosed() { loadRewardedVideoAd(); }
public void onRewardedVideoAdLeftApplication() {}
public void onRewardedVideoAdFailedToLoad(int i) {}
}
}
Reward2.java
public class Reward2 extends AbstractRewardVideo {
public Reward2(Activity activity) {
init(activity);
}
#Override
protected RewardedVideoAdListener getListener() {
return new Listener();
}
private class Listener implements RewardedVideoAdListener {
#Override
public void onRewarded(RewardItem rewardItem) {
//Do something...
}
public void onRewardedVideoAdLoaded() {}
public void onRewardedVideoAdOpened() {}
public void onRewardedVideoStarted() {}
public void onRewardedVideoAdClosed() { loadRewardedVideoAd(); }
public void onRewardedVideoAdLeftApplication() {}
public void onRewardedVideoAdFailedToLoad(int i) {}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity{
Reward1 reward1;
Reward2 reward2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
reward1 = new Reward1(this);
reward2 = new Reward1(this);
...
reward1.showVideo();
...
reward2.showVideo();
}
}
MobileAds.initialize ( this, "ca-app-pub-4761500786576152~8215465788" );
RewardedVideoAd mAd = MobileAds.getRewardedVideoAdInstance(this);
mAd.setRewardedVideoAdListener(Video_Ad.this);
}
#Override
public void onRewardedVideoAdLoaded() {
}
#Override
public void onRewardedVideoAdOpened() {
}
#Override
public void onRewardedVideoStarted() {
}
#Override
public void onRewardedVideoAdClosed() {
}
#Override
public void onRewarded(RewardItem rewardItem) {
}
#Override
public void onRewardedVideoAdLeftApplication() {
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
}
#Override
public void onRewardedVideoCompleted() {
}