I'm trying to integrate the interstitial ad from Huawei Ads, when I click on (X) or back button to close the ad, for some reason the Toast inside onAdClosed method is not showing.
huaweiInterstitialAd = new InterstitialAd(MainActivity.this);
huaweiInterstitialAd.setAdId("teste9ih9j0rc3");
private void showHuaweiInterstitial() {
if (huaweiInterstitialAd != null && huaweiInterstitialAd.isLoaded()) {
huaweiInterstitialAd.show(MainActivity.this);
}
}
public void loadHuaweiInterstitialAd() {
huaweiInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
showHuaweiInterstitial();
}
#Override
public void onAdFailed(int errorCode) {
Log.d(TAG, "Ad load failed with error code: " + errorCode);
}
#Override
public void onAdLeave() {
super.onAdLeave();
Log.d(TAG, "onAdLeave");
}
#Override
public void onAdClosed() {
super.onAdClosed();
Toast.makeText(MainActivity.this, "Ad Closed", Toast.LENGTH_SHORT).show();
}
#Override
public void onAdClicked() {
Log.d(TAG, "onAdClicked");
super.onAdClicked();
}
#Override
public void onAdOpened() {
Log.d(TAG, "onAdOpened");
super.onAdOpened();
}
});
AdParam adParam = new AdParam.Builder().build();
huaweiInterstitialAd.loadAd(adParam);
}
The problem only occurs if you use:
implementation 'com.huawei.hms:ads:3.4.46.300'
But everything works fine with :
implementation 'com.huawei.hms:ads-lite:13.4.46.300'
Related
I tried looking at previous questions and answers but with no luck finding a real solution. I'm acknowledging purchases once they are processed although my users are still automatically refunded. Below is my whole purchase activity. It's a simple activity with a big button to purchase the app's full version. Anoter button to restore previous purchases. A third button to show some advice if users were not able to restore their purchase.
Any help would be appreciated!
public class BuyActivity extends AppCompatActivity {
Button unlock_button;
Button restore_purchase;
static final String PRODUCT_ID = "full_version";
private BillingClient billingClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buy);
unlock_button = findViewById(R.id.unlock_button);
restore_purchase = findViewById(R.id.restore_purchase);
billingClient = BillingClient.newBuilder(getApplicationContext())
.setListener((billingResult, list) -> {
// responds to all purchases that were already made
if (billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK && list!= null) {
for (Purchase purchase:list){
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
acknowledge_purchase(purchase);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
features_unlocked();
}
},500);
} else {
Toast.makeText(getApplicationContext(), "ERROR OCCURRED", Toast.LENGTH_SHORT).show();
}
}
} else if (billingResult.getResponseCode()==BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED && list!=null) {
features_unlocked();
} else {
Toast.makeText(getApplicationContext(), "ERROR OCCURRED", Toast.LENGTH_SHORT).show();
}
})
.enablePendingPurchases()
.build();
connect_to_google();
restore_purchase.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
restore_purchase();
}
});
unlock_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//launch_purchase_flow(productDetailsList.get(0));
Toast.makeText(getApplicationContext(), "CAN'T START THE PURCHASE PROCESS", Toast.LENGTH_SHORT).show();
}
});
}
void features_unlocked(){
App.get().MyTheme = 1;
Intent i = new Intent(BuyActivity.this, Unlocked_celebration.class);
startActivity(i);
finish();
}
void connect_to_google(){
billingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
get_product_details(); // download all details to different variables as you want
Log.i( "appName", String.format( "billing setup response code %s", billingResult.toString() ) );
}
}
#Override
public void onBillingServiceDisconnected() {
connect_to_google();
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
}
});
}
//show products available to buy
void get_product_details(){
List<String> productIds = new ArrayList<>();
productIds.add("full_version");
SkuDetailsParams params = SkuDetailsParams
.newBuilder()
.setSkusList(productIds)
.setType(BillingClient.SkuType.INAPP)
.build();
billingClient.querySkuDetailsAsync(
params,
new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(#NonNull BillingResult billingResult, #Nullable List<SkuDetails> list) {
if (billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK && list!=null){
if (list.size()>0) {
Log.println(Log.DEBUG,"TAG", "onSkuDetailsResponse: " + list.get(0).getPrice());
unlock_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
billingClient.launchBillingFlow(
BuyActivity.this,
BillingFlowParams.newBuilder().setSkuDetails(list.get(0)).build()
);
}
});
}
}
}
}
);
}
void acknowledge_purchase(Purchase purchase){
AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams
.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
#Override
public void onAcknowledgePurchaseResponse(#NonNull BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
}
}
});
}
void restore_purchase(){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
connect_to_google();
new Handler().post(new Runnable() {
#Override
public void run() {
billingClient.queryPurchasesAsync(
BillingClient.SkuType.INAPP,
new PurchasesResponseListener() {
#Override
public void onQueryPurchasesResponse(#NonNull BillingResult billingResult, #NonNull List<Purchase> list) {
if (billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK) {
for (Purchase purchase: list){
if (purchase.getPurchaseState()==Purchase.PurchaseState.PURCHASED
&& !purchase.isAcknowledged()) {
acknowledge_purchase(purchase);
features_unlocked();
} else if (purchase.getPurchaseState()==Purchase.PurchaseState.PURCHASED) {
features_unlocked();
}
}
} else if (billingResult.getResponseCode()==BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
features_unlocked();
}
}
}
);
}
});
}
},300);
}
protected void onResume() {
super.onResume();
restore_purchase();
}
#Override
protected void onStop() {
super.onStop();
if (billingClient != null) billingClient.endConnection();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
public void onDestroy() {
if (billingClient != null) billingClient.endConnection();
billingClient=null;
super.onDestroy();
}
#Override
protected void onPause() {
super.onPause();
if (billingClient != null) billingClient.endConnection();
}
public void cantRestore(View v){
Intent i = new Intent(BuyActivity.this, RestorePurchase.class);
startActivity(i);
}
}
i have a recycler view and i want to control of downloading using buttons in my card view.
i use PRDownloader library but i have issue i can't resume download after finish the app and open it again it start the download not resume it.
my code as below
holder.downloadResumeOrPlayBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downLoadID = PRDownloader.download(remoteLink, myLocalDirectory,
fileName)
.build()
.setOnStartOrResumeListener(new OnStartOrResumeListener() {
#Override
public void onStartOrResume() {
holder.pauseDownloadBtn.setVisibility(View.VISIBLE);
holder.cancelBtn.setVisibility(View.VISIBLE);
holder.downloadResumeOrPlayBtn.setVisibility(View.GONE);
notifyDataSetChanged();
}
})
.setOnPauseListener(new OnPauseListener() {
#Override
public void onPause() {
holder.pauseDownloadBtn.setText(mContext.getResources().getString(string.resume_text_btn));
holder.downloadResumeOrPlayBtn.setVisibility(View.GONE);
holder.pauseDownloadBtn.setVisibility(View.VISIBLE);
holder.cancelBtn.setVisibility(View.GONE);
notifyDataSetChanged();
}
})
.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel() {
holder.mProgressBar.setProgress(0);
holder.downloadResumeOrPlayBtn.setText(mContext.getResources().getString(R.string.download_text));
holder.downloadResumeOrPlayBtn.setVisibility(View.VISIBLE);
holder.pauseDownloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
notifyDataSetChanged();
}
})
.setOnProgressListener(new OnProgressListener() {
#Override
public void onProgress(Progress progress) {
video.setVideoProgress(progress.currentBytes * 100 / progress.totalBytes);
Log.i("videosAdapter", video.getVideoProgress() + "");
holder.mProgressBar.setProgress((int) video.getVideoProgress());
holder.mProgressBar.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
})
.start(new OnDownloadListener() {
#Override
public void onDownloadComplete() {
System.out.println("download completed");
holder.downloadResumeOrPlayBtn.setText(mContext.getResources().getString(string.play_video_text));
holder.downloadResumeOrPlayBtn.setVisibility(View.VISIBLE);
holder.pauseDownloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
notifyDataSetChanged();
}
#Override
public void onError(Error error) {
holder.downloadResumeOrPlayBtn.setText(mContext.getResources().getString(string.download_text));
Toast.makeText(mContext, error.getServerErrorMessage(), Toast.LENGTH_SHORT).show();
holder.mProgressBar.setProgress(0);
}
});
}
if(holder.downloadResumeOrPlayBtn.getText().toString().equals(mContext.getResources().getString(string.resume_text_btn)))
{
PRDownloader.resume(downLoadID);
}
});
my question is how to resume the download without downloading the file from the start and if there is another library to use how can i make it.
I am getting this error when using InterstitialAdListener
Anonymous class derived from InterstitialAdListener' must either be declared > abstract or implement abstract method 'onInterstitialDismissed(Ad) in
'InterstitialAdListener'
The InterstitialAdListener is red color underlined.
I tried reduced it to com.facebook.ads.AdListener but doesn't work with me Also, I upgrade SDK to see if it would solve it but didn't have luck.
How I can solve this problem ?
private void initInterstitialAdPrepare() {
interstitialAd = new InterstitialAd(this, "xxxxxxxx_xxxxxxxxx");
interstitialAd.setAdListener(new InterstitialAdListener() {
#Override
public void onInterstitialDisplayed(Ad ad) {
// Interstitial ad displayed callback
Log.e(TAG, "Interstitial ad displayed.");
}
#Override
public void onError(Ad ad, AdError adError) {
// Ad error callback
Log.e(TAG, "Interstitial ad failed to load: " + adError.getErrorMessage());
}
#Override
public void onAdLoaded(Ad ad) {
// Interstitial ad is loaded and ready to be displayed
Log.d(TAG, "Interstitial ad is loaded and ready to be displayed!");
}
// Show the ad
interstitialAd.show();
}
Call this in onCreate
private void requestInterstitialAd(){
interstitialAd = new InterstitialAd(this, getResources().getString(R.string.interstitial_ad_id)); //YOUR_PLACEMENT_ID
interstitialAd.loadAd();
}
Use this code where you want to load ad and for splash use it once your splash timer is completed
if(interstitialAd.isAdLoaded()) {
interstitialAd.show();
interstitialAd.setAdListener(new InterstitialAdListener() {
#Override
public void onError(Ad ad, AdError adError) {
}
#Override
public void onInterstitialDismissed(Ad ad) {
requestInterstitialAd();
//Perform your functionality here
}
#Override
public void onInterstitialDisplayed(Ad ad) {
}
#Override
public void onAdLoaded(Ad ad) {
}
#Override
public void onAdClicked(Ad ad) {
}
#Override
public void onLoggingImpression(Ad ad) {
}
});
}
else {
requestInterstitialAd();
//Perform your functionality here in case ad is not loaded before
}
I want to use Rewarded video ads (Admob) but I want to show a progress bar while the video ads is loading
I already try to did it with async task just to see if the video will load but it didn't work
#SuppressLint("StaticFieldLeak")
public class videoAd extends AsyncTask<Void, Void, Void> {
#Override
protected void doInBackground(Void... voids) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mRewardedVideoAd.loadAd("ca-app-pub-3940256099942544/5224354917", new AdRequest.Builder().build());
}
});
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if (mRewardedVideoAd.isLoaded()){
Toast.makeText(SetFullWallpaper.this, "Video loaded", Toast.LENGTH_SHORT).show();
mRewardedVideoAd.show();
}
}
}
Now I want to load a progress bar if the video is not loaded yet
Thank you
This is how I did it:
I had a button, which when clicked showed the ad, so I had a boolean variable which tracked whether the button has been clicked:
boolean buttonClicked = false
These lines were in my onCreate function:
mRewardedVideoAd = MobileAds.getRewardedVideoAdInstance(getContext());
rewardedVideoAdListener = new RewardedVideoAdListener() {
#Override
public void onRewardedVideoAdLoaded() {
if(buttonClicked) {
showAd();
}
}
#Override
public void onRewardedVideoAdOpened() {
}
#Override
public void onRewardedVideoStarted() {
}
#Override
public void onRewardedVideoAdClosed() {
loadRewardedVideoAd();
}
#Override
public void onRewarded(RewardItem rewardItem) {
}
#Override
public void onRewardedVideoAdLeftApplication() {
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
if(buttonClicked) {
progressBar.setVisibility(View.INVISIBLE);
Toast toast = Toast.makeText(getContext(), "Please try again later", Toast.LENGTH_SHORT);
toast.show();
}
}
#Override
public void onRewardedVideoCompleted() {
}
};
mRewardedVideoAd.setRewardedVideoAdListener(rewardedVideoAdListener);
loadRewardedVideoAd();
pointsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showAd();
}
});
This was my showAd function:
public void showAd(){
if (mRewardedVideoAd.isLoaded()) {
progressBar.setVisibility(View.GONE);
mRewardedVideoAd.show();
buttonClicked = false;
} else {
loadRewardedVideoAd();
progressBar.setVisibility(View.VISIBLE);
buttonClicked = true;
}
}
How this works is, the app tries to load the ad in the background by calling the loadRewaredVideoAd() function when the activity/fragment is created. Then when the user clicks the button,showAd() function is called and one of two things happen:
1) If the ad was successfully loaded, it shows the ad.
2) If not, it calls loadRewardedVideoAd() again and shows a progressbar this time. It also sets buttonClicked to true. Then if the ad loads, the onRewardedVideoAdLoaded() function is called which calls showAd() again and this time the 1st option happens.
If the ad didn't load this time as well, then onRewardedVideoAdFailedToLoad(int i)is called and it shows a toast saying the user to try again later.
add OnProgressUpdate() in your class that extends AsyncTask and add progress dialog in this.
I am placing an admob video, which is executed when you enter the activity. In my case, I put an executable loop to start the video when it is already loaded.
if (mRewardedVideoAd.isLoaded()) {
mRewardedVideoAd.show();
}else{
loadRewardedVideoAd();
}
This is part of all my code
private boolean started = false;
private Handler handler = new Handler();
private void initializeAdMob() {
mRewardedVideoAd = MobileAds.getRewardedVideoAdInstance(this);
mRewardedVideoAd.setRewardedVideoAdListener(this);
loadRewardedVideoAd();
}
private void loadRewardedVideoAd() {
if (!mRewardedVideoAd.isLoaded()) {
mRewardedVideoAd.loadAd(getString(R.string.id_block_activity), new AdRequest.Builder().build());
}
}
private void showRewardedVideoAd() {
if (BaseInteractor.isNetworkAvailable(this)) {
showProgressBar(true);
start();
}
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
if (mRewardedVideoAd.isLoaded()) {
mRewardedVideoAd.show();
}else{
loadRewardedVideoAd();
}
if (started) {
start();
}
}
};
public void stop() {
started = false;
handler.removeCallbacks(runnable);
}
public void start() {
started = true;
handler.postDelayed(runnable, 2000);
}
finally I stop the runnable in
#Override
public void onRewardedVideoAdOpened() {
showProgressBar(false);
stop();
}
I hope this helps you.
I am trying to use the AdMob Rewarded Ad in my Android application.
In order to include it in the refered app, I need to wait for the rewarded video to load after the user click the buttom.
I am trying it throughout the code bellow, but I get the error:
java.lang.IllegalStateException: showAd must be called on the main UI
thread.
When the buttom is clicked:
b_r_ans.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isSomBotaoLigado() && loaded[0])
soundPool.play(soundID, MyApplication.getVolumeBotao(), MyApplication.getVolumeBotao(), 1, 0, 1f);
Toast.makeText(MyApplication.getAppContext(),carregando_rv, Toast.LENGTH_LONG).show();
Thread t_rv = new Thread(new Runnable() {
public void run() {
while(!rv_loaded){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t_rv.start();
try {
t_rv.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
mRewardedVideoAd.show();
}
});
Overrided the listener:
#Override
public void onRewardedVideoAdLoaded() {
Toast.makeText(this, "onRewardedVideoAdLoaded", Toast.LENGTH_SHORT).show();
rv_loaded = true;
}
Using the mRewardedVideoAd.isLoaded() function triggers the same issue.
How can I wait for the video to load properly?
It appears to happen that you are calling show from a different thread to the UI so I'd try to force its execution on the main thread like:
// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
#Override
public void run() {
if (mRewardedVideoAd.isLoaded()) {
mRewardedVideoAd.show();
}
};
mainHandler.post(myRunnable);
You can also disable the button until the ad is loaded, then in the onRewardedVideoAdLoaded function enable the button:
override fun onRewardedVideoAdLoaded() {
ad_btn.isEnabled = true
}
Hope it helps. This is the implementation that I am using.
Solved it through this code:
#Override
public void onRewardedVideoAdLoaded() {
//Toast.makeText(this, "onRewardedVideoAdLoaded", Toast.LENGTH_SHORT).show();
rv_loaded = true;
if(goToAnswers)
mRewardedVideoAd.show();
goToAnswers = false;
}
b_r_ans.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isSomBotaoLigado() && loaded[0])
soundPool.play(soundID, MyApplication.getVolumeBotao(), MyApplication.getVolumeBotao(), 1, 0, 1f);
Toast.makeText(MyApplication.getAppContext(),carregando_rv, Toast.LENGTH_LONG).show();
if(mRewardedVideoAd.isLoaded())
mRewardedVideoAd.show();
else goToAnswers=true;
}
});
This code will show a ProgressDialog while loading the reward video:
package com.mountzoft.waitForrewardvideoProperly;
import android.app.ProgressDialog;
import android.content.Context;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.reward.RewardItem;
import com.google.android.gms.ads.reward.RewardedVideoAd;
import com.google.android.gms.ads.reward.RewardedVideoAdListener;
public class MainActivity extends AppCompatActivity implements RewardedVideoAdListener {
private RewardedVideoAd mAd;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Please wait... Loading Reward Video Ad!");
mProgressDialog.setCancelable(false);
}
private final showRewardVideoAd() {
mProgressDialog.show();
initializeRewardVideoAd();
loadRewardedVideoAd();
}
private void initializeRewardVideoAd(){
String adMobAppId = BuildConfig.AD_MOB_APP_ID; //id is stored in build gradle file
MobileAds.initialize(this, adMobAppId);
mAd = MobileAds.getRewardedVideoAdInstance(this);
mAd.setRewardedVideoAdListener(this);
}
private void loadRewardedVideoAd() {
String admobAdUnitId = BuildConfig.ADMOB_AD_UNIT_ID;//id is stored in build gradle
mAd.loadAd(admobAdUnitId,
new AdRequest.Builder().build());
}
#Override
public void onRewardedVideoAdLoaded() {
mAd.show();
}
#Override
public void onRewardedVideoAdOpened() {
mAd = null;
}
#Override
public void onRewardedVideoStarted() {
mProgressDialog.dismiss();
}
#Override
public void onRewardedVideoAdClosed() {
}
#Override
public void onRewarded(RewardItem rewardItem) {
}
#Override
public void onRewardedVideoAdLeftApplication() {
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
}
#Override
public void onRewardedVideoCompleted(){
}
}
If you need to wait until rewarded ad loading use SingleLiveEvent. Please refer following code snippet.
private val isRewardedAdLoaded: LiveData<Event<Boolean>>
get() = _isRewardedAdLoaded
private var _isRewardedAdLoaded: MutableLiveData<Event<Boolean>> = MutableLiveData()
I used this is in fragment. So this from onViewCreated()
rewardedAd = createAndLoadRewardedAd()
and I post loading state as following
private fun createAndLoadRewardedAd(): RewardedAd {
val rewarded = RewardedAd(requireContext(), getString(R.string.admob_rewarded_id_test))
val adLoadCallback = object : RewardedAdLoadCallback() {
override fun onRewardedAdLoaded() {
Log.e(TAG, "onRewardedAdLoaded")
_isRewardedAdLoaded.postValue(Event(true))
}
override fun onRewardedAdFailedToLoad(errorCode: Int) {
_isRewardedAdLoaded.postValue(Event(false))
}
}
rewarded.loadAd(Builder().build(), adLoadCallback)
return rewarded
}
this is rewarded ad show method
private fun showRewardedAds(rewarded: RewardedAd) {
rewarded.show(requireActivity(), object : RewardedAdCallback() {
override fun onRewardedAdOpened() {
Log.e(TAG, "onRewardedAdOpened")
}
override fun onRewardedAdClosed() {
Log.e(TAG, "onRewardedAdClosed")
rewardedAd = createAndLoadRewardedAd()
}
override fun onUserEarnedReward(rewardItem: RewardItem) {
Log.e(TAG, "onUserEarnedReward")
translateText()
}
override fun onRewardedAdFailedToShow(errorCode: Int) {
translateText()
}
})
}
Finally I called as following
R.id.btnTranslate -> {
if (rewardedAd.isLoaded){
showMessage(
getString(R.string.translate_ads_show_warning_title),
getString(R.string.translate_ads_show_warning_msg)
)
} else {
progress.setVisible(true)
isRewardedAdLoaded.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { loaded ->
if (loaded and progress.isVisible){
progress.setVisible(false)
showMessage(
getString(R.string.translate_ads_show_warning_title),
getString(R.string.translate_ads_show_warning_msg)
)
}
}
})
}
}