0

Help me, stackoverflow, you are my only hope. I want to create an Android Live Wallpaper that displays Ads in the preference activities of the wallpaper. I almost got this working by following this example:

Android Admob advert in PreferenceActivity

This works fine, but this example uses OnCreateView() to load the ads. I noticed that OnCreateView gets called multiple times for the custom ad preference. This even happens while you are scrolling in the preferences list, so the AdRequest is triggered again and again. This problem is also mentioned here:

AdView requests new add every time SeekBar is touched

So I moved the call for the AdRequest to onAttachedToHierarchy() and use a member variable to store the adView. I then use the stored adView to add this to the view in the OnCreateView()-Event This, however, results in a strange behavior: The ad reload has stopped, but the ad is only displayed "sometimes" on top of the list of preferences. For example, when I load the preferences, the ad is not being displayed. I scroll down, and up again, suddenly the ad is there. Down again, quick up again, ad has disappeared. Sloooow up: Ad appears again. Debugging shows that from some of the multiple calls of OnCreateView() some are "successful" and the ad gets displayed, and some are not. It seems that it requires a "successful" call to happen as last call of OnCreateView() so the ad stays on the screen. What do I need to do to make sure the adView is always displayed properly? Is there maybe a different approach to display ads in the preference screen?

My code is as follows:

Preference to display the ad:

public class AdPreference extends Preference {

public AdPreference(Context context, AttributeSet attrs, int defStyle) {super    (context, attrs, defStyle);}
public AdPreference(Context context, AttributeSet attrs) {super(context, attrs);}
public AdPreference(Context context) {super(context);}

/** The view to show the ad. */
private AdView adView;

/* Your ad unit id. Replace with your actual ad unit id. */
private static final String AD_UNIT_ID = "XXXXXXXXXXXXXXX";

@Override 
public void onAttachedToHierarchy(PreferenceManager preferenceManager){
    super.onAttachedToHierarchy(preferenceManager);

    Activity activity = (Activity)getContext();

    // Create an adView.

    adView = new AdView(activity);
    adView.setAdSize(AdSize.BANNER);
    adView.setAdUnitId(AD_UNIT_ID);

    // Create an ad request. Check logcat output for the hashed device ID to
    // get test ads on a physical device.
    AdRequest adRequest = new AdRequest.Builder()
        .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
        .build();

    // Start loading the ad in the background.
    adView.loadAd(adRequest);
}

@Override
protected View onCreateView(ViewGroup parent) {
    // this will create the linear layout defined in ads_layout.xml
    View view = super.onCreateView(parent);

    if (adView.getParent()!=null)
    {
        ((LinearLayout)adView.getParent()).removeAllViews();
    }
    ((LinearLayout)view).addView(adView);

    return view;    
}

}

Snippet of the preference XML:

<?xml version="1.0" encoding="UTF-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:examplens="http://example.com">
<example.AdPreference     android:layout="@layout/ad_preference" />
<Preference android:title="@string/preference1" />
    .
    .
    .
<PreferenceCategory>

</PreferenceCategory>

Layout XML for the ad preference:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="@+id/linearLayoutForAd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>

Please let me know in case the problem description is unclear and you need more code / info! Thanks in advance!

Community
  • 1
  • 1
MrWagoner
  • 1
  • 2

2 Answers2

0

Don't show ads in preferences. This is really poor UX. And the PreferenceActvity mechanism is not well setup to handle it.

How long are your users going spend in your preferences screen? Put the ads in the main body of your app instead.

William
  • 20,150
  • 8
  • 49
  • 91
  • 1
    Thanks for the reply! Normally I would try to avoid displaying ads in the preferences, but the app is an **android live wallpaper**, so there is no "main body" or User Interface to work with...and displaying an ad in the wallpaper itself would be even worse for the user :-(. If your comment was more meant like "put the ads outside of the preferences list in the preferences screen", could you please advise how to do so? I would gladly adopt this method, but I don't know how this would work in the context of the Android PreferenceFragment as it seems to bring its own layout when displayed. – MrWagoner Mar 29 '14 at 08:59
  • 1
    Sorry, I don't think you can do what you want to do. And honestly I'm not sure the investment of your time to make it work (even it could be made to work) will be worth it. You will see so few clicks on ads that are displayed for that short a period unless you have 10 of millions of users regularly changing their settings you are likely to see extremely little revenue. – William Mar 30 '14 at 09:42
  • Thanks for replying again! I fully agree with you regarding your estimation of the ad revenue: I also don't expect to see many clicks on the ads. I wanted to do the ad integration nevertheless because I wanted to learn more about the details of AdMob integration before I use it in a bigger project. On the technical side I got it working by now by caching the entire LinearLayout instead of the AdView, see answer. Thank you again for your thoughts and your consideration! – MrWagoner Mar 30 '14 at 19:59
0

I got it working by making a minor change: The trick was to cache the entire "LinearLayout"-View instead only caching the AdView. The code for the AdPreference was changed to:

public class AdPreference extends Preference {

public AdPreference(Context context, AttributeSet attrs, int defStyle) {super    (context, attrs, defStyle);}
public AdPreference(Context context, AttributeSet attrs) {super(context, attrs);}
public AdPreference(Context context) {super(context);}

/** The view to show the ad. */
private static AdView adView;
private static View myCustomView;

/* Your ad unit id. Replace with your actual ad unit id. */
private static final String AD_UNIT_ID = "XXXXXXXXXXXXXXX";

@Override
protected View onCreateView(ViewGroup parent) {
    // this will create the linear layout defined in ads_layout.xml

    if (myCustomView==null)
    {

        View view = super.onCreateView(parent);

        Activity activity = (Activity)getContext();

        // Create an adView.

        adView = new AdView(activity);
        adView.setAdSize(AdSize.BANNER);
        adView.setAdUnitId(AD_UNIT_ID);
        //adView.

        ((LinearLayout)view).addView(adView);

        myCustomView = view;

        // Create an ad request. Check logcat output for the hashed device ID to
        // get test ads on a physical device.
        AdRequest adRequest = new AdRequest.Builder()
            .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
            .build();

        // Start loading the ad in the background.
        adView.loadAd(adRequest);

    }
    return myCustomView;    
}

}

This makes it work for me as intended, no permanent ad reloading and the ad remains "stable" in the list of preferences.

MrWagoner
  • 1
  • 2