Sep 072009
 

Click-a-tell is a simple web service that allows you to integrate sms sending capability into your web application. Its simplicity and wide range of API available is very attractive to small to medium web application developers. Among the API supported by Clickatell are :

  • HTTP POST
  • HTTP GET
  • FTP API
  • SOAP
  • EMAIL-to-SMS
  • COM Object

Clickatell website offers examples of how to use their API in several programming language including but not limited to : VB.net, PHP, ASP, ASP.NET,PERL, Python, Coldfusion, etc.

However I found that the example written for PHP is a little bit outdated and it uses the file() function to initiate HTTP GET request which is generally restricted on webservers as it pose a huge security risk. The other Clickatell class found through PHPClasses website are either too cumbersome for my project or supported other protocol than I intended to use.

As a result I wrote my own Clickatell SMS (clickatell_sendsms_0.5.zip) class specifically for my own use.

Here are a sample code using the SendSMS 0.5 class

<?php
require('SendSMS.php');


$sendsms = new SendSMS("username","password","HTTP POST API key");


/* if the login return 0, means that login failed, you cant send sms after this */
if  (  ($sendsms->login()) == 0  ) {
	die( "failed");
}

/*other wise, you can send sms using the simple send() call*/

$sendsms->send("0132073011","testing send sms - camna? boleh dpt ? - mr hafiz");

?>

You can download the clickatell_sendsms_0.5.zip”>SendSMS 0.5 PHP class from this website, note that the class is licensed under the terms of the GNU General Public License version 2, and the class is only meant to be use with Click-A-Tell HTTP POST API.

The class can also be use with the libcurlemu library whenever applicable.

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.

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

Oct 232007
 

pybluez is a python bindings for the bluez application which enables you to interface with bluetooth devices on your computer.

Combined with the power of python dynamic typing, you will be able to do Rapid Application Development and test mobile bluetooth application quickly on your computer

Here’s a snippets which combines pyosd and pybluez which scans for nearby bluetooth devices and display the result on screen :

import bluetooth
import pyosd
from time import sleep

p = pyosd.osd()

p.set_pos(pyosd.POS_MID)
p.set_align(pyosd.ALIGN_CENTER)
p.set_colour("green")

p.display( "Scanning for bluetooth device")

nearby_devices = bluetooth.discover_devices(duration=20, lookup_names = True)

str= "found %d devices" % len(nearby_devices)
print str
p.display(str)
sleep(2)

for name, addr in nearby_devices:
   p.display( "  %s - %s" % (addr, name))
   print (" %s - %s" % (addr,name))
   sleep(2)

Python enables Rapid Application Development on your computer without much fuss. Coupled with pygtk and wxPython acting as GUI, you can create a lot of bluetooth application to interface with your mobile devices, limited only by your imagination.

[tags]python,pybluez,bluetooth,gtk,gnome,linux,mobile,pda,programming,development,RAD[/tags]

Sep 282007
 

One of the popular question asked in this blog is ways to generate random numbers in J2ME application.

As most people probably realized, the JavaME CLDC does not include the Math.Random class to generate random numbers. However one can generate a series of random numbers in JavaME/J2ME application by using the included java.util.Random class.

Here’s a sample usage

import java.util.Random;
...
	Random generator = new Random();
	generator.setSeed(System.currentTimeMillis());
	float f = generator.nextFloat();
	
	System.out.println(""+(f*100.0f)%100);
...

The sample code above will produce a random floating-point number between 0..100 (exclusive)

Here’s the source code for the full Random Number Demo application : RandomDemo.java,

Sep 102007
 

Although not required, It is nice to include icon in your MIDlet distribution as it give a unique feeling to your mobile application. The only problem is different device seems to have different icon sizes requirements for tJ2ME MIDlet.

The Ideal Icon size guidelines for different mobile device
Here is the icon size guideline for different devices

Nokia

  • Series 40 – 128×160=24×24, 208×208=46×46, 240×320=46×48
  • S60 1st and 2nd – 176×208=42×29, 352×416=76×76
  • S60 3rd – 176×208=31×31, 208×176=37×37, 352×416=76×76, 240×320=53×53/55×55, 320×240=52×52/54×54, 208×208=37×37
  • N90/N95 : 84×58

Samsung & Sony Ericsson
Most Samsung phone accept 16×16, 32×32 icon size

Motorola
15×15, 16×16, 32×32

Most phone seems to accept 8bit-depth color for MIDlet icons, except Nokia S60 3rd edition which seems display 24bit icon quite well.

Note that most of this figure are based on experiments and observation on different phone models.

[tags]midlet,java,j2me,javame,midp,midp2,symbian,nokia,motorola,sony ericsson[/tags]

Sep 052007
 

If you’re using GPS receiver as a car navigation tool in your car, you might noticed that the GPS receiver works less effectively if your car is tinted with anti-UV car film.

It seems that the film used to tint the car windows contain certain properties that blocks UV rays and other microwave frequency being use as GPS carrier.

As a result, you might not be able to get GPS lock inside your car when you tint the car with VKOOL (or other brands of car tints). The most recommended solution is to get an external GPS antenna outside the car in order to get a reliable lock while navigating.

Other solution includes getting the GPS lock outside the car and then once you got the GPS lock, you can continue to use it inside the car. However the GPS accuracy might be affected due to the amount of signal filtered by the car tint if you’re using it inside the car.

Please refer to these forums for discussion about car tints and GPS signal
PPCSG forum
MalsingMaps Forum

[tags]gps,mobile,pocketpc,pocket pc,garmin,malsingmaps,mapking,satellite,radio,frequency,agps[/tags]

Sep 042007
 

shot.gif

Forget about other bloated mobile YM messenger, YMTiny is a lean Yahoo Messenger that does it best — enabling you to keep in-touch with your YM contacts!

Written in JavaME, the YMTiny has been tested (and works) on various popular phones that supports at least MIDP 2.0/CLDC 1.0 specification.

YMTiny feature simple login and buddy list user interface that makes it easy to use in a small-screen environment.

Among of the feature supported in YMTiny are :

  • Audible message alerts for BUZZ and chats
  • Vibrate/Backlight flashing feature
  • Configurable font, supports bitmap font and system font.
  • “Smart Ping” maintains connection and minimizes bandwidth usage
  • Receives offline messages, new mail and typing notifications
  • Show and hide offline friends
  • Window and forms animations

YMTiny can be downloaded from YMTiny project’s website and from Getjar

p/s : I’ve personally tested YMTiny on my 6630 and Dopod P800W (using the default Intent MIDlet Manager) — the application works perfectly out from the box!

Download YMTiny now!

[tags]ym,yahoo,yahoo messenger,mobile,java,javame,j2me[/tags]

Aug 242007
 

The minimalistic design of JavaME CLDC means that a lot of packages from the standard Java has to be trimmed out and this includes the flexible NumberFormat packages which is useful for formatting numbers in Java.

The absence of NumberFormat and java.text package means that you can’t even round a floating point number!

However there is a workaround to this problem, with this simple method, you can round floating point number (Double) roughly to a specific number of decimal points.

//round to 2 decimal points
double number = (double)(int)((bmi+0.005)*100.0)/100.0;

//round to 4 decimal points
double number = (double)(int)((bmi+0.00005)*10000.0)/10000.0;

The code above shows you how to round a double to 2 and 4 decimal points, you can change the number of zeros above to round it to your desired decimal points.

Hope that will help you in your JavaME / J2ME programming.

[tags]j2me,javame,midp,java,sdk,j2se[/tags]

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