This post will look at putting adverts into your application. To use this code you will need to sign up to google’s AdMob service. I’m going to assume that you have done all that and have a publisher id that you can use for this example.

OK, so how to go about this. The idea is to create an advert at the bottom of the screen that is invisible before the advert arrives, and slides up from the bottom of the screen when it arrives.

Step 1 is to create a new Android application in eclipse called AdMobExample. When you have done that you need to right click on the project and select Properties. On the Properties for AdMobExample dialog, click on Java Build Path from the list on the right. You should now see something like this:

Properties dialog

To add the GoogleAdMobAdsSdk-4.0.4.jar library you need to click on the Add External Jars button and select the jar file (you must install the library yourself by downloading the SDK from the AdMob site.) I installed the SDK to /usr/lib (on Linux), this might be something like C:/Program Files/GoogleAdsMobAdsSdk on Windows.

Now we can start to build the app. First up is the AndroidManifest.xml file. We need add an activity to the <application> so that AdMob can do its thing. Add this just before the </application> tag:

1
2
3
4
<!-- AdMobActivity definition -->
<activity android:name="com.google.ads.AdActivity"
    android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
    android:configChanges="orientation|keyboard|keyboardHidden" />

In order for this activity to work it needs access to the internet, and access to the network state of the device. This means that we must request these permissions by adding these lines after the <application> tag:

1
2
3
    <!-- AdMob SDK requires Internet permission  -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Finally, AdMob can use the device’s location when it serves adverts. To enable this feature you need to add the following after the &jt;uses-permission> lines :

1
2
    <!-- Allow AdMob to use the devices location when delivering ads -->
    <meta-data android:value="true" android:name="ADMOB_ALLOW_LOCATION_FOR_ADS" />

That completes the changes to the manifest. Now we need to create a layout that will lock the adverts to the bottom of the screen. This is done by using RelativeLayout. Here is the complete main.xml file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myapp="http://schemas.android.com/apk/res/com.example.admobexample"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
 
<!-- This is the main view. Here it is just a simple TextView, but it will
      probably be another layout in a more complex app -->
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
 
<RelativeLayout
     android:layout_width="wrap_content"         
     android:layout_height="wrap_content"         
     android:layout_alignParentBottom="true" >  
 
	<!-- Set myapp:adUnitId to be your publisher ID -->
    <com.google.ads.AdView
        android:id="@+id/ad"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        myapp:adUnitId="000000000000000"
        myapp:adSize="BANNER"
        myapp:refreshInterval="30"
     />
 
</RelativeLayout>
</RelativeLayout>

The first RelativeLayout contains the main view, in this example it is just a simple TextView, followed by another RelativeLayout that contains the view for the advert. In terms of the layout, the crucial part of this layout is line 19, setting the android:layout_alignParentBottom element to true tells android to put the AdView at the bottom of the screen. To get the view to deliver your adverts you need to change the myapp:adUnitId value to be your publisher id.

Now we have got our manifest and layout configured all that is left is to request an advert in the onCreate method:

1
2
3
4
5
6
7
8
9
10
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
 
    // Request an ad
    AdRequest ad = new AdRequest();
    ad.setTesting(true);
    AdView adView = (AdView)findViewById(R.id.ad);
    adView.loadAd(ad);
}

The setTesting(true) call tells AdMob to simulate adverts in the emulator, but it will still serve real adverts on a device.

If you run this now in the emulator you should see a screen like this:

Properties dialog

If you deploy this to a device then it will deliver a real advert.

Download

You can download this example from here.

To add this example to eclipse go to File|New|Android Project, select “Create project from existing source” and then browse to the folder inside of the downloaded zip file.

, ,

The ViewFlipper is a really useful view on android. It allows you to build up a set of pages and easily move between them. At its simplest, you call the showPrevious and showNext methods on the view and it moves through your pages and wraps back to the beginning when it gets to the end. At the other end of the spectrum you can incorporate gestures to enable the user to swipe through the pages, and with the ViewFlipper handling just three views you can allow the user to move through any number of pages.

In this first article, I am just going to show you a simple application so that you can see what it does. I will go into the more complex examples in other posts.

So, this application is going to show two buttons at the top to allow the user to go to the next and previous pages. Beneath them will be the ViewFlipper which contains three TextViews.

So firstly create a new android project called ViewFlipperSimple and change the res/layout/main.xml file to be the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content">
        <Button 
            android:id="@+id/previous" 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:text="Prev" />
        <Button 
            android:id="@+id/next" 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:text="Next" />
    </LinearLayout>
    <ViewFlipper
        android:id="@+id/flipper" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent">
        <TextView
            android:text="view 1"
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" />
        <TextView
            android:text="view 2"
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" />
        <TextView
            android:text="view 3"
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" />
    </ViewFlipper>
</LinearLayout>

Now replace the contents of ViewFlipperSimple.java with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.example.android.viewflippersimple;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ViewFlipper;
 
public class ViewFlipperSimple extends Activity implements OnClickListener {
    Button next;
    Button previous;
    ViewFlipper flipper;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        flipper = (ViewFlipper)findViewById(R.id.flipper);
        next = (Button) findViewById(R.id.next);
        previous = (Button) findViewById(R.id.previous);
 
        next.setOnClickListener(this);
        previous.setOnClickListener(this);
    }
 
    @Override
    public void onClick(View v) {
        if (v == next) {
            flipper.showNext();
        }
        else if (v == previous) {
            flipper.showPrevious();
        }
    }
}

You can see on line 10 that the Activity class implements the OnClickListener class. This is so that our activity knows when the user clicks on the buttons: lines 24 and 25 tell the buttons that we want to know about the clicks.

The onClick method determines which button was pressed and calls showNext or showPrevious on the ViewFlipper.

That is all we need to do for the application to work, so try running it and see what happens.

Unfortunately, that is not the whole story, because on android 2.1 there is a problem with changing orientation. I also get the crash on android 2.2. An IllegalArgumentException occurs in the onDetachedFromWindow method of ViewFlipper. You can find out about the about the problem here. In the emulator, with the num lock key off press the 7 key to change to landscape and then the 9 key to go to back to portrait. Did the app crash? If not try going back and forth between landscape and portrait quickly. After the crash you should see something like this in the Debug window:

Thread [<1> main] (Suspended (exception IllegalArgumentException))
    WindowManagerImpl.removeViewImmediate(View) line: 226
    Window$LocalWindowManager.removeViewImmediate(View) line: 436
    ActivityThread.handleDestroyActivity(IBinder, boolean, int, boolean) line: 3684
    ActivityThread.handleRelaunchActivity(ActivityThread$ActivityRecord, int) line: 3789
    ...

The java exception is something like:

java.lang.IllegalArgumentException: Receiver not registered: android.widget.ViewFlipper$1@44b6ab90
    at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:667)
    at android.app.ApplicationContext.unregisterReceiver(ApplicationContext.java:747)
    at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:321)
    at android.widget.ViewFlipper.onDetachedFromWindow(ViewFlipper.java:104)

There is a workaround for this bug. Which is to create a wrapper class around ViewFlipper and catch the exception. To fix our application create a new class called MyViewFlipper and change the code to be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ViewFlipper;
 
public class MyViewFlipper extends ViewFlipper {
    public MyViewFlipper(Context context) 
    {
        super(context);
    }
 
    public MyViewFlipper(Context context, AttributeSet attrs) 
    {
        super(context, attrs);
    }
 
    @Override
    protected void onDetachedFromWindow() 
    {
        if (Integer.parseInt(Build.VERSION.SDK) &gt;= 7) 
        {                          
            try 
            {                                  
                super.onDetachedFromWindow();                          
            } 
             catch (IllegalArgumentException e) 
            {                                  
                Log.e("MyViewFlipper", "Android issue 6191: http://code.google.com/p/android/issues/detail?id=6191");                          
            } 
            finally 
            {                                  
                super.stopFlipping();                          
            }                  
        }  
        else 
        {                          
            super.onDetachedFromWindow();                  
        }  
    }
}

All we need to do to use our extended ViewFlipper is to modify the AndroidManifest.xml file. Change “ViewFlipper” to be “com.example.android.viewflippersimple.MyViewFlipper” on lines 21 and 37.

Run the application again and try changing the orientation. The application should function as you would expect. If you look in the LogCat window in eclipse you will see the red exception line that the MyViewFlipper class puts out when it absorbs the exception.

Download

You can download this example from here.

To add this example to eclipse go to File|New|Android Project, select “Create project from existing source” and then browse to the folder inside of the downloaded zip file.

,

By day I am a C#/SQL developer, and have been for… well, too long to remember. But now Android is here, and it is fascinating stuff, so now I develop Android apps in my spare time. There is a lot of stuff on the internet that has really helped get to grips with developing for Android, but quite often there was a step missing in the information that left me piecing bits together. So this blog will be about the blockers that I encounter as I learn.

Some of the stuff will be from other blogs, but the idea is not to regurgitate what others have done, but to provide complete solutions that others can use. I should have posted the missing details as comments on the blogs that I did find useful, but in my haste to get up-to-speed, I did not. That’s life. In the future I will add comments, as I hope readers of this blog will.

If I feel the urge I will post on C#, SQL and other developer type stuff along the way.

, ,