Search This Blog

Showing posts with label layout. Show all posts
Showing posts with label layout. Show all posts

03 January 2012

Fragments

Well, I've been needing to look into Fragments for awhile now...

First, to generate a blank project...

malachi@onyx:~/work$ mvn archetype:generate -DarchetypeCatalog=http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml
[INFO] Scanning for projects...
[INFO]                                                                        
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml -> org.eoti.kryten:kryten-archetype (kryten-archetype)
2: http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml -> org.eoti.galatea:galatea-archetype (galatea-archetype)
3: http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml -> org.eoti.archtest:archtest-archetype (archtest-archetype)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 2
Define value for property 'groupId': : org.eoti.android.test.fragments
Define value for property 'artifactId': : FragmentTest
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  org.eoti.android.test.fragments: :
Confirm properties configuration:
groupId: org.eoti.android.test.fragments
artifactId: FragmentTest
version: 1.0-SNAPSHOT
package: org.eoti.android.test.fragments
 Y: :
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: galatea-archetype:1.1-SNAPSHOT
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.eoti.android.test.fragments
[INFO] Parameter: artifactId, Value: FragmentTest
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: org.eoti.android.test.fragments
[INFO] Parameter: packageInPathFormat, Value: org/eoti/android/test/fragments
[INFO] Parameter: package, Value: org.eoti.android.test.fragments
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: org.eoti.android.test.fragments
[INFO] Parameter: artifactId, Value: FragmentTest
[WARNING] Don't override file /home/malachi/work/FragmentTest/src/main/android/res/values/strings.xml
[WARNING] Don't override file /home/malachi/work/FragmentTest/src/main/android/res/layout/main.xml
[INFO] project created from Archetype in dir: /home/malachi/work/FragmentTest
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 21.579s
[INFO] Finished at: Tue Jan 03 08:30:32 PST 2012
[INFO] Final Memory: 8M/245M
[INFO] ------------------------------------------------------------------------
malachi@onyx:~/work$ cd FragmentTest/
malachi@onyx:~/work/FragmentTest$ tree
.
├── pom.xml
└── src
    ├── AndroidManifest.xml
    └── main
        ├── android
        │   └── res
        │       ├── drawable
        │       │   └── icon.png
        │       ├── layout
        │       │   └── main.xml
        │       └── values
        │           └── strings.xml
        └── java
            └── org
                └── eoti
                    └── android
                        └── test
                            └── fragments
                                └── FragmentTestActivity.java

13 directories, 6 files


While it should be possible to use the Fragments with pre-HONEYCOMB (http://android-developers.blogspot.com/2011/03/fragments-for-all.html); but for now, let's just try it in the ICS emulator.

Based on the available jars in search.maven.org (http://search.maven.org/#artifactdetails|com.google.android|android|4.0.1.2|jar) let's set the version of the Android dependency in the pom to 4.0.1.2.

Also, change the <sdk><platform>10</platform></sdk> to <sdk><platform>14</platform></sdk>.

For now, comment out the maven-jarsigner-plugin as that requires setting up a keystore.
You'll also need to comment out the <sign /> portion of the android-maven-plugin.

Start up an ICS emulator and try 'mvn clean install' just to make sure we are able to grab the dependencies.
Launch the FragmentTest and you should see your hello world.

Let's move on to adding fragments... this part is derived from http://www.vogella.de/articles/Android/article.html#fragments_tutorial
I've modified their instructions quite a bit to fit into our Maven structure as well as to make things more clear (they had ListFragment extends ListFragment which tends to confuse people).

First, copy src/main/android/res/layout/main.xml to src/main/android/res/layout/detail.xml
On the new detail.xml, give the TextView an id:
android:id="@+id/ftDetailText"

Now, we'll deal the with portrait layout for FragmentTestActivity:
Replace the TextView in the layout/main.xml with:
    <fragment
        android:id="@+id/ftListFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="org.eoti.android.test.fragments.FTListFragment"
    />

Now, let's modify it for landscape...

Copy src/main/android/res/layout/main.xml to src/main/android/res/layout-land/main.xml [note: you will have to create the layout-land directory]

Now, for the layout-land/main.xml:
1. change the LinearLayout to Horizontal:
android:orientation="horizontal"
2. copy/paste the fragment so you now have 2 of them
3. for the first one. let's change the width to:
android:layout_width="300dip"
4. for the second one, change the id to:
android:id="@+id/ftDetailFragment"
5. Change the class to
class="org.eoti.android.test.fragments.FTDetailFragment"



Note: I changed the name of these classes so it would be obvious that these are our classes, and not some default Android implementation. Perhaps a redundant point since we also set the package name.


We'll need to have a separate activity for the detail portion in portrait mode, so let's create the layout for that.
Copy src/main/android/res/layout-land/main.xml to src/main/android/res/layout/details.xml [note: plural details not detail]

For the new details.xml:
1. change the LinearLayout back to Vertical:
android:orientation="vertical"
2. remove the ftListFragment <fragment />

We already have our main FragmentTestActivity.  We are missing our DetailActivity. Let's do some more copy/paste.
Copy FragmentTestActivity.java to DetailActivity.java (in the same directory)
Let's edit DetailActivity.java:
1. Change the class name to DetailActivity [I'd change the TAG to match]
2. change the setContentView to R.layout.details
3. add the following just after setContentView:
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            TextView view = (TextView) findViewById(R.id.ftDetailText);
            view.setText(System.getProperty(extras.getString("key")));
        }
4. Make sure to add the import android.widget.TextView;

We've defined two fragments in the layouts.  We need to create those.
First, we'll create our src/main/java/org/eoti/android/test/fragments/FTDetailFragment.java
This one is pretty simple:

package org.eoti.android.test.fragments;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class FTDetailFragment extends Fragment
{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.detail, container,  false);
    }

    public void setText(String key)
    {
        ((TextView)getView().findViewById(R.id.ftDetailText)).setText(System.getProperty(key));
    }

}


Next, we'll create our src/main/java/org/eoti/android/test/fragments/FTListFragment.java
This one isn't much more difficult:

package org.eoti.android.test.fragments;

import android.*;
import android.R;
import android.app.ListFragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;

public class FTListFragment extends ListFragment
{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ArrayList keys = new ArrayList(System.getProperties().keySet());
        ArrayAdapter adapter = new ArrayAdapter(getActivity(), R.layout.simple_list_item_1, keys);
        setListAdapter(adapter);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        String key = getListAdapter().getItem(position).toString();
        FTDetailFragment fragment = (FTDetailFragment)getFragmentManager().findFragmentById(org.eoti.android.test.fragments.R.id.ftDetailFragment);
        if(fragment != null)
        {
            fragment.setText(key);
        }else{
            Intent intent = new Intent(getActivity().getApplicationContext(), DetailActivity.class);
            intent.putExtra("key", key);
            startActivity(intent);
        }
    }
}

Last, but not least, we need to add the other activity to your AndroidManifest. Put this inside your <application /> tag.
          <activity android:name=".DetailActivity" />



mvn clean install

Launch the application (in portrait mode, I assume)
Select something. You should see a new activity popup with the value of the property you chose.
Hit back, and try it a few times.
When you are done, rotate the emulator using CTRL-F11.  I'm not sure about anyone else, but I have to hit it twice quickly or it won't rotate.
Now, when you select an item on the left, the answer is on the right.
When you are done playing with it, CTRL-F12 [twice in my case] to go back to portrait.

UPDATE: If you wish to use it with older devices...
First, I used the  maven-android-sdk-deployer to create the maven-compliant compat library for me.

        <dependency>
            <groupId>android.support</groupId>
            <artifactId>compatibility-v13</artifactId>
            <version>r6</version>
        </dependency>

This allows older versions of Android to use the Fragments. In my case, I tested against an Android 2.3.3 emulator.

I made no other changes to the pom.  IE: I compiled against a newer SDK and deployed against both.

Other changes to make:
  1. make FTDetailFragment extend android.support.v4.app.Fragment
  2. make FTListFragment extend android.support.v4.app.ListFragment
  3. make DetailActivity extend android.support.v4.app.FragmentActivity
  4. make FragmentTestActivity extend android.support.v4.app.FragmentActivity
  5. In FTListFragment, instead of using getFragmentManager you need to call getSupportFragmentManager.  This is part of the FragmentActivity, so you will need to do something like:
((FragmentActivity)getActivity()).getSupportFragmentManager()...

mvn clean install and it should all work... close down the 2.3.3 emulator, start up an ICS emulator and.. it will still work ;)

16 July 2010

Tables


Let's start with a basic app...

F:\work> mvn archetype:generate -DarchetypeCatalog=http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml
2: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> galatea-archetype (null)
Choose a number: : 2
groupId: org.eoti.android.table
artifactId: TableTest
version: 1.0-SNAPSHOT
package: org.eoti.android.table

F:\work> cd TableTest
F:\work\TableTest> mvn clean install


Now, let's create a new src/main/android/res/values/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="cell">
        <item name="android:layout_height">32px</item>
        <item name="android:layout_width">32px</item>
    </style>
</resources>

Edit src/main/android/res/layout/main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <TableRow>
        <!-- empty corner -->
        <TextView
            style="@style/cell"
            android:text=" "/>
        <!-- top row -->
        <TextView
            style="@style/cell"
            android:text="C1"/>
        <TextView
            style="@style/cell"
            android:text="C2"/>
        <TextView
            style="@style/cell"
            android:text="C3"/>
    </TableRow>

    <!-- row 1 -->
    <TableRow>
        <!-- row 1: left edge -->
        <TextView
            style="@style/cell"
            android:text="R1"/>
        <!-- row 1, col 1 -->
        <TextView
            style="@style/cell"
            android:text="1x1"/>
        <!-- row 1, col 2 -->
        <TextView
            style="@style/cell"
            android:text="2x1"/>
        <!-- row 1, col 3 -->
        <TextView
            style="@style/cell"
            android:text="3x1"/>
    </TableRow>

    <!-- row 2 -->
    <TableRow>
        <!-- row 2: left edge -->
        <TextView
            style="@style/cell"
            android:text="R2"/>
        <!-- row 2, col 1 -->
        <TextView
            style="@style/cell"
            android:text="1x2"/>
        <!-- row 2, col 2 -->
        <TextView
            style="@style/cell"
            android:text="2x2"/>
        <!-- row 2, col 3 -->
        <TextView
            style="@style/cell"
            android:text="3x2"/>
    </TableRow>

    <!-- row 3 -->
    <TableRow>
        <!-- row 3: left edge -->
        <TextView
            style="@style/cell"
            android:text="R3"/>
        <!-- row 3, col 1 -->
        <TextView
            style="@style/cell"
            android:text="1x3"/>
        <!-- row 3, col 2 -->
        <TextView
            style="@style/cell"
            android:text="2x3"/>
        <!-- row 3, col 3 -->
        <TextView
            style="@style/cell"
            android:text="3x3"/>
    </TableRow>
</TableLayout>

Redeploy (mvn clean install) and you should see a fairly unimpressive table.

Let's see if we can make it look a little better...

Update your styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="cell">
        <item name="android:layout_height">32px</item>
        <item name="android:layout_width">32px</item>
        <item name="android:gravity">center</item>
        <item name="android:layout_margin">2dp</item>
    </style>
    <style name="header" parent="@style/cell">
        <item name="android:background">#4D62A4</item>
        <item name="android:textColor">#000000</item>
        <item name="android:textStyle">bold</item>
    </style>
</resources>

And we will change the style of the header column and rows:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <TableRow>
        <!-- empty corner -->
        <TextView
            style="@style/header"
            android:text=" "/>
        <!-- top row -->
        <TextView
            style="@style/header"
            android:text="C1"/>
        <TextView
            style="@style/header"
            android:text="C2"/>
        <TextView
            style="@style/header"
            android:text="C3"/>
    </TableRow>

    <!-- row 1 -->
    <TableRow>
        <!-- row 1: left edge -->
        <TextView
            style="@style/header"
            android:text="R1"/>
        <!-- row 1, col 1 -->
        <TextView
            style="@style/cell"
            android:text="1x1"/>
        <!-- row 1, col 2 -->
        <TextView
            style="@style/cell"
            android:text="2x1"/>
        <!-- row 1, col 3 -->
        <TextView
            style="@style/cell"
            android:text="3x1"/>
    </TableRow>

    <!-- row 2 -->
    <TableRow>
        <!-- row 2: left edge -->
        <TextView
            style="@style/header"
            android:text="R2"/>
        <!-- row 2, col 1 -->
        <TextView
            style="@style/cell"
            android:text="1x2"/>
        <!-- row 2, col 2 -->
        <TextView
            style="@style/cell"
            android:text="2x2"/>
        <!-- row 2, col 3 -->
        <TextView
            style="@style/cell"
            android:text="3x2"/>
    </TableRow>

    <!-- row 3 -->
    <TableRow>
        <!-- row 3: left edge -->
        <TextView
            style="@style/header"
            android:text="R3"/>
        <!-- row 3, col 1 -->
        <TextView
            style="@style/cell"
            android:text="1x3"/>
        <!-- row 3, col 2 -->
        <TextView
            style="@style/cell"
            android:text="2x3"/>
        <!-- row 3, col 3 -->
        <TextView
            style="@style/cell"
            android:text="3x3"/>
    </TableRow>
</TableLayout>


Redeploy (mvn clean install).

That's all well and good... but what if we want to do spanning?

Change row 2:
    <!-- row 2 -->
    <TableRow>
        <!-- row 2: left edge -->
        <TextView
            style="@style/header"
            android:text="R2"/>
        <!-- row 2, col 1 -->
        <TextView
            style="@style/cell"
            android:layout_column="1"
            android:layout_span="2"
            android:text="1x2"/>
        <!-- row 2, col 2 -->
        <!--<TextView-->
            <!--style="@style/cell"-->
            <!--android:text="2x2"/>-->
        <!-- row 2, col 3 -->
        <TextView
            style="@style/cell"
            android:text="3x2"/>
    </TableRow>
   
And let's make it a little easier to see where the data cells are. Add this to your @style/cell:
<item name="android:background">#333333</item>

Redeploy (mvn clean install).

Ok, this is starting to look really good.... but... what if I want more than 1 view added to a cell?

Let's replace "row 1, col 2":

    <!-- row 1 -->
    <TableRow>
        <!-- row 1: left edge -->
        <TextView
            style="@style/header"
            android:text="R1"/>
        <!-- row 1, col 1 -->
        <TextView
            style="@style/cell"
            android:text="1x1"/>
        <!-- row 1, col 2 -->
        <LinearLayout
                android:orientation="horizontal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
            <ImageView
                style="@style/cell"
                android:src="@drawable/icon"/>
            <ImageView
                style="@style/cell"
                android:src="@drawable/icon"/>
        </LinearLayout>
        <!-- row 1, col 3 -->
        <TextView
            style="@style/cell"
            android:text="3x1"/>
    </TableRow>


Redeploy (mvn clean install). You should now see two icons in one cell.

Last, but not least; what if we want the table to stretch across the screen?

Add this to the outside TableLayout:
android:stretchColumns="*"

Redeploy (mvn clean install) and it should now span width.

29 May 2010

Tabs

Let's try doing some tabs.... We'll start with our basic app...

F:\work> mvn archetype:generate -DarchetypeCatalog=http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml

Choose the galatea-archetype plugin
groupId: org.eoti.android
artifactId: TabTest
version: 1.0-SNAPSHOT
package: org.eoti.android

Make sure the emulator is running...
F:\work> cd TabTest
F:\work\TabTest> mvn clean install

Replace the contents of your src\main\android\res\layout\main.xml:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/my_tabhost"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent">
    <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="65px"/>
    <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="200px"
            android:paddingTop="65px">
        <LinearLayout
                android:id="@+id/content1"
                android:orientation="vertical"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
            <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/weather"
                    />
        </LinearLayout>
        <LinearLayout
                android:id="@+id/content2"
                android:orientation="vertical"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
            <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/faces"
                    />
        </LinearLayout>
    </FrameLayout>
</TabHost>


Replace the contents of your src\main\android\res\values\strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">TabTest</string>
    <string name="weather">This is the weather tab</string>
    <string name="faces">This is the faces tab</string>
</resources>


Insert this into the end of your onCreate method in your activity (src\main\java\org\eoti\android\TabTest.java in my case):
        TabHost tabs = (TabHost) this.findViewById(R.id.my_tabhost);
        tabs.setup();

        TabHost.TabSpec spec1 = tabs.newTabSpec("First tab");
        spec1.setIndicator("Weather");
        spec1.setContent(R.id.content1);
        tabs.addTab(spec1);

        TabHost.TabSpec spec2 = tabs.newTabSpec("Second tab");
        spec2.setIndicator("Face");
        spec2.setContent(R.id.content2);
        tabs.addTab(spec2);

        tabs.setCurrentTabByTag("First tab");

Redeploy (mvn clean install) and you will have some basic text-based tabs... 

But, maybe we want some graphics too... This tutorial says:
You need an icon for each of your tabs. For each icon, you should create two versions: one for when the tab is selected and one for when it is unselected. The general design recommendation is for the selected icon to be a dark color (grey), and the unselected icon to be a light color (white).
But I wanted to be a little more creative, so I grabbed a couple icons from the Tango project [note: had to replace '-' in filenames with '_']:
Download these images into src\main\android\res\drawable\





Create face.xml into src\main\android\res\drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/face-devilish" android:state_selected="true" />
    <item android:drawable="@drawable/face-angel" />
</selector>

Create weather.xml into src\main\android\res\drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/weather-showers-scattered" android:state_selected="true" />
    <item android:drawable="@drawable/weather-snow" />
</selector>

In your activity, replace this line:
        spec1.setIndicator("Weather");
with:
        spec1.setIndicator("Weather", this.getResources().getDrawable(R.drawable.weather));

And replace this:
        spec2.setIndicator("Face");
with:
        spec2.setIndicator("Face", this.getResources().getDrawable(R.drawable.face));


While we are at it, open your AndroidManifest.xml and replace this line:
        <activity android:name=".TabTestActivity">
with:
        <activity android:name=".TabTestActivity" android:theme="@android:style/Theme.NoTitleBar">

Redeploy (mvn clean install) and you will have nice icons on your tabs...

End result should look like these:




It is also possible to have the tabs load different Views or Activities by having the activity extend TabActivity. Maybe I'll do another tutorial for that.

27 May 2010

AdMob and AdWhirl

Do you want to display advertisements on your app in hopes of bringing in some money, displaying cross-productization ads or even just so you can make a Lite vs Pro version?  In this example, we will do that using both AdMob (ad server) and AdWhirl (ad aggregator).

To get started, we are going to need to setup a couple of online accounts.

AdMob
  • Create an account at AdMob.
  • From your dashboard, click on "Sites & Apps".
  • Click on "Add Site/App".
  • Click on "Android App"
  • Fill in the form (I'd ignore the URL for now but eventually it will look like http://market.android.com/search?q=pname:com.example.ExampleApp)
  • Hit "Continue"
  • Click on "Download AdMob Android SDK"
  • Extract it to the disk somewhere and navigate to it from the command line
 C:\java\admob-sdk-android> mvn install:install-file -Dfile=admob-sdk-android.jar -DgroupId=com.admob.android.ads -DartifactId=AdMobAndroid -Dversion=20100331 -Dpackaging=jar
  • Note: I got the version from the top of the Changelog.txt file
  • Click on "Go to Sites/Apps"
  • Under the row for your new app, click on "Manage Settings" (it uses mouse-hover, so if you don't see it move your mouse)
  • Copy the id# from "Publisher ID: a14bfed196e8994"
AdWhirl
  • Create an account at AdWhirl.  AdWhirl will act as aggregator, allowing you to mix-n-match ad hosting accounts (like AdMob).
  • Under "Apps" click on "Add Application"
  • Fill out the form. Make sure to choose 'Android'.  Click "Add App"
  • Note: At this point, I have seen an issue where it shows up on the screen twice. If I go into it and come back it resolves itself.  Don't worry about it.
  • Click on your new app's name
  • Copy your SDK key from: "SDK Key:d34d05761f0544dab08b396807778d23"
  • Next to AdMob, click on (mouse-hover again) "Edit Settings"
  • Put the id# from above into the "PublisherID" box and apply it
  • Under "Ad Serving" make sure AdMob is enabled
  • Save Changes
  • Download the latest Android zip from here. In this case, it is "AdWhirlSDK_Android_2.0.8.zip".
  • Extract it to the disk somewhere and navigate to it from the command line
C:\java\AdWhirlSDK_Android_2.0.8> mvn install:install-file -Dfile=AdWhirlSDK_Android_2.0.8.jar -DgroupId=com.adwhirl -DartifactId=AdWhirlSDKAndroid -Dversion=2.0.8 -Dpackaging=jar
  • Note: I took the version from the filename 
Your Code

Whew!  Ok, with your accounts setup, let's create a basic project:

F:\work>  mvn archetype:generate -DarchetypeCatalog=http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml

choose the galatea-archetype plugin
groupId: org.eoti.android
artifactId: AdWhirlTest
version: 1.0-SNAPSHOT

Assuming you have your emulator running...

F:\work>  cd AdWhirlTest
F:\work\AdWhirlTest>  mvn clean install


Add these dependencies to your pom.xml [change versions to match what you did earlier]:
        <dependency>
          <groupId>com.adwhirl</groupId>
          <artifactId>AdWhirlSDKAndroid</artifactId>
          <version>2.0.8</version>
        </dependency>
        <dependency>
          <groupId>com.admob.android.ads</groupId>
          <artifactId>AdMobAndroid</artifactId>
          <version>20100331</version>
        </dependency>



Add this to your AndroidManifest.xml:  

        <uses-permission android:name="android.permission.INTERNET" />
       
Inside your src\main\android\res\layout\main.xml, insert this just above the bottom '</LinearLayout> '
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="bottom"
        android:id="@+id/layout_ad"
    />
   
   
Open your activity (src\main\java\org\eoti\android\AdWhirlTestActivity.java in my case)
Add this into the bottom of your onCreate method:
        try{
            AdManager.setTestDevices( new String[] { AdManager.TEST_EMULATOR } );
            LinearLayout layout = (LinearLayout)findViewById(R.id.layout_ad);
            AdWhirlLayout adWhirlLayout = new AdWhirlLayout(this, "d34d05761f0544dab08b396807778d23");
            Display d = this.getWindowManager().getDefaultDisplay();
            RelativeLayout.LayoutParams adWhirlLayoutParams = new RelativeLayout.LayoutParams(d.getWidth(), 72);
            layout.addView(adWhirlLayout, adWhirlLayoutParams);
        }catch(Exception e){
            Log.e(TAG, "Unable to create AdWhirlLayout", e);
        }
Note: Make sure to use the SDK Key from the AdWhirl setup earlier when creating the AdWhirlLayout.

Redeploy (mvn clean install) and launch it.  You should see an ad at the bottom of the screen.  If not, check your logs (you do have 'adb logcat' running, right?)