Using animations in your Android applications can help create an interesting and engaging experience for your users. They can be used in games and applications in a number of ways either as a visual treat or as a method to convey information. Fortunately Android has an animation framework that allows you to easily translate, rotate, scale and alter the alpha of (or a combination) a View. Common transitions like fade in/out or slide in from off screen are examples of animations the framework can produce. Animations and Interpolators The process of animating a View makes use of two classes the Animation and Interpolator classes. The Animation class describes various aspects of the animation such as the transformation (changes in position, alpha, etc) and the duration of the animation. The Interpolator class describes the rate of change of the animation, for example a ScaleAnimation with an AccelerateIterpolator results in a View that scales slowly at first and speeds up until the end of the animation. There are a number of different interpolators the most basic LinearInterpolator to more complex ones such as AccelerateInterpolator, AccelerateDecelerateInterpolter and OvershootInterpolator. Adding Animation to a View Here is res/layout/main.xml, it contains a button called ‘butt’ that is centred in the screen.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">

	<Button android:id="@+id/butt" android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_centerInParent="true" android:text="Shake!"/>

</RelativeLayout>
Now we define our animation, res/anim/exampe_anim.xml , which is going to slide the button in from the bottom of the screen to the centre of the screen scaling from 0.5 to 1 as it travels all in 1.5 seconds. The p in 50%p means parent, since the Button is a primary child of the RelativeLayout this means 50% of the screen height.
<?xml version="1.0" encoding="utf-8"?>

	<set xmlns:android="http://schemas.android.com/apk/res/android"
	android:interpolator="@android:anim/decelerate_interpolator" android:shareInterpolator="true">

		<translate android:fromYDelta="50%p" android:toYDelta="0" android:duration="1500" />

		<scale android:fromYScale="0.5" android:toYScale="1" android:fromXScale="0.5"
		android:toXScale="1" android:duration="1500" />

</set>
To start the animation use AnimationUtils.loadAnimation(context, resID) to load the animation and the startAnimation(animation) method of the View class.
butt.startAnimation(AnimationUtils.loadAnimation(getBaseContext(), R.anim.example_anim));
Read more: Creating Custom Animations

Android GPS Example

April 11th, 2010

For some reason there doesn’t seem to be a clear example showing how to use GPS on Android. Here is some code I have written that listens for location changes and displays the data in a TextView. The example also shows how to open the GPS setting with code via an Intent, since sometimes the GPS will be turned off by the user. Code
package uk.co.hejp.GPSExample;

import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends Activity implements LocationListener {

	/* this class implements LocationListener, which listens for both
	 * changes in the location of the device and changes in the status
	 * of the GPS system.
	 * */
	
	static final String tag = "Main"; // for Log
	
	TextView txtInfo;
	LocationManager lm; 
	StringBuilder sb;
	int noOfFixes = 0;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		/* get TextView to display the GPS data */
		txtInfo = (TextView) findViewById(R.id.textInfo);
		
		/* the location manager is the most vital part it allows access 
		 * to location and GPS status services */
		lm = (LocationManager) getSystemService(LOCATION_SERVICE);
	}
	
	@Override
	protected void onResume() {
		/*
		 * onResume is is always called after onStart, even if the app hasn't been
		 * paused
		 * 
		 * add location listener and request updates every 1000ms or 10m
		 */
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10f, this);
		super.onResume();
	}
	
	@Override
	protected void onPause() {
		/* GPS, as it turns out, consumes battery like crazy */
		lm.removeUpdates(this);
		super.onPause();
	}

	@Override
	public void onLocationChanged(Location location) {
		Log.v(tag, "Location Changed");

		sb = new StringBuilder(512);
		
		noOfFixes++;

		/* display some of the data in the TextView */

		sb.append("No. of Fixes: ");
		sb.append(noOfFixes);
		sb.append('\n');
		sb.append('\n');

		sb.append("Londitude: ");
		sb.append(location.getLongitude());
		sb.append('\n');

		sb.append("Latitude: ");
		sb.append(location.getLatitude());
		sb.append('\n');

		sb.append("Altitiude: ");
		sb.append(location.getAltitude());
		sb.append('\n');

		sb.append("Accuracy: ");
		sb.append(location.getAccuracy());
		sb.append('\n');

		sb.append("Timestamp: ");
		sb.append(location.getTime());
		sb.append('\n');

		txtInfo.setText(sb.toString());
	}

	@Override
	public void onProviderDisabled(String provider) {
		/* this is called if/when the GPS is disabled in settings */
		Log.v(tag, "Disabled");

		/* bring up the GPS settings */
		Intent intent = new Intent(
				android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
		startActivity(intent);
	}

	@Override
	public void onProviderEnabled(String provider) {
		Log.v(tag, "Enabled");
		Toast.makeText(this, "GPS Enabled", Toast.LENGTH_SHORT).show();

	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		/* This is called when the GPS status alters */
		switch (status) {
		case LocationProvider.OUT_OF_SERVICE:
			Log.v(tag, "Status Changed: Out of Service");
			Toast.makeText(this, "Status Changed: Out of Service",
					Toast.LENGTH_SHORT).show();
			break;
		case LocationProvider.TEMPORARILY_UNAVAILABLE:
			Log.v(tag, "Status Changed: Temporarily Unavailable");
			Toast.makeText(this, "Status Changed: Temporarily Unavailable",
					Toast.LENGTH_SHORT).show();
			break;
		case LocationProvider.AVAILABLE:
			Log.v(tag, "Status Changed: Available");
			Toast.makeText(this, "Status Changed: Available",
					Toast.LENGTH_SHORT).show();
			break;
		}
	}

	@Override
	protected void onStop() {
		/* may as well just finish since saving the state is not important for this toy app */
		finish();
		super.onStop();
	}
}
Permissions Of course the Android framework has security permissions to protect the user. To get the permission to use GPS add a uses-permission tag with attribute android:name set to “android.permission.ACCESS_FINE_LOCATION” to the AndroidManifest.xml document as a direct child of the manifest tag, i.e:
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Notes When testing this code in the emulator, you can send mock fixes by connecting to the emulator using telnet, i.e. ‘telnet localhost 5554′ and typing: geo fix -10.223, 40.549

Playground: HEJP ColourPicker

February 3rd, 2010

Just been messing around with the Robot class, which is designed for automated testing of applications but has other uses. Here I have used it to write an application to get the pixel colour of any pixel on the screen. The GUI consists of a Canvas magnifying the area around the mouse pointer and a text field to display the pixel hex value. How to Use Move the mouse pointer to the pixel you’d like to know the colour of and hit Enter. Source and Jar Source (zip) Jar Notes Regarding the Robot Class getColorPixel is very slow as I found out as soon as using it, the solution is to use createScreenCapture to get the pixels around the mouse pointer then read the colours from the BufferedImage.

Multi-client Icons: Macbook Pro – jasonrm, Server – visualpharm.

Handling multiple clients in Java is relatively easy and painless compared to C for example. This is because Java hides a lot of the complexities of writing your application to make use of multiple threads. Basically all that needs to be written is a class, ClientHandler say, the implements Runnable and handles the client. ClientHandler‘s constructor takes the client Socket as an input, so that it has something to act upon. And, the run() method does whatever needs to be done (i.e. reading and writing to the Socket) and then close()s the Socket. ClientHandler Implementation
package uk.co.hejp.Server;

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;

public class ClientHandler implements Runnable {
	Socket socket;
	PrintStream out;

	ClientHandler(Socket s) {
		socket = s;
	}

	@Override
	public void run() {

		try {
			out = new PrintStream(socket.getOutputStream());
		} catch (IOException e) {
			System.out.println("PrintStream Error");
		}

		out.println("Hello");

		try {
			socket.close();
		} catch (IOException e) {
			System.out.println("Failed to close, oddly...");
		}
	}

}
This particular implementation of ClientHandler just writes ‘Hello’ to the Socket and close()s. And just for completeness here is an implementation of a Server that uses ClientHandler:
package uk.co.hejp.Server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	static ServerSocket socket;
	static int port = 7999;

	public static void main(String[] args) {

		try {
			socket = new ServerSocket(port);
			System.out.println("Bound to port: " + port);
		} catch (IOException e) {
			System.out.println("Cannot bind to port: " + port);
			System.exit(0);
		}

		while (true) {
			try {
				Socket s = socket.accept();
				System.out.println("New Client: "+s.getInetAddress().toString());
				(new Thread(new ClientHandler(s))).start();
			} catch (IOException e) {
				System.out.println("Failed to accept client");
			}
		}

	}
}
To test this Server you can use telnet (telnet 127.0.0.1 7999) or in your favourite browser goto ‘http://localhost:7999/’ the result should be just a line to text ‘Hello’ assuming you have the Server running.