Facebook's NativeAdsManager gives always the same ad - android

I'm using Facebook's NativeAdManager for Android as intended:
nativeAdsManager = new NativeAdsManager(context, "my_placement_id", 3);
which should load me 3 different ads, and them allow me to get them in my adapter using:
NativeAd adItem = nativeAdsManager.nextNativeAd();
but for some reason I always get the same ad. According to their reference:
The NativeAdsManager provides a mechanism to fetch a set of NativeAds and then use them within your application. The recommended usage is to call nextNativeAd() at the moment when you are about to render an ad. The NativeAdsManager can hold at most 10 unique ads at once but supports giving out as many ads as needed by cloning over the set of NativeAds it got back from the server which can be useful for feed scenarios.
Am I missing something here?

Related

How Do We Call loadAd Method of NativeBannerAd More Than Once?

I'm just trying to manage fail scenarios of ads in my app. So, after onError triggered due to some reason(e.g no network) I just called loadAd method of NativeBannerAd like below. But app crashed with called more than once error.
mFacebookNativeBannerAd = NativeBannerAd(context, id)
val builder = mFacebookNativeBannerAd.buildLoadAdConfig()
builder.withAdListener(object : NativeAdListener {
// ...
// Other callback methods
override fun onError(p0: Ad?, error: AdError?) {
mFacebookNativeBannerAd.loadAd() // --> 'called more than once' exception
}
})
mFacebookNativeBannerAd.loadAd()
I didn't see any description about this exception on documents. NativeAd, NativeAdsManager, InterstitialAd objects works with above scenario. But NativeBannerAd does not.
How can i load the ad again ?
The audience version i'm using is audience-network-sdk:5.6.1
Once the Facebook NativeBannerAd is failed then a new banner object needs to be created for every reload because the same object cannot be used again so you can create a method which will instantiate a new NativeBannerAd object and load it.
You must be thinking Why not reuse the same object from onError?
Because it's a code smell. In case of network error(your use case), the add will keeps on trying to load it self(can add retry logic but still code smell) and eventually will crash your app with StackOverflowException due to recursive behaviour.
Documentation reference as POC
Ad Instance is not an ad manager. You are supposed to
instantiate a new instance whenever you need "reload" an ad for native
ads and banner ads.

Inmobi.com "ad request successful but no ad served"

When I try to load an interstitial with inmobi.com and most of the times I get the error "ad request successful but no ad served". Why is this happening? Any solution for this? It works well with testing ads when set to "Test mode" in the website. Will this be because inmobi has not enough providers to display ads at that moment?
I asked Inmobi support page but they don't answer. I am starting to regret moving from admob to inmobi.
This is the code I use:
JSONObject consentObject = new JSONObject();
try {
consentObject.put(InMobiSdk.IM_GDPR_CONSENT_AVAILABLE, true); // Provide correct consent value to sdk which is obtained by User
consentObject.put("gdpr", "1"); // Provide 0 if GDPR is not applicable and 1 if applicable
//consentObject.put(InMobiSdk.IM_GDPR_CONSENT_IAB, “<<consent in IAB format>>”); // Provide user consent in IAB format
} catch (JSONException e) {
}
InMobiSdk.init(this, "My InMobi Account ID here", consentObject);
long MyPlacementID = 1234566789L; //My Placement ID here as long
mInterstitialAd = new InMobiInterstitial(this, MyPlacementID, new InterstitialAdEventListener() {
#Override
public void onAdLoadSucceeded(InMobiInterstitial inMobiInterstitial) {
super.onAdLoadSucceeded(inMobiInterstitial);
if (inMobiInterstitial.isReady()) {
mInterstitialAd.show();
}
#Override
public void onAdLoadFailed(InMobiInterstitial inMobiInterstitial, InMobiAdRequestStatus inMobiAdRequestStatus) {
sError = inMobiAdRequestStatus.getMessage();
Here I get error: "ad request successful but no ad served"
}
I emailed the support team and they answered that is shown if they don't have any ad to be displayed (maybe for my location or for my time). So, it is just that they run out of ads to be displayed. If I try it many many times then I may get one ad. So it is a server problem. Not enough clients to pay for ads. It is a pity.
I was having the same issue.I tried different ways to get the test ads.But everything was in vein.Then i went through their documentation and found that we need to set up a layout for ad placement.There is an option to customize that.Click on save and then add your device id in the testing devices section, you will see test ads coming up.I found this one from an article where it said "If you set banner sizes different from those provided by default, the SDK will refuse to load data and will issue a corresponding message to the log:
[InMobi]: Failed to fetch ad for placement id: 201901231449, reason phrase available in onAdLoadFailed callback.
And the message “Ad request successful but no ad served” with the code “NO_FILL” appears in the listener's method. Hence our expert advice: always redefine the listener's methods which are responsible for errors. Acting such a way, you'll avoid many difficulties later."
https://agilie.com/en/blog/how-to-integrate-inmobi-sdk-to-start-monetizing-your-android-app
Contradicting answer to #Ton's answer.
All the ad servers work in the following manner. Advertisers pay for ads with specific targetted audiences. So whenever you ask an ad network to provide an ad it actually checks if they have an ad for which targeting is matched with the current user (for ex. area, gender, age as and when available). If they don't have any ad which can be shown to the current user then they will fire NO_FILL.
Also, specific to InMobi, they don't provide many ads on emulators so try on a physical device to get ads.

High ram usage with admob

I am trying to place ads inside my app. According to Admob Documentation I have to initialize Mobile Ads SDK
MobileAds.initialize(this, "YOUR_ADMOB_APP_ID");
This causes spike in high ram usage in code.
But if i remove this line then ram usage drops & and this line of code doesn't seem to have any affect on servering ads inside the app.
Also when requesting ad from admob ram usage again spike up and causes 3-4 GC events on app startup. I believe this is memory leak.
Here's how i am requesting ad in onCreate method
AdRequest request = null;
if (BuildConfig.DEBUG) {
//Facebook Audience Network
List<String> testDeviceId = new ArrayList<>();
testDeviceId.add("TESTID");//Redmi Note 3
testDeviceId.add("TESTID");//Moto G 1st Gen
AdSettings.addTestDevices(testDeviceId);
//Google Ad-mob
request = new AdRequest.Builder()
.addTestDevice("TESTID")//Redmi Note 3
.addTestDevice("TESTID")//Mot G 1st Gen
.build();
} else {
request = new AdRequest.Builder()
.build();
}
AdView mAdView = findViewById(R.id.adView);
mAdView.loadAd(request);
When loading this banner ads several GC event are kicked in. If i don't load ads GC event are never kicked in.
Is this behavior normal with admob? How can i resolve this?
Google AdView has WebView with a lot of animation inside. It will heats up all mobile CPU.
AdView take 30% of CPU.
Solution : You can also add custom listeners to destroy after some time and recreate in order to handle it even better. Serverside there is also a parameter telling the app ad how soon should ask for a new ad, I am not sure if it exist in all cases but it is there for DFP accounts.
here is the easiest way i would suggest
new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
if (!isBeingDestroyed) {
final AdRequest adRequest = new AdRequest();
final AdView adView = (AdView) findViewById(R.id.ad);
adView.loadAd(adRequest);
}
}).sendEmptyMessageDelayed(0, 1000);
Here is the link that provide complete solution for this.
Hope it will help you.
Yes, that behaviour is normal. AdView is a dynamic WebView which consumes about 50mb RAM. Most of the memory leaks occur when you rotate screen and instance of previous Activity is attached to an element like listener or thread. Here are some examples. To check whether your app leaks or not you can use LeakCanary or Android Studio.
To check leaks in Android Studio
Start Memory Profiler
Select Memory and "Dump Java Heap"
Export file as .hprof file
Drag .hprof file to Android Studio and look for Analyzer Tasks and push run button to check if your activity leaks.
Your app is still within an acceptable limit of RAM usage for most devices.
You can put android:largeHeap="true" in your AndroidManifest.xml file, so that your users won't get affected.
You are absolutely right. MobileAds.initilize() can be removed, and the application will work, BUT. When you request the first load of ads, the initilize() method will be called under the hood.
I recommend that you call this method as soon as possible. For example, in your Application class. Also, starting from version Admob 21.0.0, you can optimize the initialization process. Just add the following lines to your manifest
<meta-data
android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
android:value="true"/>
<meta-data
android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
android:value="true"/>
i dont know if this will help but if you care about ram usage and you use ads in many activities you could start the ad mob from application class and that case the ad will only initialized once

How to set admob custom targeting

I would like to an admob banner in my app, showing ads in specific categories (every device would have a specific categories).
For example, app installed on one device would show only music, other would show only travel, etc.
I looked in Google developers guide and PublisherAdRequest API and notice the following example:
// Example: Pass custom targeting "Age=25", "Color=Blue,Green,Red"
private PublisherAdRequest createRequest() {
Bundle bundle = new Bundle();
bundle.putString("Age", "25");
bundle.putString("Color", "Blue,Green,Red");
return new PublisherAdRequest.Builder()
.addNetworkExtras(new AdMobExtras(bundle))
.build();
}
My question is - What keywords are available for me?
If I would like to get only Music and travel related ads, what keywords should I use?
Is there another way to do it?

Why does AdMob return NO FILL

I'm using an AdMob view in an android app, but I'm unable to get any ad into the app.
For reference, I've added the view to a ListView as explained by Dan Dyer here
EDIT:
I'm using GoogleAdMobAdsSdk-4.1.1. The release notes of Google AdMob Ads SDK for version 4.1.0 says:
"...
- Added support for AdRequest.addTestDevice() and AdRequest.setTestDevices(). Note that AdRequest.setTesting() is now deprecated.
..."
This is how the ad is inserted to my ListView:
public View getView(int position, View convertView, ViewGroup parent) {
// Some other code
// Reusing convertView etc.
AdView adView =
new AdView((Activity) getContext(), AdSize.BANNER,
"/xxxxxx/ca-pub-xxxxxxx/my_ad_unit");
for (int i = 0; i < adView.getChildCount(); i++) {
adView.getChildAt(i).setFocusable(false);
}
adView.setFocusable(false);
float density = getContext().getResources().getDisplayMetrics().density;
int height = Math.round(50 * density);
AbsListView.LayoutParams params = new AbsListView.LayoutParams(
AbsListView.LayoutParams.FILL_PARENT, height);
adView.setLayoutParams(params);
AdRequest request = new AdRequest();
request.addTestDevice("xxxxxxxxxxxxxxxxx");
adView.loadAd(request);
// other stuff
// returning convertView
}
I've also added an AdListener to the adview, and on every loadAd, the onFailedToReceiveAd callback method is called:
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
Log.d(TAG, "AdMob in list failed to receive ad: " + arg1.name());
}
In logcat I get this message:
08-17 15:22:18.065: AdMob in list failed to receive ad: NO_FILL
Can anyone tell me what this errorcode means?
To answer the question:
NO_FILL is returned from AdMob when there is no inventory left to
serve in the AdMob/DFP backend.
First of all this meant I was requesting an ad of size AxB, but the backend had no ads of this size left to show. It is important that the size you request has inventory left in the backend systems of AdMob/DFP.
Second, their API states that the first time you request an ad to a specific ad unit, you should expect up to two minutes before the ads start serving. I don't know if it is because I am not stationed in the US, but these two minutes often becomes at least 20 minutes if not several hours for me.
I get a 'No Fill' response when I make a request for ads in the Test or Non-Test Mode. What should I do?
In both the Test and Non-Test modes, depending on various parameters such as server load, non-availability of targeted ads, and so on, the Ad Server may send a No Fill response. Try reloading the ad after some time to keep receiving the ads. Although a No Fill is common in the advertising space, you can write to us with your queries.
http://developer.inmobi.com/wiki/index.php?title=Android
This essentially means there are no Ads currently with AdMob for your FILL request. Run AdMob in test mode and you can see the ad.
request.setTesting(true);
Change the package name of your live app or game in market available..
and use your new admob-id in the project , check once..
androidadmobunityunity3d

Categories

Resources