Archive for the ‘Android’ Category

10.000+ Downloads

Our Android app City, Country, Caller ID has reached the magic number of 10,000 installations.
Thanks for the numerous suggestions and comments that helped us to improve the app constantly.

ipcas-android-caller-city-downloads

Where does the call come from? City, Country, Caller ID is a free Android app, which displays the city or the country of the caller.

Android Color Picker

This Android tutorial shows a color picker which we developed for our Android App City, Country, Caller ID. The source code can be downloaded as Eclipse project: Android Color Picker.

Here we have, in the first example, a predefined list with colors: android-color-picker

We use a GridView with six columns. Within the rows and columns there is an ImageView defined, which background color will be set using imageView.setBackgroundColor(colorList.get(position));.

The layout of the GridView is defined in res/layout/color_picker.xml.

Look for the colors in ColorPickerAdapter.java, which are placed in an array (for better reading).

// for convenience and better reading, we place the colors in a two dimension array
String colors[][] = { { "822111", "AC2B16", "CC3A21", "E66550", "EFA093", "F6C5BE" },
		{ "A46A21", "CF8933", "EAA041", "FFBC6B", "FFD6A2", "FFE6C7" },
		{ "AA8831", "D5AE49", "F2C960", "FCDA83", "FCE8B3", "FEF1D1" },
		{ "076239", "0B804B", "149E60", "44B984", "89D3B2", "B9E4D0" },
		{ "1A764D", "2A9C68", "3DC789", "68DFA9", "A0EAC9", "C6F3DE" },
		{ "1C4587", "285BAC", "3C78D8", "6D9EEB", "A4C2F4", "C9DAF8" },
		{ "41236D", "653E9B", "8E63CE", "B694E8", "D0BCF1", "E4D7F5" },
		{ "83334C", "B65775", "E07798", "F7A7C0", "FBC8D9", "FCDEE8" },
		{ "000000", "434343", "666666", "999999", "CCCCCC", "EFEFEF" } };

colorList = new ArrayList();

// add the color array to the list
for (int i = 0; i < colors.length; i++) {
	for (int j = 0; j < colors[i].length; j++) {
		colorList.add(Color.parseColor("#" + colors[i][j]));
	}
}

In the next step we will assign the Adapter to the GridView:

GridView gridViewColors = (GridView) findViewById(R.id.gridViewColors);
gridViewColors.setAdapter(new ColorPickerAdapter(getContext()));

The second example shows a Rainbow-Color-Picker where the number of colors is flexible:

Define the rainbow with the following steps::

// FF 00 00 --> FF FF 00
for (red = 255, green = 0, blue = 0; green <= 255; green += step)
    colorList.add(Color.rgb(red, green, blue));

// FF FF 00 --> 00 FF 00
for (red = 255, green = 255, blue = 0; red >= 0; red -= step)
    colorList.add(Color.rgb(red, green, blue));

// 00 FF 00 --> 00 FF FF
for (red = 0, green = 255, blue = 0; blue <= 255; blue += step)
    colorList.add(Color.rgb(red, green, blue));

// 00 FF FF -- > 00 00 FF
for (red = 0, green = 255, blue = 255; green >= 0; green -= step)
    colorList.add(Color.rgb(red, green, blue));

// 00 00 FF --> FF 00 FF
for (red = 0, green = 0, blue = 255; red <= 255; red += step)
    colorList.add(Color.rgb(red, green, blue));

// FF 00 FF -- > FF 00 00
for (red = 255, green = 0, blue = 255; blue >= 0; blue -= 256 / step)
    colorList.add(Color.rgb(red, green, blue));

Layout tipps

Right now the layout is only optimized for hdpi devices. Looking at a ldpi device (small screen) we get the following screen:

We have to adjust the GridView column width in order to have the desired layout on various screens. Creating the file res\values-small\strings.xml and setting the width with colorGridColumnWidth will solve the problem:

Download Eclipse Project Android Color Picker

GlobalTime for Android – always the exact GPS time

GPS Time: GlobalTime for AndroidWith Global Time you always have the exact time at hand.

The time is determined via the GPS time signal from the satellites. GPS satellites have an atomic clock and always deliver the correct time. Unlike the time signal transmitter DCF77 reception is not limited to Central Europe; GPS is available worldwide.
No network connection required to determine the time. That makes Global Time the ideal travel companion and saves high mobile network costs abroad if you do not have an unlimited data plan.

With ipcas always the exact time, on the go with Global Time for Android and for your network with the GPS Time Server ipNTP.

GPS Time Server ipNTP
With ipNTP you can synchronize your computer systems, and network attached devices with the time signal of the global satellite navigation system (GPS).

The Android application Global Time is now available on the Android Market (free of charge).
GlobalTime is available in Android Marketipcas global Time - Android Market QR Code

Global Time Screenshots
ipcas Global Time ScreenShot: Searching for GPS …ipcas Global Time ScreenShot: Received GPS signalipcas Global Time ScreenShot: GPS is disabled

 

Threads in Android Part 2 (updating the UI)

Do we need threads in android? Yes. Especially when you have long running operations like network access. These operations will block the main thread, which runs the user interface (UI), and have the effect that the UI is not able to receive user input. The following example simulates the problem:

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

    textView = (TextView) findViewById(R.id.textView);
    textView.setText("hello World");

    // simulate long running operation
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        Log.e(TAG, "Thread.sleep", e);
    }
}

Encapsulate processes which might take longer in threads. Particularly when the process is started in the lifecycle of the activity (onCreate, onResume, onPause).
Besides that you may receive an “Application Not Responding (ANR) dialog” from android if the activity is not responding.

So we create a thread which prints a message after finishing it’s work:

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

    textView = (TextView) findViewById(R.id.textView);
    textView.setText("hello World");

    thread = new Thread() {
        public void run() {
            try {
                // simulate long running operation
                Thread.sleep(5000);
                textView.setText("new value...");
            } catch (InterruptedException e) {
                Log.e(TAG, "run in thread", e);
            }
        }
    };
    thread.start();
}

All set? Not yet. See how you app beautifully dies with a CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. CalledFromWrongThreadException

Just like in Java or C# an UI object (textView in our case) can only be modified by the thread which created it. Which is in our case the main UI thread (not the new thread).

See also the articel Painless Threading on the android developers page. This tutorial here shows how to update the UI from a thread using a Handler.

A handler instance in an activity is bound to the main UI thread. And is able to update UI objects when receiving notifications from other threads.

Next we subclass the Handler class and override the handleMessage method. msg.obj contains the message from the other thread.

private Handler uiHandler = new UIHandler();

class UIHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        // a message is received; update UI text view
        textView.setText(msg.obj.toString());
        super.handleMessage(msg);
    }
}

Create the message object in the long running thread and pass it to the handler. Use Message.obtain() to take a message from a pool of recycled objects:

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

    textView = (TextView) findViewById(R.id.textView);
    textView.setText("hello World");

    thread = new Thread() {
        public void run() {
            try {
                // simulate long running operation
                Thread.sleep(5000);

                // create message which will be send to handler
                Message msg = Message.obtain(uiHandler);
                msg.obj = "new value...";
                uiHandler.sendMessage(msg);

            } catch (InterruptedException e) {
                Log.e(TAG, "run in thread", e);
            }
        }
    };
    thread.start();
}

The uiHandler object receives the message and prints the content in the UI object.

You have different threads and want to control where the message comes from? Use the msg.what to identify the message:

class UIHandler extends Handler {
    private static final int ID_0 = 0;
    private static final int ID_1 = 1;

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case ID_0:
            // a message is received; update UI text view
            if (msg.obj != null)
                textView.setText(msg.obj.toString());
            break;

        default:
            break;
        }
        super.handleMessage(msg);
    }
}

Change the thread to send a message with the user defined code:

// create message which will be send to handler
Message msg = Message.obtain(uiHandler, UIHandler.ID_0);
msg.obj = "new value...";
uiHandler.sendMessage(msg);

Subversion in Android Projects (using Eclipse)

There is no need to have then bin and gen folder of your android project in the subversion repository. You might as well add then to the ignore list since the content is generated:
bin and gen folder

But what happens if we compile and build the project using eclipse:

.svn folders in bin folder

Eclipse copies the hidden .svn folders from the source directory to the bin folder.

Here is the solution to the problem. Go to the project properties and select Java Build Path. Now add the exclusion pattern **/.svn/ to the source directory:

Java Build Path: exclusion **/.svn/

Cleaning and building the project removes the .svn folders. Notice that the file .classpath has the following new entry: <classpathentry excluding=”**/.svn/” kind=”src” path=”src”/>

Threads in Android Part 1 (infinite loop)

This series shows tips and tricks about using threads in android development. Part 1 describes how to create a thread with an infinite loop. Since we only need the thread while the app is running we must assure that the thread stops when the app is not active.

In this example we create a thread which will execute every n seconds. Look a the following code. We override the onCreate method of the activity and create a thread which will do it’s work and sleep afterward.

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

    thread = new Thread() {
        public void run() {
            while (true) {
                try {
                    // do something here
                    Log.d(TAG, "local Thread sleeping");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Log.e(TAG, "local Thread error", e);
                }
            }
        }
    };
    thread.start();
}

What happens if the app is pausing? For instance another app comes to the foreground. The following screen shot from the debugger shows that the thread is still running while the app is not active: Debugger: thread is still running

So we need to control the thread and stop it in the onPause method.

The solution is taken from the google article Updating the UI from a Timer (http://developer.android.com/resources/articles/timed-ui-updates.html). We instantiate a Handler which allows us to process Runnable objects.

The Handler it is bound to the main UI thread of the activity. By calling handler.postDelayed(this, 1000); the new thread is added to message queue (of the main UI thread) and will be run after 1 second.

private Thread thread;
private Handler handler = new Handler();

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	
	thread = new Thread() {
		public void run() {
			// do something here
			Log.d(TAG, "local Thread sleeping");
			handler.postDelayed(this, 1000);
		}
	};
}

The rest is easy. We start the thread in the onResume, which is called after onCreate and when the activity comes to the foreground, by calling handler.postDelayed(thread, 0); (parameter 0 shows that there is no delay).

Before adding the thread to the handler we may remove it, to make sure it is not already bound to the handler. onPause does the same:

@Override
protected void onResume() {
	super.onResume();
	
	handler.removeCallbacks(thread);
	handler.postDelayed(thread, 0);
	Log.d(TAG, "onResume");
}

@Override
protected void onPause() {
	super.onPause();

	handler.removeCallbacks(thread);
	Log.d(TAG, "onPause");
}

Looking at the debugger we notice that the thread stopped after pausing the activity: Threads in Android - onResume / onPause