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!

Top 10 Techie things I want to achieve in 2012

I’m not the type of person that gets bored easily, I’ve always got many things to keep me amused, mostly side projects at home. I’m a firm believer, that if you don’t set yourself goals in the first place, then you won’t have anything to fail to achieve, so I’ve set myself a list of targets that I’d like to achieve in 2012 knowing full well I probably won’t get around to them all, but if I can do at least 3, it was worth it.

SCJP

I first picked up the SCJP study guide sometime around 2008, and I’ve had a love-hate relationship ever since. It’s by no means a trivial read, in fact, over 800 pages of solid technical details, a fair chunk of which I’ve never actually used, and probably never will once I’ve got through the exam. Reading the book is not enough to get through the exam, you also need to spend countless hours writing small code snippets to back up understanding, and spend plenty of time in mock exam simulators to prepare yourself. I have a terrible habit of getting obsessively involved in studying for a few weeks, before something pops up (working extra hours on a recent project at work is one good example) and I’ll not touch the book for weeks, only to have to re-cover the chapter where I last left off. This is definitely my goal for 2012, if I achieve nothing else but this, I’d be contempt.

Update AndroidSam

I put my first android app out on the market earlier this year, since its release I’ve had some fantastic feedback, amassing well over 15,000 downloads in the first 6 months alone. The app was very much an experimentation, and I certainly cut a few corners in the UI department prior to launch. I’ve been working on a few look and feel improvements, and a few other tweaks that I’d like to get out there soon.

Become more active on JR and SO, and java black belt

This is a must, theres no end goal and its more of an ongoing task that I must do. StackOverflow is a technical Q&A site, I’ve mostly become involved on the questions asking side, but the site has almost doubled in size in recent years so now there are plenty of unanswered questions that I can sneak in answers to, so I’ll have to start sweeping through my tags and get answering. JavaRanch is also a great site, I read this daily, however I rarely leave any posts. I’m planning to get more active and try to chip in with my comments more often. JavaBlackBelt is yet another great site, I was invited to be a beta question creator on the android exam but I just didn’t get round to providing any content, perhaps I can get more involved in 2012.

Complete SCJP study write ups

I found that a good way to help remember topics when studying, was to try and blog about them. I took the index of the SCJP study guide and outlined all the topics, and then gradually made my way through them all blogging about them in my own words. When trying to explain something, you often realise how you know (or sometimes how well you don’t know a particular subject). I’m about halfway through, and I’d really like to complete the blog posts, and get as much of my sample code up onto my Github account so it can help others.

Read, digest, and blog about technical books

Books, I’ve got a whole shelf of books that need some time. The main 3 that I’m interested in reading in 2012 are Effective Java, Clean Code, and Pragmatic Programmers Guide.

Effective Java is basically a compilation of tips and tricks that a Java developer should use if at all possible, Clean Code tells you how you should be writing your code and approaching problems, and the Pragmatic Programmers Guide is just more theory to lay on top. They’re not trivial reads, and some of it may possibly be too advanced for me, but if I can take anything away from it, it should help my progression.

Finish off my other android projects

I’ve been using Evernote to brain dump app ideas, its a handy little tool. Sometimes you get ideas spring into mind at the most awkward of moments, but most of the time I have my phone to hand, so I just tap them into evernote and let my ideas develop. Right now, in my cooking pot of ideas, I’ve got about 6 apps that I feel are worth putting to code, most are utlitlies but I have a few heavyweight ideas in there. Hopefully I can progress these throughout the year and get at least a few out to market.

Explore Spring Web MVC

The first company that I worked at solely produced Java web applications, that was where I got my first taste for the likes of Struts, Stripes, and a little bit of Spring MVC. I particularly liked working with the Stripes MVC framework, but it did lack a lot of community support, I’d like to explore a little with Spring MVC, since it’s always handy to know how to use the basics of Spring anyway. I started writing my own sales tracking system on Google App Engine, perhaps I’ll do something similar with Spring MVC and host it in the cloud somewhere.

Complete a cloud based CI environment

I’ve got various little side projects on the go, sometimes I use my windows PC at home to work on them, sometimes my works laptop, or my linux machine, so it can be a bit of a pain managing source code and builds. Fortunately I discovered something called Unfuddle, an online SVN repository where I could check my code into. I’ve also discovered something called CloudBees, which is a free on-line Jenkins installation, I’m planning to use that to build all my projects in the cloud, and dump artefacts onto DropBox. I may look at maven repositories too. Ultimately, I want to get my build processes in the cloud, so its purely coding that happens outside the cloud.

Ubuntu Certification

OK so one certification in the year is optomistic, but what about two? I’ve been an on-off linux user since I was in college, only really dipping back into Windows when I go through phases of gaming (WINE is just too much effort). Being competent with the shell terminal is going to help in the long run, so why not dedicate some time to skilling up in something useful. I’m not sure if I’d specifically go for the UCP, but it seemed an obvious choice since I have some familiarity with Ubuntu.

Explore Android ICS

With the latest Ice Cream Sandwich android released, theres plenty to be experimenting with, even if theres only a handful of devices that support it. I imagine that ICS will become more and more supported as the year goes on, so its probably time for me to devote some hours into picking up the new features of the SDK, and coming up with something nice. I’m also desperately in need of upgrading my 2.1 Orange San Francisco sub £100 handset, so possibly an excuse for a nice new shiny upgrade?

Revisit GAE Sales Tracker

About 2 years back I began working on an open source sales tracking system, to monitor progression of sales prospects. I started this in Stripes MVC framework and deployed to the Google App Engine. At the time GAE was still in its infinacy, but after a few years and several upgrades, I think developing on this platform may be slightly less painful now. I still have all the source code, and still have a running demo, maybe I can pick it up again and see what GAE improvements have come around.

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!

Android; A really easy tutorial on how to use Text To Speech (TTS) and how you can enter text and have it spoken

Hello readers, time for another little android post of mine. I’ve been working hard recently on some voice recognition and TTS work, so figured I’d post up some tutorials for people to see how easy it is. This is also my first post where I host content on Github so please bear with me!

TTS is actually incredibly easy, take a look at this first example activity :


/**
 * Author : James Elsey
 * Date : 26/Feb/2011
 * Title : TextToSpeechDemo
 * URL : Http://www.JamesElsey.co.uk
 */
package com.jameselsey.demo.texttospeechdemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;

/**
 * This class demonstrates checking for a TTS engine, and if one is
 * available it will spit out some speak.
 */
public class Main extends Activity implements TextToSpeech.OnInitListener
{
    private TextToSpeech mTts;
    // This code can be any value you want, its just a checksum.
    private static final int MY_DATA_CHECK_CODE = 1234;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Fire off an intent to check if a TTS engine is installed
        Intent checkIntent = new Intent();
        checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);

    }

    /**
     * Executed when a new TTS is instantiated. Some static text is spoken via TTS here.
     * @param i
     */
    public void onInit(int i)
    {
        mTts.speak("Hello folks, welcome to my little demo on Text To Speech.",
                TextToSpeech.QUEUE_FLUSH,  // Drop all pending entries in the playback queue.
                null);
    }


    /**
     * This is the callback from the TTS engine check, if a TTS is installed we
     * create a new TTS instance (which in turn calls onInit), if not then we will
     * create an intent to go off and install a TTS engine
     * @param requestCode int Request code returned from the check for TTS engine.
     * @param resultCode int Result code returned from the check for TTS engine.
     * @param data Intent Intent returned from the TTS check.
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if (requestCode == MY_DATA_CHECK_CODE)
        {
            if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS)
            {
                // success, create the TTS instance
                mTts = new TextToSpeech(this, this);
            }
            else
            {
                // missing data, install it
                Intent installIntent = new Intent();
                installIntent.setAction(
                        TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(installIntent);
            }
        }
    }

    /**
     * Be kind, once you've finished with the TTS engine, shut it down so other
     * applications can use it without us interfering with it :)
     */
    @Override
    public void onDestroy()
    {
        // Don't forget to shutdown!
        if (mTts != null)
        {
            mTts.stop();
            mTts.shutdown();
        }
        super.onDestroy();
    }
}

Its really simple, what we do in the onCreate method is to fire off an intent to check if there is a valid TTS engine installed on the device. Think of it this way, if the device doesn’t have an engine which it can use for converting text to speech, how can this work? We use this check to see if we need to direct the user to download one.

The callback on this check is the onActivityResult, which will be invoked after the check has complete. In this method we first check the MY_DATA_CHECK_CODE, this value can be anything you like, I’ve just chosen 1234. This is basically a checksum to check that the intent we receive in the onActivityResult is the one we’re expecting.

After that we check the result code, if it is CHECK_VOICE_DATA_PASS that means there is a valid TTS engine available, so we can create a TextToSpeech instance. If we don’t get a CHECK_VOICE_DATA_PASS then we assume there is either no TTS engine, or the one we have doesn’t work properly, so we create another intent that directs the user off to install one.

If the above was a success, then by creating a new TextToSpeech object we’ll invoke the onInit method, this is quite simple all it does is call the speak method on the TextToSpeech object and passes it a static String to speak.

The QUEUE_FLUSH is a nifty little feature which flushes out anything else the engine is trying to speak.

Checkout the branch I’ve created on Github, you can download the complete source code for this and have a play.

Thats all nice and dandy, but having a static String to be spoken is a little boring, lets have a look at how we can modify this so that you can have a text box, type in some text and hit a button to have it spoken. Have a look at the following Activity, its similar to the above yet improved to do dynamic speech.

/**
* Author : James Elsey
* Date : 26/Feb/2011
* Title : TextToSpeechDemo
* URL : Http://www.JamesElsey.co.uk
*/
package com.jameselsey.demo.texttospeechdemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.view.View;
import android.widget.EditText;

/**
* This class demonstrates checking for a TTS engine, and if one is
* available it will spit out some speak based on what is in the
* text field.
*/
public class Main extends Activity implements TextToSpeech.OnInitListener
{
private TextToSpeech mTts;
// This code can be any value you want, its just a checksum.
private static final int MY_DATA_CHECK_CODE = 1234;

/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Fire off an intent to check if a TTS engine is installed
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);

}

/**
* This method is bound to the speak button so is invoked anytime that is clicked.
* @param v View default view.
*/
public void speakClicked(View v)
{
// grab the contents of the text box.
EditText editText = (EditText) findViewById(R.id.inputText);

mTts.speak(editText.getText().toString(),
TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue.
null);
}
/**
* Executed when a new TTS is instantiated. We don’t do anything here since
* our speech is now determine by the button click
* @param i
*/
public void onInit(int i)
{

}

/**
* This is the callback from the TTS engine check, if a TTS is installed we
* create a new TTS instance (which in turn calls onInit), if not then we will
* create an intent to go off and install a TTS engine
* @param requestCode int Request code returned from the check for TTS engine.
* @param resultCode int Result code returned from the check for TTS engine.
* @param data Intent Intent returned from the TTS check.
*/
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == MY_DATA_CHECK_CODE)
{
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS)
{
// success, create the TTS instance
mTts = new TextToSpeech(this, this);
}
else
{
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(
TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
}

/**
* Be kind, once you’ve finished with the TTS engine, shut it down so other
* applications can use it without us interfering with it :)
*/
@Override
public void onDestroy()
{
// Don’t forget to shutdown!
if (mTts != null)
{
mTts.stop();
mTts.shutdown();
}
super.onDestroy();
}
}

The main changes here is removing the code from the onInit method, we do this because when we create the TTS object we don’t actually know at that point what text we want spoken, so we leave it blank.

Another change is the introduction of the speakClicked method, there is a button which is bound to this method, so when that button is clicked this method is invoked (I wrote another tutorial on that, please check it out).

So when the button is clicked, we’ll take whatever text is in the EditText and have that spoken, simple as that!

I’ve put all this in a separate branch on my Github so feel free to check it out.

Lastly, don’t forget to stop and shutdown the TTS object when you’re done, you don’t want it causing issues for other applicaitons that may want to use the TTS engine.

Further reading

Monetizing your Android apps with AdMob (AdSense), an easy guide

Howdy folks, another nice and easy android guide here. If you’re like me you’re thinking about putting your first application up on the market. It might be a good idea to set-up some ads on application, hopefully making a few pennies as you go.

Its actually quite easy, if your familiar with AdSense for web sites it’ll be even more easier.

First thing you need to do, is head over to AdMob and create an account, should only take you a couple of minutes.

Once thats all setup, login and go to the “add sites” link and create an android site. You’ll be asked for some details on your app, if you don’t actually have it loaded into the marketplace yet, then just enter some dummy values since you can always modify these later.

On the next screen you should find a link to download the SDK, this is where we get started!

Download the SDK, and take the file “admob-sdk-android.jar” and put it into the libs/ directory of your application. You’ll also need to configure your IDE to put this onto the build path in order for it to be recognised.

Next we’ll need to configure our application to use the AdMob library, open up your AndroidManifest.xml file and add the following before the closing application tag.

<!-- The application's publisher ID assigned by AdMob -->
<meta-data android:value="YOUR_ID_HERE" android:name="ADMOB_PUBLISHER_ID" />
        
<!-- AdMobActivity definition -->
<activity android:name="com.admob.android.ads.AdMobActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation|keyboard|keyboardHidden" />
<!-- Track Market installs -->          
<receiver android:name="com.admob.android.ads.analytics.InstallReceiver"
android:exported="true">
<intent-filter>
   <action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>

You’ll need to replace YOUR_ID_HERE with your publisher ID. Thats easy to find, login to your AdMob account, click on Sites, then manage the settings on your application, you’ll see the code at the top of the page.

Also, make sure that your application has permissions to the internet, if it can’t access the web, how can it fetch ads?

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

Next, if you don’t already have a file called res/values/attrs.xml, then create one with the following content. If you do already have that file, then work in the following

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="com.admob.android.ads.AdView">
<attr name="backgroundColor" format="color" />
<attr name="primaryTextColor" format="color" />
<attr name="secondaryTextColor" format="color" />
<attr name="keywords" format="string" />
<attr name="refreshInterval" format="integer" />
</declare-styleable>
</resources>

Now thats all done, lets think about actually inserting some ads into your application. I’ve added the following as the last element in my LinearLayout in my res/layout/main.xml file, which means the adds will sit along the bottom like a footer

     <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"/>

It will probably show up in red text in your IDE, it does in mine, but it still compiles fine so its nothing to worry about.

Be sure to add the “myapp” namespace into the LinearLayout, it must point to your package, such as :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:myapp="http://schemas.android.com/apk/res/com.jameselsey.LanguageSelection"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

Thats it, build your APK and deploy it to a device and you’ll see your ads. Sometimes it will take ~10 seconds for the ad to display, I believe this is due to the app having to make a connection to AdMob to retrieve a suitable ad.

If you want to set some test ads, then add the following snippet into the onCreate method in your activity (the one that uses the view where we declared the AdView)

 AdManager.setTestDevices(new String[]{
                AdManager.TEST_EMULATOR, // Android emulator
                "CF95DC53F383F9A836FD749F3EF439CD",
        });

The long horrible code is my device code, in order to find out what it is for your device, run the application with the following code in, and then look at LogCat, it should have the following line telling you what your device code is :

02-26 21:51:11.695: INFO/AdMobSDK(7591): To get test ads on this device use AdManager.setTestDevices( new String[] { "CF95DC53F383F9A836FD749F3EF439CD" } )

Using this test mode, it ensures that an ad is always placed in your app, and you don’t have to worry about internet connections and such, its essentially a placeholder.

Thats it, I hope I’ve helped you get setup and ready to earn a few pennies, please leave me a comment to let me know how you get on!

Further Reading