Pages

Thursday 28 April 2011

Regular Expressions in Android

If you are not familiar with regular expressions, then it is well worth spending some time finding out about them. Basically a regular expressions allow you to define a and search for a pattern of text within a string, to pick out an email address for example. Head over to regular-expressions.info and find out more, it may seem overly complicated at first, but you will often find you cannot do without them. There are also plenty of sites for testing patterns against, regexpal.com is a good simple one.

Right, let's get to the code. To handle regular expressions in Android you use the standard Java classes, so if you are familiar with these then there is nothing more to learn. Otherwise, the first thing to do is add the following import references to your class:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

My example method will match a defined pattern in the variable myString. If a match is found then the first match (there may be more than one) is returned for use:

private String findMatch(String myString) {

    String match = "";

    // Pattern to find code
    String pattern = "[0-9]{8}";  // Sequence of 8 digits
    Pattern regEx = Pattern.compile(pattern);

    // Find instance of pattern matches
    Matcher m = regEx.matcher(myString);
    if (m.find()) {
        match = m.group(0);
    }
    return match;
}

Hopefully this simple guide is enough of an introduction to the basics to get you going. There are many good resources on the web to help you build patterns and also libraries of commonly used patterns, regexlib.com for example. Now you'll be knocking out expressions in no time!

Thursday 21 April 2011

Adding a Menu to your Android app

Adding an Android Menu to your app that opens when the hardware menu button is pressed

This is very simple so we'll jump straight into the XML file that defines the menu. Typically menu XML definitions will be kept in a menu folder within the resources folder; res. Create the directory if it is missing and add a new XML file called 'example.xml'.

The following full path should now exists within your project:

  res/menu/example.xml

Open the XML file and paste in XML below. Here we are defining a menu with a single item labelled "Refresh". This item has an icon, but this is not a requirement:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_refresh"
     android:icon="@drawable/ic_menu_refresh"
      android:title="Refresh" />
</menu>

Now open the activity class that you want to include the menu in. Add the following imports at the top of the class:

import android.view.Menu;
  import android.view.MenuInflater;
  import android.view MenuItem;

Two methods are required within your activity class, the first creates the menu options by inflating the xml definition we created:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.example, menu);
        return true;
    }
   
The second method handles the menu item selection. Here I use a case statement to react in response to the ID of the tapped menu item:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_refresh:
            // Refresh something
            return true; 
        default:
            return super.onOptionsItemSelected(item);
        }
    }

Now run your app and hit the menu button and you should see something like this...

Android app with menu

For more detail please refer to the Android Developer Creating Menus guide.

Monday 18 April 2011

Quick Tip: Opening a URI in the web browser

Below is example code to open a web page URI / URL in the web browser:

  String webPageUri = "http://android-elements.blogspot.com/";
  Uri uri = Uri.parse(webPageUri);
  if (uri != null) {
    Intent myIntent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(myIntent);
  }

First we parse the uri string. If we have a non-null value we create a new Intent object set to use ACTION_VIEW with the uri as a parameter. ACTION_VIEW will perform the appropriate action for the contents of the provided uri. Then we call a method to start the new activity with this intent object.

Finally, we must ensure the app has internet access to call a web page (see my list of common Android pitfalls) so add the following permission to the manifest:

<uses-permission android:name="android.permission.INTERNET" />


Review the Android Developers site for more on intents and my Android Building Blocks guide for getting started.

Android Versions

Android Platform Versions, API Levels and Names

Each Android platform release or update is given an incremental API version and also the name of a dessert, to make discussions on the subject easier to swallow (ho ho). The dessert names run in alphabetical order and are always hotly speculated prior to release.

The table below lists the Android versions with their API level and also dessert name. The list strikes-through versions that were not released or are declared obsolete:

Platform Version   API Level    Name
1.01
1.12
1.53Cupcake
1.64Donut
2.05
2.0.16
2.17Eclair
2.28Froyo
2.39Gingerbread
2.3.310Gingerbread
3.011Honeycomb
3.112Honeycomb
3.213Honeycomb
4.014Ice Cream Sandwich
4.015Ice Cream Sandwich
4.113Jelly Bean

It is always worth keeping and eye on the latest Android Platform Versions statistics provided by Google.

How do I find the Android platform version my app is running on?

In your app you can test for the version of Android that is running with the following code:

if(android.os.Build.VERSION.SDK_INT < 8) {
    // Do something for versions less than 2.2
}

Thursday 14 April 2011

First Steps (5) Common pitfalls

Common pitfalls and how to avoid them.
Below I have listed the pitfalls that have caught me out most often since starting in Android development. Hopefully this short checklist of rules will help you quickly skip over basic problems...


Rule 1: CHECK THE MANIFEST!
Yes I did shout that. In the early days this caught me out countless times and still from time-to-time now. The Android manifest file is the code of your app and holds it all together. Activities must be listed in the manifest as well as the permissions you app requires.

When you add a new activity to your project you'll need to add an activity entry to the manifest. Refactor or rename an activity and your code will be nicely updated, but not your manifest. It's easy to fix, but you'll just kick yourself each time it happens, mostly because the project will happily build and it won't show itself until you get a nasty force close.


In addition you may be adding code that requires a permission. The most common is probably internet access. If you forget to add this permission to the manifest then you will see "Permission Denied" errors. If you're doing something like hitting a web service it can sometimes take a few moments to sink in where the permission problem lies and you'll kick yourself again!

Rule 2: Keep it Clean
Resource file changes are not available within your code immediately, you must clean up your project to refresh the references. For example, if you add a value to your res/values/string.xml file call 'bob', initially your code will make R.string.bob as an error. 
To fix this you need to clean which recompiles the resources.
From the Eclipse menu, pick Project > Clean...

This call also remove any lingering errors that are being reported but may have been resolved.

Rule 3: Don't forget your XML header and first node type in your layouts
All of your XML resource files must start with an XML version node (line 1, below) and the first node must contain an Android XML namespace attribute (line 2, below). Your resource file will not compile without these.

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

Rule 4: Look out for Android.R
Sometimes when you paste or reference from another project an 'import' reference to the Andriod.R resources is added to your code. This then means that when you try to reference your own resource with R.something the API looks for a reference in the Android.R namespace and warns you it cannot be found.

Simply remove the 'imports Android.R;' line from your class. Another easy fix, but can be confusing when it happens.

Rule 5: For String comparisons use .equals
When comparing strings, use myString1.equals(myString2) rather than "==" (double equals) as this will avoid comparison problems. Use equalsIgnoreCase for case-insensitive comparisons.


Rule 6: Check for emulator internet access
Sometimes, inexplicably, the network availability is lost on my emulator. Again, this is very easy to miss and can drive you to insanity trying to determine why things have stopped working. Just keep an eye on connection status in the notification area of the emulator to avoid this.
The emulator connection can drop for no reason
Rule 7: View items missing from LinearLayout
If you create a linear layout and find that only the first view (a TextView for example) is showin, it probably means you haven't set the orientation. If the width of the first view is set to fill/match parent and the orientation is not defined then all subsequent views will be rendered off-screen to the right.

<?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"><TextView
      android:text="One"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent">
<!-- You won't see the following view if the orientation is horizontal or not set -->
<TextView
    android:text="Two"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

Rule 8: DON'T PANIC!
Yes, I shouted again. On occasion I have seen my list of errors suddenly go through the roof after only a minor change. This usually boils down to a small XML change (layout, or other resource) that resulted in some invalid mark-up and suddenly your project looks a mess. Take a deep breath, try to think what you've changed and take a look at the first error or so in the list. It may just be that you've missed a quote or an angle bracket.


So, that's my list so far. Any further suggestions are welcomed. I hope it saves someone some of the pain I went through during my first steps.


Tuesday 12 April 2011

First Steps (4) My Second Android Project

Extending a simple Android App to add a new WebView.Introducing: Activity, Intent, Layout, Manifest, WebView, UsesPermission

In this tutorial I will expand on my previous guide to building My First Android Project to add a new screen containing some web content You can continue from the code we had completed at the end of that project, which was a single Activity with a Button that invoked a Toast message. Alternatively you can start a new project and use this guide.

The aim of this second project is to add an additional Activity with a WebView control that displays a web page or HTML content. We will also have a look at the manifest file as we will require permission to access the web. Are you sitting comfortably?...

1. Open your MyAndroidProject project, or create a new project.

2. First we add a class that will be our new Activity. In Eclipse right-click on the project and select New > Class.



3. Complete the following information in the New Java Class form:

Source folder: MyAndroidProject/src
Package: com.androidelements.MyAndroidProject
The package namespace of our project.
Name: Web
The name of our new class.
Superclass: android.app.Activity
We are going to extend the Android Activity class.

Finally, untick the "Inherited abstract methods" tickbox so that we get an empty class definition and click on Finish.



4. The new activity will have been created inheriting from the Android Activity class, but without the onCreate method that is required for an activity. Copy and paste this from your Main.java activity or type in  the following so that the class is as below.

package com.androidelements.MyAndroidProject;

  import android.app.Activity;
  import android.os.Bundle;

  public class Web extends Activity {

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

5. We need this activity to use a new layout, so ensure that the setContentView method is set to use a layout called "web":

    setContentView(R.layout.web);

6. The web layout does not yet exist so we need to create it by on the New Android XML File button in the menu:


7 Complete the New Android XML File wizard with the following information:

Project: MyAndroidProject
File: web.xml
What type of resource configuration would you like?: Layout
Folder: /res/layout
Select the root element for the XML file: LinearLayout

Click on the Finish button.


8. The web.xml will now be opened in the Graphical Layout view. Switch to the xml view by selecting the tab at the bottom of the screen labelled "web.xml".



9. Within the XML add a WebView. A view always requires a width and height. The values for these are one off fill_parent/match_parent (fill the space), wrap_content (use required space) or a fixed, defined size.

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

    <WebView
      android:id="@+id/web1"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent">
    </WebView>

  </LinearLayout>

Note the id specification, the @ (at) symbol denotes an id, and the + (plus) denotes that it should be added to the resource file (only supported on id declaration).

10. Save your new files and return to the Web.java code. You should see that the content setContentView declaration has a red warning underline under "web" of R.layout.web. This is because the resource file, R, has not been recompiled. To resolve this we need to 'clean' the project:



From the menu bar select Project > Clean...

11. In the Clean dialog, select "Clean projects selected below", tick the MyAndroidProject project, tick "Start a build immediately" and select "Build only the selected projects". Click OK.



After the clean has taken place the warning should be removed and the word "web" will display in italicised blue.

12. Now we want to add some code to set the contents of the web view. Add the following line under the setContentView method:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.web);
       
        WebView web1 = (WebView)findViewById(R.id.web1);             
    }

This line defines a variable of type WebView and assigns it to the view in the layout by specifying the resource id as a parameter to the findviewById method.

13. Initially the words WebView will be underlined red because no reference to these object types exists in this Activity class. Hover your mouse cursor over the WebView keyword and a list of fixes will be displayed. Click on "Import 'WevView' (android.webkit).

This will add the following import reference to the top of your class (alternatively you can type this in yourself):

import android.webkit.WebView;

14. Now add a line to set the web view to display a web page:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.web);
       
        WebView web1 = (WebView)findViewById(R.id.web1);
        web1.loadUrl("http://android-elements.blogspot.com/");
    }

15. Now we need to specify our new Activity and internet permission in the manifest. Open the Android.manifest file from the Package Explorer and switch to the XML view (bottom tab).

16. Add our new lines, the first defining the Activity and the second requesting internet access permission:

<?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.androidelements.MyAndroidProject"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Main"
                  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=".Web" android:label="@string/app_name" />
    </application>
    <uses-sdk android:minSdkVersion="8" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>
17. Open the Main.java file. We are going to change our button click to launch the new Activity. This is done be creating a new Intent object, assigning a class name and then requesting the start of an activity:

package com.androidelements.MyAndroidProject;

  import android.app.Activity;
  import android.content.Intent;
  import android.os.Bundle;
  import android.view.View;
  import android.widget.Toast;

  public class Main extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
   
    public void clicked(View view) {
        Intent myIntent = new Intent();
        myIntent.setClassName("com.androidelements.MyAndroidProject", "com.androidelements.MyAndroidProject.Web");
        startActivity(myIntent);
    }
   
  }

18. Launch the AVD (Android Virtual Device) and run the app. You should see the screen with the single button. Click the button and you should see our new activity, wait a few seconds for the page to load and voila, you have a web page rendered within your app...

Saturday 9 April 2011

First Steps (3) My First Android Project

Here I will run through the steps for creating your first Android project. I assume that you have a fully installed Eclipse with Android SDK environment and you know how to create an AVD (Android Virtual Device).

1.Open Eclipse then select from the top menu; File > New > Other...


2. Select Android Project, which is under the Android folder in the list:

3. Fill in the required project properties:
  • Project name: MyAndroidProject
    Project name within Eclipse and folder name within the workspace.
  • Contents: (leave as defaults)
  • Built Target: Google APIs 2.2
    The target version of the Android SDK. Generally I target the most common Android version running. (currently 2.2)
  • Application name: MyAndroidProject
    The name of the app which displayed to the user and below the icon on the device.
  • Package name: com.androidelements.MyAndroidProject
    The namespace of your project. The convertion is to have your company name followed by the project name with a three character type prefix (com, meaning company).
  • Create Activity: Main
    The name of the first activity to load.
  • Min SDK Version: 8
    The minimum Android SDK version to support. Using the same as the target version for this example.



4. Click Finish (skipping the Test creation step for this example).

The project is now created and available within Eclipse.

5. Expand the "src" (source) folder, then the package folder and you will see the Main.java activity class. Double-click on this to view the code within Eclipse. You should see the following code

package com.androidelements.MyAndroidProject;

import android.app.Activity;

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

This is our Activity called "Main" which is inheriting from the Activity class. The onCreate method is called when the activity starts. Note that the setContentView method has the parameter R.layout.main.
R is the generated resources file and the reference is to the main.xml file in layout.

5. Expand res - layout then double-click main.xml

You will see a preview of the layout in the Graphical Layout window which will display "Hello World, Main!". Click on the tabe below this which is labelled "main.xml". The XML will now be visible:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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/hello"
    />
</LinearLayout>

This is a 'linear' layout with a single TextView element. A linear layout stacks 'views' elements in the order they are decalred. The text view is a label.

6. We are going to add a button to this layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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/hello"
    />
 <Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Click me"
    android:onClick="clicked"
    />
</LinearLayout>

7. Save and close the XML file to return to the code. We need to add the handler for the clicked event called by the button. This method must take one parameter that contains the reference to the calling View (the button in this case):

    public void clicked(View view) {
        Toast.makeText(this, "Clicked", Toast.LENGTH_SHORT).show();
    }

8. You will require 2 import references at the top of the code to refer to the View and Toast classes.

    import android.view.View;
    import android.widget.Toast;

9. Now we are ready to launch the app. Click on the Android SDK and AVD Manager from the toolbar (or Window menu)

10. Select an AVD (Android Virtual Device) that is configured for the platform and API versions 8 then click on the Start.. button then on the next screen leave the default and click Launch.

11. Now click the "Run As" button (it looks like a standard play button) then select Android Application and click the OK button.


12. Your app should now load within the emulator. Click your "Click me" button and the toast message should appear.



And that is it. Simples.

Friday 8 April 2011

First Steps (2) Android Building Blocks

As a developer with a long background in Microsoft technologies (VB then .NET and C#) moving to Android Java development was initially a bit of a challenge. Not least because I was required to stray from the comforts of my Visual Studio environment.

Having already traversed (or perhaps transcended?!) the bridge I thought I would impart some knowledge that may make the transition easier for others.

Building Blocks

When first creating an app you have to deal with Activities. These are essentially blocks of code that deal with user interaction. Coming from a Windows background it is easy to think of these as your Forms.

The interaction between activities are dealt with by Intents. These are a request for a type of action (start a new activity, launch camera, start an SMS, etc) and can also contain a Bundle which in WinForms terms would be your argument array.

Figure 1: Android Activity and Intent usage
Foundation Block

The thing that binds your project together is the manifest file which resides in the project root and is named AndroidManifest.xml. This defines the requirements, components and permissions of your app.You can think of this as your .NET app/web.config. I will being covering this in details as well as the overall project structure in a separate post.

To Conclude

Once you understand these key terms you have a good starting point for approaching your first "Hello World" project. With the aim of keeping my posts concise I will tie it up there, but please continue to follow the series.

First Steps (2) .NET Developer Moving to Android

This post has been renamed and moved to Android Building Blocks.

Thursday 7 April 2011

First Steps (1) Welcome to Android Elements

Hello and Welcome to Android Elements. The aim of this blog is to assist those who are new to Android development, having already trodden the path myself. Posts will provide concise information and examples whilst pointing out potential pitfalls and problems.

It is now about 6 months since I first decided to have a stab at putting an Android app together after having my HTC Desire for a while. I am a professional developer but mainly on the Microsoft / .NET platform. Even so, the transition to Android, Java and Eclipse was not a smooth one...

Developing for Android

The initial hurdle was the general lack of good information and examples. Google have done an excellent job with their Android Developers site which will probably always be your first stop for information. But it for what is has in detail it lacks in examples.

Also, the nature of mobile development, particularly on the array of Android devices is complicated. Your web development skills will not help you here. Well maybe a tiny bit, but I wanted to sound dramatic.

I would also advise that you should be at the very least familiar with OOP and real-world programming methodologies if you want to start creating apps. This is not BASIC on your BBC Micro (showing my age there). If you're a seasoned Java developer who uses Eclipse on a Linux platform every day, then you have a huge advantage.


The Environment

Your choices for the IDE are the Eclipse or IntelliJ IDEA. Eclipse is by far the more widely used of the two and is also the one used in the Google guides, so this was my choice. However I have heard good things about IntelliJ so intend to check it out soon. I plan to do a whole post on setting up the environment later as there were some steps that I had trouble with even when following the Installing the SDK guide.

The Challenges

The Android platform is evolving rapidly and many of its strengths are also a headache for developers. Take the number of devices for example, great for Android, horrible for testing. Platform updates are also relatively regular with new features being added and old deprecated perhaps twice a year.

When you hit a problem and start searching you will often find examples using different approaches and sometimes raise more questions than answers; should you use the native Android methods?  Are they supported in all versions? Will the Java libraries do a better job? Or perhaps I need a third party library?
You can find a code example that is only year old but is completely out of date. 'Official' examples and best practices often do not exist. For the same reasons a good book only has a very short lifespan. This is very different from the .NET world.

Resources

It seems there are very few decent Android resources on the web. The most reliable have proven to be:
  • Google Developers - First stop for detailed information on objects and classes.
  • StackOverflow - A fantastic resource when you get stuck. Growing and helpful community, but be sure to search before you ask questions.
  • O'Reilly Programming Android - online book which is available for until it goes into publication. It's O'Reilly so expect content of the highest quality.

To keep ahead in the dynamic mobile environment you'll need to keep abreast of changes so you should follow (RSS or Twitter) some or all of the following:


Now it's time to take your first steps. Good luck...