ArrowKeys.java

/**
 * Copyright (c) 2013 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */

package com.nokia.example;

import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.sensor.ChannelInfo;
import javax.microedition.sensor.Data;
import javax.microedition.sensor.DataListener;
import javax.microedition.sensor.SensorInfo;
import javax.microedition.sensor.SensorConnection;
import javax.microedition.sensor.SensorManager;

public class ArrowKeys extends MIDlet implements CommandListener, DataListener {
	private static final int BUFFER_SIZE = 1;
	private static final boolean IS_TRIGGERING_EVENT_ALWAYS = false;
	private static int exEvent = -1;
	private static Command exitCommand = new Command("Exit", Command.EXIT, 1);
	private SensorConnection sensor;
	private Form form;
	private ImageItem imageItem;
	private final String UP = "/Up.png";
	private final String DOWN = "/Down.png";
	private final String LEFT = "/Left.png";
	private final String RIGHT = "/Right.png";

	public ArrowKeys() {
		form = new Form("ArrowKeys - Direction");
		form.addCommand(exitCommand);
		form.setCommandListener(this);
		imageItem = new ImageItem("", null, Item.LAYOUT_DEFAULT, "");
		imageItem.setLayout(Item.LAYOUT_EXPAND | Item.LAYOUT_CENTER);
		form.append(imageItem);
		Display.getDisplay(this).setCurrent(form);
	}

	public void startApp() {
		sensor = openSensor();
		if (sensor == null)
			return;
		sensor.setDataListener(this, BUFFER_SIZE);
	}

	public void destroyApp(boolean par) {

		try {
			if (sensor != null) {
				sensor.removeDataListener();
				sensor.close();
			}
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}

	public void pauseApp() {
	}

	private SensorConnection openSensor() {
		SensorInfo infos[] = SensorManager.findSensors("acceleration", null);
		if (infos.length == 0)
			return null;
		try {
			return (SensorConnection) Connector.open(infos[0].getUrl());
		} catch (Exception se) {
            form.append("Exception:\n " + se.getMessage());
			return null;
		}
	}

	public void commandAction(Command command, Displayable screen) {
		// exit command
		if (command == exitCommand) {
			setStopped(true);
			destroyApp(false);
			notifyDestroyed();
		}
	}

	private synchronized void setStopped(boolean isStopped) {
		notify();
	}

	/**
	 * The method returns an action event (UP,DOWN,LEFT,RIGHT) that corresponds
	 * to the given axis x and y accelerations.
	 * 
	 * @param axis_x
	 * @param axis_y
	 * @return the corresponding action key
	 */
	private static int getActionKey(double axis_x, double axis_y) {
		// axis_x: LEFT or RIGHT
		if (Math.abs(axis_x) > Math.abs(axis_y)) {
			return axis_x < 0 ? Canvas.RIGHT : Canvas.LEFT;
		}
		// axis_y: UP or DOWN
		return axis_y < 0 ? Canvas.UP : Canvas.DOWN;
	}

	/**
	 * The method returns action events that corresponds to the given
	 * acceleration data. Valid return values are: 
	 * Canvas.UP Canvas.DOWN Canvas.RIGHT Canvas.LEFT
	 * 
	 * @param data
	 *            the acceleration data
	 * @return the action event array
	 */

	private static int[] data2actionEvents(Data[] data) {

		ChannelInfo cInfo = data[0].getChannelInfo();
		boolean isInts = cInfo.getDataType() == ChannelInfo.TYPE_INT ? true : false;
		int[] events = new int[BUFFER_SIZE];

		if (isInts) {
			int[][] ints = new int[2][BUFFER_SIZE];
			for (int i = 0; i < 2; i++) {
				ints[i] = data[i].getIntValues();
			}
			for (int i = 0; i < BUFFER_SIZE; i++) {
				events[i] = getActionKey(ints[0][i], ints[1][i]);
			}
			return events;
		}
		double[][] doubles = new double[2][BUFFER_SIZE];
		for (int i = 0; i < 2; i++) {
			doubles[i] = data[i].getDoubleValues();
		}
		for (int i = 0; i < BUFFER_SIZE; i++) {
			events[i] = getActionKey(doubles[0][i], doubles[1][i]);
		}
		return events;
	}

	public void dataReceived(SensorConnection sensor, Data[] d, boolean isDataLost) {
		int[] events = data2actionEvents(d);
		for (int i = 0; i < BUFFER_SIZE; i++) {
			if (events[i] == exEvent && !IS_TRIGGERING_EVENT_ALWAYS)
				continue;

			exEvent = events[i];
			switch (events[i]) {
			case Canvas.UP:
				imageItem.setImage(load(UP));
				break;
			case Canvas.DOWN:
				imageItem.setImage(load(DOWN));
				break;
			case Canvas.LEFT:
				imageItem.setImage(load(LEFT));
				break;
			case Canvas.RIGHT:
				imageItem.setImage(load(RIGHT));
				break;
			default:
			}
		}
	}

	private Image load(String file) {
		Image image = null;
		try {
			image = Image.createImage(file);
		} catch (Exception ioe) {
			System.out.println("Image not found or invalid: " + file);
		}
		return image;
	}

}