Aug 282011
 

The Royal Malaysian Police (Selangor state) has released MyDistress – a mobile application for sending personal distress call to Malaysian Police. MyDistress can automatically detect the location of the distress call sender and notify nearby police station of the distress.

To use MyDistress, the user are required to register the application by providing full name, MyKad number and home address. MyDistress is available for iPhone (via iTunes store – Malaysia), Android (marketplace), Blackberry and JavaME (*.jar)

Aug 172011
 

As we all know, the Android is similar to JavaME because both runs on Java platform . However instead of executing the classfiles, Android add the extra step of converting the Java bytecode into alternative instruction set used by (into *.dex) Dalvik Virtual Machine, which makes it unable to run Java classfile (*.jar) normally used by JavaME.

Luckily, some brave soul has provided phoneME implementation for Android, which in turn enable users to execute Java MIDlet in Android. phoneME for Android can be downloaded from its website: http://davy.preuveneers.be/phoneme/?q=node/10#android

phoneme screenshot phoneme screenshot phoneme screenshot

What you need to do is to download phoneME Advanced – Foundation Profile + MIDP or phoneME Advanced – Foundation Profile + MIDP High Resolution (240×320). The midlet manager provided with the distribution requires OpenIntents File Manager, which is used to browse for midlet *.jad or *.jar file.

So far, almost all core MIDP 2.0 functionality is available from the phoneME *.apk. The only incompatibilities arises from midlets that use optional JSR, which usually causes midlet manager to crash.

Aug 132011
 

Previously Geocoding from mobile web (or ‘ordinary’ web application) is achieved through Google Gears (as pre-installed in Android 1.5+). However the W3C Geolocation API Specification has render Google Gears obsolete as newer browsers has these functionality built-in (including mobile browser).

How to include Geolocation API in a Web Page?
The most basic code that you started is listed below, the code below tests if the browser have built-in support for geolocation. If it does have geolocation support, it will call either one of the callback “successCallback” or “errorCallback”.


if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
} else {
  error('Sorry, your browser does not support geolocation');
}

“successCallback” is call whenever the API call is successful. You need to create a function for “successCallback”, as shown in the example below:

function successCallback(pos) {
  var lat, long;

  lat = pos.coords.latitude ;
  long = pos.coords.longitude;

var element = '<p><a href="http://maps.google.com/maps?q='+lat+','+long+'&hl=en">Latitude: ' +lat+ ' Long: ' + long + '</a></p>';

alert(lat +','+long);
$('body').prepend(element);

The function will return the latitude and longitude data and stores it in ‘lat’ and ‘long’ variable, which is then displayed to the screen.

Continue reading »

Mar 042009
 

Great news for JavaME developers! The J2ME Polish project has announced that their upcoming j2mepolish 2.1 toolkit suite will support porting JavaME apps to Google Android mobile platform automatically! This means that the current JavaME developers will enjoy the advantages of porting their existing mobile application to Android effortlessly.

Android Logo

According to their press release, the next j2mepolish release will focus on automating the process of converting JavaME MIDlets to iPhone application.

J2ME Polish 2.1: Android support?

Android Logo

Currently I’ve yet to see how a ported JavaME application would look like on an Android mobile phone, but hopefully it would be as good as the ordinary Google Android app. At this time of this writing, J2ME Polish 2.1 is only available as a preview release which can be downloaded from J2ME Polish website.

I’ll update this blog about this feature once J2ME Polish 2.1 has been released.

p/s: I’m Eager to know how a JavaME app will look like once its ported to Android.

Feb 222009
 

I’ve completed the JSR-179 Location API code for reverse geocoding in JavaME. This code essentially is an expansion of the previous JSR-179 example that i’ve posted in the blog before, plus the Reverse-Geocoding feature, thanks to TinyGeocoder service.

J2ME GPS Reverse Geocoding mypapit

What this sample MIDlet does?
It obtain coordinates via the mobile phone JSR-179 Location API and subsequently display the name of the location using TinyGeocoder reverse geocoding service.

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.location.*;
import javax.microedition.io.*;
import javax.microedition.location.*;
import java.io.*;

public class Geocoder extends MIDlet implements CommandListener
{
	public Display display;
	public Form form;
	private Command cmdExit,cmdOK;
	public StringItem si, sili;

	public Geocoder()
	{

		display =Display.getDisplay(this);
		form = new Form("Location Api test");
		cmdExit = new Command("Exit",Command.EXIT,5);
		cmdOK = new Command("OK",Command.OK,1);
		si = new StringItem("Coordinates", "Press OK");
		sili = new StringItem("Location", "");
		form.append(si);
		form.append(sili);
		form.addCommand(cmdOK);
		form.addCommand(cmdExit);
		form.setCommandListener(this);
	}

	public void startApp()
	{
		display.setCurrent(form);
	}


	public void pauseApp()
	{}

	public void destroyApp(boolean flag) {
		notifyDestroyed();
	}

	public void commandAction(Command c, Displayable d)
	{
		if (c == cmdOK){
			Retriever ret = new Retriever(this);
			ret.start();

		} else if (c == cmdExit) {
			destroyApp(false);
		}
	}

	public void displayString(String string)
	{
		si.setText(string);
	}

	public void showAlert(String message) {
		Alert alert = new Alert("Alert",message,null,AlertType.WARNING);
		display.setCurrent(alert,form);
	}




}

class Retriever extends Thread {

	private Geocoder midlet;
	Form formRunning;
	Gauge gauge;



	public Retriever(Geocoder midlet)
		{
			/**
			  * Constructor
			  *
			  * EFFECTS: Initialise the server and store midlet information
			  *
			  * @param midlet The main application midlet
			  * @param server Forecast Server URL
			  *
			  */
			this.midlet = midlet;
			formRunning = new Form("Retrieving Info");
			formRunning.append(new Gauge("Processing",false,Gauge.INDEFINITE,Gauge.CONTINUOUS_RUNNING));
			midlet.display.setCurrent(formRunning);

	}

	public void run()
		{
			/**
			* Entry point of the thread
			*
			* EFFECTS: call to connect() method
			*/
			try {
							checkLocation();
						} catch (Exception ex)
						{
							ex.printStackTrace();
							midlet.displayString(ex.toString());
			} finally {

			}


		}

	public void checkLocation() throws Exception
	{
		String string;
		Location l;
		LocationProvider lp;
		Coordinates c;
		// Set criteria for selecting a location provider:
		// accurate to 500 meters horizontally
		Criteria cr= new Criteria();
		cr.setHorizontalAccuracy(5000);
		cr.setVerticalAccuracy(5000);

		// Get an instance of the provider
		lp= LocationProvider.getInstance(cr);

		// Request the location, setting a one-minute timeout
		l = lp.getLocation(120);
		c = l.getQualifiedCoordinates();

		if(c != null ) {
		  // Use coordinate information
		  double lat = c.getLatitude();
		  double lon = c.getLongitude();
		  string = "\nLatitude : " + lat + "\nLongitude : " + lon;
		  new GetData(midlet,lat,lon).start();

		} else {
			string ="Location API failed";
		}

		formRunning.append("Obtained coordinates...");
		midlet.displayString(string);
	}
}

class GetData implements Runnable,CommandListener {

Geocoder midlet;
double lat, lon;

public GetData (Geocoder midlet, double lat, double lon) {

	this.lat = lat;
	this.lon = lon;
	this.midlet = midlet;


}

public void commandAction (Command cmd,Displayable disp)
{

}

public void start() {
       Thread t = new Thread(this);
       t.start();
}


public void run() {
	HttpConnection conn=null;
	InputStream is=null;
	String sb;

	try {
			String sUrl = "http://tinygeocoder.com/create-api.php?g="+""+lat+","+""+lon;
			conn = (HttpConnection) Connector.open(sUrl,Connector.READ);
			if (conn.getResponseCode() == HttpConnection.HTTP_OK) {
					is = conn.openInputStream();
					byte buf[] = new byte[128];
					int total =0;
					while (total < 128) {
						int count = is.read(buf,total,128-total);
						if (count<0) {
							break;
						}
						total += count;
					}

					sb = new String(buf,0,total);

				    if (sb.length() < 10) {
							midlet.showAlert("Connection error, please try again");
							is.close();
							conn.close();

							return;
					}

					  midlet.sili.setText(sb);
					//midlet.form.append(sb);
					//vectorized();
					//midlet.saveCurrency(false,midlet.vector);
					//midlet.display.setCurrent(midlet.form);
			} else if (conn.getResponseCode() == HttpConnection.HTTP_NOT_FOUND) {
					midlet.showAlert("URL not found");

			} else {
				midlet.showAlert("Server busy or unavailable. Please try again later");
			}

	} catch (SecurityException sex) {
		midlet.showAlert("Connection failed. You need to authorize this application to access network");
	} catch (IOException ioex) {
			midlet.showAlert("Connection failed. Please try again later.");
	} catch (Exception e){
		midlet.showAlert(e.toString());
		e.printStackTrace();
		//midlet.display.setCurrent(midlet.form);
	} finally {
		try {
			if (is != null) {
				is.close();
			}

			if (conn != null) {
				conn.close();
			}
		} catch (IOException ioexception) {}
			is =null;
			conn =null;
			midlet.display.setCurrent(midlet.form);


	}
}


public String URLEncode(String s)
{
		if (s!=null) {
			StringBuffer tmp = new StringBuffer();
			int i=0;
			try {
				while (true) {
					int b = (int)s.charAt(i++);
					if ((b>=0x30 && b<=0x39) || (b>=0x41 && b<=0x5A) || (b>=0x61 && b<=0x7A)) {
						tmp.append((char)b);
					}
					else {
						tmp.append("%");
						if (b <= 0xf) tmp.append("0");
						tmp.append(Integer.toHexString(b));
					}
				}
			}
			catch (Exception e) {}
			return tmp.toString();
		}
		return null;
}
}



The code requires mobile device which implements JSR-179 Location API and has been tested on Nokia E71 and 6210 Navigator.

Feb 082009
 

Finally after spending a couple months working on this on and off personal project, I decided to release the final version of Kirodict – a lightweight mobile dictionary.

As it name implies, Kirodict was designed to be small in size while maintaining its functionality as a fully fledge dictionary for mobile and embedded device. Kirodict acts as a front-end to an RFC2229 (dict.org) compatible server which it obtain the word definition from.

Kirodict - compact mobile dictionary

Its small and compact size as well as its portability makes it an attractive application to be downloaded and installed on your mobile phone. Kirodict requires mobile phones with at least these feature :

  • MIDP 2.0 /CLDC 1.0 compatible phones
  • 128kB of free storage space
  • Phone with network connection (3G, GPRS, Wifi, wimax)

With lower requirements, it can be installed on a lower end phone without much problem. Kirodict does not use additional storage space as it does not cache its results.

Kirodict can be downloaded from Kirodict Google Code project website and it is licensed under the GNU General Public License version 2.0

Jan 312009
 

Primosync Google Calendar

This week, I’ve tried Primosync, a JavaME application which allows you to synchronize your Calendar, Events and activities with Google Calendar.

Primosync is compatible with mobile phone which supports JavaME JSR-75 PIM API, a feature that becoming common in latest modern phones.

Advantages of syncing phone calendar with Google Calendar :

  • You will be able to access your event, activities and reminders anywhere with internet connection
  • Your events and reminder will be more portable across various phone models as you can sync it with Google Calendar to update your Calendar
  • Easier to keep track of your reminder and events
  • As a backup measure in case if your mobile phone is stolen or lost

You can download it from Primosync Google Code project website (yes it is open source!) or from Primosync.mobi download site (mobile phone friendly). Available in 3 versions (Blackberry, JavaME Signed, JavaME Unsigned), for some reasons, I was unable to install the Signed version of Primosync in my E71. So I figure the Unsigned version might work in more phones.

So lets start syncing!

Dec 262008
 

I know I’ve been slacking lately on my post.. but hey, I got myself a new phone – The Nokia E71!

Phones model and features are getting diverse now and I’ve noticed that its getting harder and harder to choose a phone that really suits my needs. For example, one feature found on Phone A isnt necessarily can be found on Phone B.

So it took me a while to replace my good old 6630 that has been stolen few months before. But hey, I’m back on my feet now.

Nokia E71 papit

Among the key feature that attract me to buy this phone are :

  • Location API support (JSR-179) with built in GPS receiver
  • QWERTY keyboard
  • Ease of handling, my hands a bit slippy on its sister’s phone E66
  • Battery last longer
  • Hot swappable micro-sd card
  • More than adequate internal memory
  • \

  • Supports WiFi

The only drawback that I could think of this phone is its camera that is not as good as the N95,N96 series phone. But I can still live with that since I rarely use the camera anyway.

Other additional feature
The phone comes with Advance Call Manager and Multi Scanner free of charge, making it easier to filter out unwanted call and to manage phone blacklist.

Multi Scanner allows you to take a photo of name card and automatically store important information (Name, Phone Number, Address, Company’s Name, Fax Number) right into the phone.

I hope I can be more productive at updating this blog and producing new mobile applications with this phone.

Nov 092008
 

Nokia Symbian 3rd Edition phone introduces “com.nokia.mid.batterylevel” properties which you can get the current battery charge level by calling System.getProperty(“com.nokia.mid.batterylevel”) from within your midlet application. Its up to your imagination for you to do the rest.

Sample source code (displaying battery charge level on gauge):

/**********
/*
/* Nokia Battery Level midlet
/* Copyright 2008 Mohammad Hafiz bin Ismail ([email protected])
/* http://mobilepit.com
/*
/* May be use freely
**********/
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class NokiaBattery extends MIDlet implements CommandListener {

int value;
Display display;
Form form;
Gauge gauge;
Command cmdExit;

public NokiaBattery() {
 display = Display.getDisplay(this);
 form = new Form("Nokia Battery");
 cmdExit = new Command("Exit",Command.EXIT,1);
 form.addCommand(cmdExit);
 value=Integer.parseInt(System.getProperty("com.nokia.mid.batterylevel"));
 gauge = new Gauge("Level",false,100,value);
 form.append(gauge);
form.append("Value :"+value);
 
 StringItem item = new StringItem("Network Signal",System.getProperty("com.nokia.mid.networksignal"));
 form.append(item);
 form.setCommandListener(this);
}

public void startApp(){
      display.setCurrent(form);
}

public void pauseApp() {}

public void destroyApp(boolean flags) {

	notifyDestroyed();
} 


public void commandAction (Command cmd, Displayable disp)
{
	if (cmd == cmdExit) {
	 	destroyApp(false);	
	}
}

}

Download source code and sample midlet : NokiaBattery_midlet.zip

This blog is protected by dr Dave\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'s Spam Karma 2: 279408 Spams eaten and counting...