Asserting for a Toast message using Robolectric

I’ve recently put together a few proof of concept applications, and since they’re “rough and ready” applications, a lot of the functionality is actually mocked, or given a stubbed implementation.

For example, I’ve got various buttons for things like “sign in with LinkedIn” or “Connect with Facebook”. Since its just a proof of concept, and those features aren’t really must haves, I stub them with a Toast message saying something along the lines of “feature not yet implemented”.

This gives the user the opinion that the buttons are there, functional, however the actions they take are not yet implemented.

This is fine, however if you have numerous stubbed toast messages across the application, or even real toast messages that you have in production standard code, you’ll want to unit test those to be sure you don’t introduce defects when you’re busy beavering away in other areas of the source code.

Fortunately we can use the Robolectric framework to cover a lot of these unit tests. I won’t go into detail about Robolectric here, so please head over to their site and have a look at the basics before you can understand this post.

The assertion is pretty straight forward, and consists of the following :

@Test
public void assertValidationFailureWithNullInput()
{
	searchEditText.setText(null);
	searchButton.performClick();

	ShadowHandler.idleMainLooper();
	assertThat( ShadowToast.getTextOfLatestToast(), equalTo("Please enter a value."));
}

What I have here, is an EditText that I use for a search button, I set its value to null and then click on it. The purpose of the test is to ensure that submitting “search” with a null input will be caught by my validation, and a toast message prompting the user to enter valid data.

Hope that helps, and if you have any questions please leave a comment :)

A second app to launch; Agile Planning Poker

After launching my first application onto the market back in March 2011, and amassing somewhere in the region of 15,000 downloads since it’s launch, I was eager to produce another.

I offered up my services at my work to develop an application to “test the water”, teaming up with the marketing director we created a simple yet useful application for agile project managers; planning poker decks.

The concept is simple, when an agile team is in an estimation phase, they assess each task and try to estimate how much effort would be involved to complete that task. There are many different approaches to how the estimation can take place, such as grouping tasks into small/medium/large, or even a simple show of hands voting system. Another method is with the use of planning poker cards.

We decided to keep it simple and offer 3 types of estimation, or 3 decks of card in this application; standard, fibonacci, and hours deck, with the following cards :

Standard

  • 0
  • 0.5
  • 1
  • 2
  • 3
  • 5
  • 8
  • 13
  • 20
  • 40
  • 100

Fibonacci

  • 0
  • 1
  • 2
  • 3
  • 5
  • 8
  • 13
  • 21
  • 34
  • 55
  • 89

Hours

  • 0
  • 0.5
  • 1
  • 2
  • 4
  • 8
  • 12
  • 16

In addition to the numbers above, each deck has the following special cards :

  • ? – Played when you genuinely have no idea how long it would take
  • Infinity symbolPlayed when you believe the task would take forever, or at least longer than is feasible
  • Coffee mugPlayed when you’ve just had enough, and need a timeout

The idea is that when estimating tasks, the users would all select the appropriate card, and on call display their selection to the rest of the team. This rules out any obvious biased choices as the users would all select their own cards, and display at the same time ruling out any options for copying the developer next to you.

The idea is to stimulate discussion and justification of the estimates, so if you estimate a task would be 5 days, but Dalibor estimates it’s only a few hours, it opens up a debate and can rule out any obvious misunderstandings or misconceptions about the task itself, or how it could be achieved, eventually resulting in more accurate estimates.

Click here to view/download the application from the market.

If you’re interested in web services, systems integration and other such enterprise technologies, be sure to check out our blog, also have a look at my write up from DroidCon UK 2011, plenty of android goodness lies within.

How to add a splash screen to your android application in under 5 minutes

Adding a splash screen to your application is a quick and easy way to make it look more well rounded, complete, and more professional, it can also serve as a useful distraction whereby you have an extra few seconds to initialise your application components before displaying them to the user.

In this post I’ll show you how to quickly and easily add a splash screen into your application, I’ll also show you how you can create an option whereby users may disable or enable the splash screen for subsequent launches of your application. I’ll also post up my sample code freely on Github so you can checkout what I’ve done and use as you please.

So lets get started right away and create the application, we’ll go ahead and create 3 activities as detailed below, and also shut off the title bar.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.jameselsey.android.demo.androidsplashscreen"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar">
        <activity android:name="SplashActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="MainActivity"
                  android:label="@string/app_name">
        </activity>
        <activity android:name="EditPreferences"
                android:label="@string/app_name">
        </activity>
    </application>
</manifest>

The Splash activity will be the activity that handles the splash screen (Oh, really?!). Since we want to intercept any user launches of the application, we’ll make this the main entry point.

public class SplashActivity extends Activity
{
	// Set the display time, in milliseconds (or extract it out as a configurable parameter)
	private final int SPLASH_DISPLAY_LENGTH = 3000;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.splash);
	}

	@Override
	protected void onResume()
	{
		super.onResume();
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
		// Obtain the sharedPreference, default to true if not available
		boolean isSplashEnabled = sp.getBoolean("isSplashEnabled", true);

		if (isSplashEnabled)
		{
			new Handler().postDelayed(new Runnable()
			{
				@Override
				public void run()
				{
					//Finish the splash activity so it can't be returned to.
					SplashActivity.this.finish();
					// Create an Intent that will start the main activity.
					Intent mainIntent = new Intent(SplashActivity.this, MainActivity.class);
					SplashActivity.this.startActivity(mainIntent);
				}
			}, SPLASH_DISPLAY_LENGTH);
		}
		else
		{
			// if the splash is not enabled, then finish the activity immediately and go to main.
			finish();
			Intent mainIntent = new Intent(SplashActivity.this, MainActivity.class);
			SplashActivity.this.startActivity(mainIntent);
		}
	}
}

In the onCreate we’re initialising the view layout, in my case I’m just referring to the splash view which has just a simple ImageView, but yours could contain anything such as images, text, adverts, possibly even combine it with a ProgressBar.

In the onResume, which is invoked after the create, we’re attempting to retrieve a saved variable, defaulting to true if it is not currently set.

A simple check on that boolean decides whether we should spawn a handler with a pre-defined delay, or finish the activity and move onto the main. In either case, we always want to call finish on the splash activity so that the activity is destroyed safely and the user cannot return back to it, then we create an intent to MainActivity and start it.

Arguably, there is more than one way of achieving this, we could use an AsyncTask, or even just spawn off a raw Thread, but I find the handler approach is much cleaner for this task whereby we can use an anonymous inner class rather than a regular inner class, also we don’t need any of the hooks into the UI which the AsyncTask provides, I deem that slightly overkill for such scenario.

That will pretty much get you a splash screen, now lets improve this a little by letting the user disable if they want.

First task we need to do is allow the use of the “menu” button on the device, by adding an override on onOptionsItemSelected in the MainActivity (or anywhere we want to allow this behaviour)

public class MainActivity extends Activity
{
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.options_menu, menu);
		return true;
	}

	/**
	 * This method will be called any time a user selects one of the options
	 * on the menu. For the implementation, whichever button is clicked is
	 * mapped onto the relevant activity.
	 * @param item MenuItem
	 * @return boolean
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
			case R.id.preferences:
				startActivity(new Intent(this, EditPreferences.class));
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}
}

Of course we also need to create the EditPreferences activity too, which in all fairness, exists purely to load preferences from an XML resource file :

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

	@Override
	protected void onResume()
	{
		super.onResume();
		addPreferencesFromResource(R.xml.preferences);
	}
}

Adding the following shared preference :

<PreferenceScreen
        xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
            android:id="@+id/isSplashEnabled"
            android:key="isSplashEnabled"
            android:title="Splash screen enabled"
            android:summary="Select to enable the splash screen on application startup"
            android:defaultValue="true"/>
</PreferenceScreen>

That is all you need to do! I’ve intentionally left out some of the layout resource files, but you can look them all up on the Github entry I created.

Hope that helps, any comments or suggestions please let me know!

Converting dp to pixels in android

Sometimes in android you have to deal with pixels, which can often be awkward, such as view.setPadding(int, int, int, int).  Obviously this is not ideal as pixel ratings vary from device to device, nonetheless there is a work around for this

Simply come up with the value you want in dip (density independent pixels), such as 10, and then convert into pixels using the display metrics of the device you’re working on. This will ensure that when the conversion runs, it’ll always scale to the device the application is running on.

float sizeInDip = 10f;
int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sizeInDip, getResources().getDisplayMetrics());

Enjoy!

SMS text messaging simulation on android

As part of an application I’m currently developing, I need to be able to interogate incoming SMS messages. Since I’ll be developing against the emulator initially I need a way of sending in SMS messages to the emulator. Fortunately, we can use adb to poke in SMS messages at will, as detailed below.
Ultimately, you’ll need to telnet into your emulator, and you’ll need two things:
  • The port the emulator runs on. To find this out, open up a command window and type :

adb devices

You should see something like this :

C:\development\projects\AndroidSam\trunk_androidsam>adb devices
List of devices attached
emulator-5554 device
So my emulator is running on the default port of 5554.
  • Secondly, if you’re a Windows 7 / Vista user, you probably won’t have telnet enabled by default, so switch that on by going into Control Panel > Programs > Programs and Features > Turn Windows features on or off.

Now, lets actually send in an SMS. From the command window, type :

telnet localhost 5554

sms send 07841123123 Hello this is a sample message
OK

Then have a look at your emulator, you should see the SMS come through.
Stick around, I’ll post up some more SMS related tips in the coming weeks!

How to remove the default grey title bar on android apps

Fed up of the default title bar on your android applications?

We can get rid of that easy, either use the following in your activities to do it :

requestWindowFeature(Window.FEATURE_NO_TITLE);

Or, the way I prefer, disable it application wide by slipping the following into the AndroidManifest.xml file :

android:theme="@android:style/Theme.NoTitleBar"

Automating android application signing and zipaligning with maven

This is something that has had me tearing my hair out for a few days now, I was pretty much border-line braveheart-ing my screen….

Code rage

I’ve recently been on a little drive to try to maven-ize my projects. All had been going well until I needed to sign and zipalign my APKs. This post will help you conquer that barrier with the use of some maven plugins.

When using ant, I was able to simply enter keystore details into build.properties and just call “ant release”. Unfortunately that approach doesn’t carry across to maven, and you have to provide some more configuration.

Firstly, before we go any further, I’m going to assume that you already have a maven android project setup, so you have a pom.xml, you’ve configured the maven-android-plugin and you can run “mvn clean install” to build your APK, and “mvn android:deploy” to deploy it to an emulator. If you haven’t got that far, I’d suggest you have a look at one of my previous posts to help get you up to speed.

So, when you want to build your application with maven, you’d run “mvn install”. That will, by default, use a debug key to sign your APK. When we want to build a releasable APK we still want to execute the same install goal, however we’ll want to use a proper key. Luckily, maven provides something called profiles.

In short, maven profiles allow you to still perform the same standard goals, yet they behave slightly different, in the manner of binding extra steps to them, all will come clearer in a moment.

This has already been covered, in a useful post by the guys at Novoda, and various other blog posts scattered around the web. I’ve followed at least 10 tutorials and each time I was unable to get the signing process to work correctly, each time I encountered the following error :

INFO] jarsigner: attempt to rename C:\android-projects\jameselsey_andsam_branch_mavenbranch\target\LanguageSelection-1.0.0-SNAPSHOT.jar to C:\android-projects\jameselsey_ands
am_branch_mavenbranch\target\LanguageSelection-1.0.0-SNAPSHOT.jar.orig failed
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed executing 'cmd.exe /X /C "C:\development\tools\Java\jdk1.6.0_20\jre\..\bin\jarsigner.exe -verbose -keystore my-release-key.keystore -storepass '*****' -keypass '
*****' C:\android-projects\jameselsey_andsam_branch_mavenbranch\target\LanguageSelection-1.0.0-SNAPSHOT.jar mykeystore"' - exitcode 1
[INFO] ------------------------------------------------------------------------

I’d tried everything, even copying out the command and pasting into a command window worked, but I could not get it to work from maven. Unfortunately it seems there may be an issue with the maven-jarsigner-plugin (as suggested in the comments on the Novoda post). However fear not, for there is an alternative, the maven-jar-plugin.

The maven-jar-plugin is a similar plugin to the jarsigner plugin, however the signing APIs are now deprecated and it points you to use the (apparently) broken maven-jarsigner-plugin. Using a deprecated API doesn’t particulary concern me in this instance, as its just signing artefacts.

Take a look at my profiles section, copy this into your pom.xml :

<profiles>
<profile><!-- release profile. uses keystore defined in keystore.* properties. signs and zipaligns the app to the target folder-->
            <id>release</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <build>
                <defaultGoal>install</defaultGoal>
                <finalName>${project.artifactId}-${project.version}</finalName>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-jar-plugin</artifactId>
                        <version>2.2</version>
                        <executions>
                            <execution>
                                <id>signing</id>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                                <phase>package</phase>
                                <inherited>true</inherited>

                                <configuration>
                                    <keystore>
                                        my-release-key.keystore
                                    </keystore>
                                    <storepass>mypassword</storepass>
                                    <keypass>mypassword</keypass>
                                    <alias>mykeystore</alias>
                                    <verbose>true</verbose>
                                    <verify>true</verify>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>

                    <plugin>
                        <groupId>com.jayway.maven.plugins.android.generation2</groupId>
                        <artifactId>maven-android-plugin</artifactId>
                        <inherited>true</inherited>
                        <configuration>
                            <sign>
                                <debug>false</debug>
                            </sign>
                        </configuration>
                    </plugin>

                    <plugin>
                        <groupId>com.jayway.maven.plugins.android.generation2</groupId>
                        <artifactId>maven-android-plugin</artifactId>
                        <configuration>
                            <zipalign>
                                <verbose>true</verbose>
                                <skip>false</skip>
                                <!-- defaults to true -->
                                <inputApk>${project.build.directory}/${project.artifactId}-${project.version}.apk</inputApk>
                                <outputApk>${project.build.directory}/${project.artifactId}-${project.version}-RELEASE.apk
                                </outputApk>
                            </zipalign>

                        </configuration>
                        <executions>
                            <execution>
                                <id>zipalign</id>
                                <phase>install</phase>
                                <goals>
                                    <goal>zipalign</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
</profiles>

OK, so lets walk through what the above profile does. Firstly, the “id” of the profile is “release”, so when you want to apply this profile, you’d run “mvn install -Prelease”. The “activeByDefault” is set to false, which means you need to use the above arguement, if you flip that over, you won’t need the P flag.

The execution goal is to “sign”, which is the API on the plugin, documented here. We bind this execution on to the standard “package” goal. Then we provide the configuration elements which specify the details of the keystore.

In pure English, this binds the plugin phase onto the package goal of maven, so anytime we run using this profile it’ll execute the jar signing of our artefacts. The “verify” tag gives us extra piece of mind by verifying that the signing was successful afterwards.

I’ve also setup a zipalign profile that will take the APK, zipalign it, and rename it to “*-RELEASE.apk”, so I know that particular APK is the one which I’ll release to market.

So thats it, once more a success, and its just one small step on the ladder to android glory!

Phhew!! Done, finally I was able to shutdown the laptop and go to sleep at 3am….on a school night!!!

Good luck, feel free to comment!

Peace.

How to send an email from your Android application…

If you’re like me, you’ll certainly like to hear feedback on your applications out there on the market, and what better method than via a direct email link.

I usually opt for a “contact me” button, which when clicked will open up the phones email client with a new email ready. The mail-to and subject will already be set so all the user needs to do is to type in their message and send. Lets have a look at setting this up in your application.

First thing you’ll need is the button, so go ahead and add this whereever you want the button :

<Button
                android:layout_height="wrap_content"
                android:layout_width="fill_parent"
                android:text="@string/linkEmail"
                android:onClick="linkEmailClicked"
                android:singleLine="true"/>

Take note of the onClick property, we’ll need that in a moment. Now either create a new activity, or add the following method into an existing activity :

/**
     * This method will be invoked when the user clicks on "email me" link
     * in the About the developer page, which will then spawn an email to
     * me
     * @param v View Default view
     */
    public void linkEmailClicked(View v)
    {
        Intent it = new Intent(Intent.ACTION_SEND);
        String[] tos = {getString(R.string.emailAddress)};
        it.putExtra(Intent.EXTRA_EMAIL, tos);
        it.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.emailSubject));
        it.setType("text/plain");
        startActivity(it);
    }

Notice how the method name matches the onClick property in the XML? That’s how android works out what to invoke when the button is clicked. All the above code samples are from production code, so they should work fine for you!

This is incredibly simple, I don’t need to explain much here, other than storing my email address and email subject in the strings.xml file for ease of configuration.

Further Reading

Publishing your app to the Android Market, a noobs guide…

Hola a todos! Its been a little while since I last posted, mostly because I’ve been busy getting my first app in a state thats good enough to be published, in which I have, and heres a little write up on how easy it is to actually publish.

If you head over to the official documentation, you’ll get inundated with instructions, I’ve already been through the pain of figuring it out, so I’ll regurgitate that in a real easy friendly way. As a quick overview, you’ll need to do the following :

  1. Remove any logging, remove the “debuggable” option in your manifest, set your version numbers
  2. Build your final APK
  3. Sign the APK with a key
  4. Zipalign the APK
  5. Register on the market ($25 fee), fill out the form and publish the app

Sounds a little scary, however, if you follow my super secret-squirrel tips, you can do 2,3 & 4 in one simple ant command, lets have a look at each step now. (But before that, lets have a little Picard humour, its necessary)

Remove any logging, remove the “debuggable” option in your manifest, set your version numbers

Fairly simple step this is, logging is irrelevant for a published app, so it should be removed. Its up to you if you want to actually delete out all the lines which contain Log.logCat();, or just comment them out. I opted for commenting them out, as I have relatively few of them and to be honest, it wasn’t really a big deal since its only me that works on it, so I know whats what.

Next, if you’ve been debugging on a device, you’ll most likely have the android:debuggable option set in your AndroidManifest.xml file, it needs to be removed.

<application android:label="LanguageSelection" android:icon="@drawable/creep_003" android:debuggable="true">
...
</application>

After that, you just need to setup the versioning parameters for your application, in your AndroidManifest.xml file you’ll have the following at the top :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.jameselsey.apps.androidsam"
          android:versionCode="1"
          android:versionName="1.0">
...
</manifest>

Its really up to you what versioning strategy you use, I’ve opted to release my first version as 1.0, and any subsequent patches/bugfixes as minor releases, so 1.1, 1.2 and so on. A full release (i.e., new content) would be 2.0, 3.0 etc. Whatever you choose, make sure you’re consistent.

Thats it with the tweaking of your application, now comes onto getting a release ready.

Build your final APK

Before we come onto farting around with APKs, lets have a little chat about the signing process. Every app that gets installed to an emulator or a device MUST be signed, even if you create a new hello world app and run it on the emulator, its been signed automatically behind your back, without you knowing. When you’re developing, your apps automatically get signed using a debug keystore, which means they will work on the emulator/device OK, however when you come to release your app to the market, you need to provide a proper, genuine 24 carat gold self signed certificate, in other words, a debug key for a live app just won’t cut it.

Creating a key is simple, just create a keystore if you don’t already have one. I decided to put mine in the root of my project structure, use the following command :

C:\development\projects\AndroidSam_trunk>keytool -genkey -v -keystore my-release-key.keystore
Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  James Elsey
What is the name of your organizational unit?
  [Unknown]:  Individual Developer
What is the name of your organization?
  [Unknown]:  None
What is the name of your City or Locality?
  [Unknown]:  Ipswich
What is the name of your State or Province?
  [Unknown]:  Suffolk
What is the two-letter country code for this unit?
  [Unknown]:  UK
Is CN=James Elsey, OU=Individual Developer, O=None, L=Suffolk, ST=Suffolk, C=UK correct?
  [no]:  yes

Generating 1,024 bit DSA key pair and self-signed certificate (SHA1withDSA) with a validity of 90 days
        for: CN=James Elsey, OU=Individual Developer, O=None, L=Suffolk, ST=Suffolk, C=UK
Enter key password for <mykey>
        (RETURN if same as keystore password):
[Storing my-release-key.keystore]

As you can see, it’ll prompt you for some extra info, but otherwise its straightforward.

Now comes the meaty part, tieing all this into our build process.

Sign the APK with a key (part of the build process)

In Eclipse (or preferably, IntelliJ), have a look for the file build.properties. This file will probably all be commented out, but add these two properties to the bottom. Make sure the key store points to where you created the keystore, in my case it was in the root directory.

key.store=./my-release-key.keystore
key.alias=mykeystore

Thats all the configuration you need to do for this part.

Zipalign the APK (after running the build process)

OK, so so far we have created a keystore, and told our build properties where it can find it, lets actually create a build. Since you’ve already got Ant installed (at least I’m assuming you do), its just a case of running the ant release target, such as follows :

C:\development\projects\AndroidSam_trunk>ant release
Buildfile: C:\development\projects\AndroidSam_trunk\build.xml
    [setup] Android SDK Tools Revision 9
    [setup] Project Target: Android 2.1-update1
    [setup] API level: 7
    [setup]
    [setup] ------------------
    [setup] Resolving library dependencies:
    [setup] No library dependencies.
    [setup]
    [setup] ------------------
    [setup]
    [setup]
    [setup] Importing rules file: tools\ant\main_rules.xml

-set-release-mode:
     [echo] *************************************************
     [echo] ****  Android Manifest has debuggable=true   ****
     [echo] **** Doing DEBUG packaging with RELEASE keys ****
     [echo] *************************************************

-release-obfuscation-check:

-dirs:
     [echo] Creating output directories if needed...

-pre-build:

-resource-src:
     [echo] Generating R.java / Manifest.java from the resources...

-aidl:
     [echo] Compiling aidl files into Java classes...

-pre-compile:

compile:
    [javac] C:\development\tools\androidSDK\android-sdk-windows\tools\ant\main_rules.xml:361: warning: 'includeantruntime' was not
set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 1 source file to C:\development\projects\AndroidSam_trunk\bin\classes

-post-compile:

-obfuscate:

-dex:
     [echo] Converting compiled files and external libraries into C:\development\projects\AndroidSam_trunk\bin\classes.dex...

-package-resources:
     [echo] Packaging resources
     [aapt] Creating full resource package...
     [null] Warning: AndroidManifest.xml already defines debuggable (in http://schemas.android.com/apk/res/android); using existing
 value in manifest.

-package-release:
[apkbuilder] Creating AndroidSam-unsigned.apk for release...

-release-prompt-for-password:
    [input] Please enter keystore password (store:./my-release-key.keystore):
<your password here>
    [input] Please enter password for alias 'mykeystore':
<your password here>

-release-nosign:

release:
     [echo] Signing final apk...
  [signjar] Signing JAR: C:\development\projects\AndroidSam_trunk\bin\AndroidSam-unsigned.apk to C:\development\projects\AndroidSam
_trunk\bin\AndroidSam-unaligned.apk as mykeystore
     [echo] Running zip align on final apk...
     [echo] Release Package: C:\development\projects\AndroidSam_trunk\bin\AndroidSam-release.apk

BUILD SUCCESSFUL
Total time: 16 seconds

That’s all you need to do, as you can see, my final (build, signed and aligned) apk is located at C:\development\projects\AndroidSam_trunk\bin\AndroidSam-release.apk, so all I need to do is upload that file into the market place! Easy.

Register on the market ($25 fee), fill out the form and publish the app

OK so we’re at the final hurdle now, one last leap and our app is out there on the interwebz, you’ll need to head over to the android marketplace and register yourself as a developer. There is a one time fee of $25 which you can pay with via your Google checkout account. This all ties into your GMail account so no worries about new accounts and such. There is an extra process you need to go through if you intend to sell your apps, but if you are listing for free, the developer account is sufficient.

Click “Upload Application”, fill out the form, and that is it! You will need to provide a description of your app, some icons, and select which category it should be listed under.

Done, yay! Picard demands that you join him in celebration!

My experiences, tips and advice

Theres a few things I’ve found from publishing my first app, hopefully they help others:

  1. The documentation on Google is overwhelming, they make it seem much harder than it actually is.
  2. Installing Ant and using the ant release target saves any manual signing/aligning and has made my life MUCH easier.
  3. The $25 fee is a bit cheeky, but as a developer you need to constantly up your game, think of it as a future investment into your career.

Further Reading

  1. Google Documentation – Preparing to publish
  2. Android Marketplace Home
  3. Apache Ant
  4. Installing Apache Ant
  5. AndroidSam – My app on the market

How to place your ads at the bottom of your screen in Android

So you’ve setup some ads using AdMob or AdWhirl for your android application, and you’re having a hard time getting the ad to appear at the bottom of your screen? Well fear not, for we have a solution.

What you need to do, is to have a RelativeLayout, and within that, have one LinearLayout for your own views, and another LinearLayout which just contains the ads, and anchor that to the bottom of the screen.

Have a look at my example here :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:androidsam="http://schemas.android.com/apk/res/com.jameselsey"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">
    <LinearLayout android:layout_width="fill_parent"
                  android:id="@+id/home_layout"
                  android:orientation="vertical"
                  android:layout_height="wrap_content">
        <!-- Put all your application views here, such as buttons, textviews, edittexts and so on -->

    </LinearLayout>
    <LinearLayout android:layout_width="fill_parent"
                  android:id="@+id/ad_layout"
                  android:layout_height="wrap_content"
                  android:gravity="bottom"
                  android:layout_alignParentBottom="true"
                  android:layout_alignBottom="@+id/home_layout">
        <com.admob.android.ads.AdView
                android:id="@+id/ad"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="bottom"
                androidsam:backgroundColor="#000000"
                androidsam:primaryTextColor="#FFFFFF"
                androidsam:secondaryTextColor="#CCCCCC"/>
    </LinearLayout>
</RelativeLayout>

Hope this helps!