How do I put an admob adview in the settings screen for a live wallpaper?

12,155

Solution 1

Here's a simpler solution: Create a new preference type that displays a single ad. You can then include that preference type in the xml definition for your preferences to display one or more ads.

Custom Preference Class:

public class AdmobPreference extends Preference
{

    public AdmobPreference(Context context) {
        super(context, null);
    }

    public AdmobPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected View onCreateView(ViewGroup parent) {
            //override here to return the admob ad instead of a regular preference display
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        return inflater.inflate(R.layout.admob_preference, null);
    }

}

XML Layout for AdmobPreference:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myapp="http://schemas.android.com/apk/res/<YOUR PACKAGE>"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
>

    <com.google.ads.AdView android:id="@+id/ad" android:layout_width="fill_parent"
        android:layout_height="wrap_content" myapp:backgroundColor="#000000" myapp:primaryTextColor="#FFFFFF"
        myapp:secondaryTextColor="#CCCCCC" />
</LinearLayout>

And then you just add something like this into your preferences xml definition:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 
android:orderingFromXml="true">

    <YOUR PACKAGE NAME.AdmobPreference android:key="ad" />

    ... other preferences ...
</PreferenceScreen>

Solution 2

Thank you, I was really looking for this.

Just a warning: if you are using this approach for production code and you are using proguard you need to tell proguard not to encode the class AdmobPreference, otherwise the inflator will FC.

Add this line to your proguard.cfg:

-keep public class * extends android.preference.Preference

Solution 3

For those wondering how to implement this with a PreferenceFragment, here is a solution, there is no need to create a custom Preference:

First create a new layout (here named settings.xml in the layout resources folder) that will be inflated in the PreferenceFragment:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_height="match_parent"
                android:layout_width="match_parent">

    <com.google.android.gms.ads.AdView
            xmlns:ads="http://schemas.android.com/apk/res-auto"
            android:id="@+id/adview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            ads:adUnitId="XXXXX"
            ads:adSize="SMART_BANNER"
            android:layout_alignParentTop="true" />

    <ListView android:id="@android:id/list" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content"
        android:layout_below="@id/adview" />

</RelativeLayout>

Then, use this layout in the PreferenceFragment, load it in the onCreateView method:

private AdView adView;
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.settings, null);

        adView = (AdView)v.findViewById(R.id.adview);

        //** Adview */
        if(Tools.isNetworkConnected(getActivity())){
            adView.setVisibility(View.VISIBLE);
        }
        else{
            adView.setVisibility(View.GONE);
        }

        //Create ad banner request
        AdRequest adBannerRequest = new AdRequest.Builder()
//      .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
//      .addTestDevice("XXXXX")
        .build();

        // Begin loading banner
        adView.loadAd(adBannerRequest);

        return v;
    }

Don't forget to add the following code for the new version of Admob using Google Play services:

@Override
    public void onResume() {
        super.onResume();
        if(adView != null){
            adView.resume();
        }
    }

    @Override
    public void onPause() {
        if(adView != null){
            adView.pause();
        }
        super.onPause();
    }

    @Override
    public void onDestroy() {
        if(adView != null){
            adView.destroy();
        }
        super.onDestroy();  
    }

Solution 4

I've managed to answer this for myself so I'll post the solution in here in case someone else has the same question.

I added a TabActivity as well as the standard Preferences activity, then nested the Preferences inside a Tab of the TabActivity. This means I've got a normal layout xml for the TabActivity that I can put an adview (or any other type of view) inside and I've still got the generated preferences screen working within that.

Code for the TabActivity

public class SettingsTabActivity extends TabActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tablayout);

        TabHost tabHost = getTabHost();  // The activity TabHost
        TabHost.TabSpec spec;  // Resusable TabSpec for each tab
        Intent intent;  // Reusable Intent for each tab

        // Create an Intent for the regular live wallpaper preferences activity
        intent = new Intent().setClass(this, Preferences.class);

        // Initialize a TabSpec and set the intent
        spec = tabHost.newTabSpec("TabTitle").setContent(intent);
        spec.setIndicator("TabTitle");

        tabHost.addTab(spec);

        tabHost.setCurrentTab(0);      
    }
}

Code for the tablayout.xml

<?xml version="1.0" encoding="utf-8"?>

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myapp="http://schemas.android.com/apk/res/*your package name goes here for admob*"
    android:id="@android:id/tabhost" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout android:orientation="vertical"
            android:layout_width="fill_parent" android:layout_height="fill_parent">

            <com.admob.android.ads.AdView android:id="@+id/ad"
                    android:layout_width="fill_parent" android:layout_height="wrap_content"
                    myapp:backgroundColor="#000000" myapp:primaryTextColor="#FFFFFF"
                    myapp:secondaryTextColor="#CCCCCC" />

            <TabWidget android:id="@android:id/tabs"
                    android:layout_width="fill_parent" android:layout_height="1dp"
                    android:tabStripEnabled="false" android:visibility="invisible" />

            <FrameLayout android:id="@android:id/tabcontent"
                    android:layout_width="fill_parent" android:layout_height="fill_parent"
                    android:padding="1dp" />
    </LinearLayout>
</TabHost>

Setting android:visibility="invisible" and android:layout_height="1dp" on the TabWidget tag means the user can't tell it's actually a Tab

Solution 5

You can implement a settings screen in two ways:

  1. Use the preferences framework so that the XML preferences file auto-creates the preferences layout and all its functionality
  2. Write the activity yourself, i.e. on loading show the current preferences, as they are shown, save them, using a normal layout XML file that you create

I suspect you are adding the AdMob object to an XML file that cannot handle it, and can onlky handle preference items. Please post your XML file, and specify what casting error you are seeing.

If you want ultimate control over the contents of the preferences screen, then implement it yourself as a normal activity, and then you can do anything you want.

Share:
12,155
James
Author by

James

Updated on June 04, 2022

Comments

  • James
    James over 1 year

    I've seen the Mario live wallpaper uses admob ads in the settings screen, but I haven't been able to do it myself. If I put the adview into the settings.xml like you would with a normal layout I get a class cast exception.

    Here's a screenshot of the mario live wallpaper to illustrate what I'm trying to do.

    example screenshot

  • pmont
    pmont over 9 years
    Looks like this would make the ad scroll with the rest of the preferences list.
  • Steven De Bock
    Steven De Bock over 9 years
    Creating a custom preference does allow you to easily insert ads in between settings / other preferences. Whereas your solution only allows to put an ad at the bottom or top of the settings.
  • Yoann Hercouet
    Yoann Hercouet over 9 years
    Yes I agree, but the question is asking for a solution to put the ad at the top, and it is what my code is doing.
  • pmont
    pmont over 9 years
    Thanks. See this for placing the ad at the bottom: stackoverflow.com/questions/8583861/…