Why PHP
with J2ME
You my have noticed
in last year or two there has been an increasing boom in technology in the area
of mobile handsets and mobile software development. Wireless technology is not
only becoming more commonplace but also more affordable. To support this even
further a survey released by IDC projected revenues in wireless gaming alone
will approximately generate 72.2 million by 2007. Along side with mobile gaming
there will ever increase in demand for mobile applications.
Okay this is fine
and dandy, but what does this have to do with PHP? Not only will there be thousands
of new wireless applications but many existing applications of today will now
be enhanced/modified to work with mobile handsets. In most cases it would make
sense to keep the current technology and architecture and simply have it interface
with the new mobile technology. Possibly meaning sites already written in PHP
now need to interact with the mobile technology, one of the more popular emerging
technologies is J2METM. J2METM is provided by Sun Microsystems and stands for
Java 2 Platform Micro Edition. To learn more about J2METM and Java general visit
http://java.sun.com. J2METM produces small
Java applications or games called midlets. A very simple description would be
midlets are to wml like the Java applets are to HTML. Though midlets do not
run directly inside of wml, you would access/download a midlet through a wml
browser. As well you do have the option to directly upload the midlet to your
mobile handset via PC and cable connector.
There are few options
available when considering how to communicate PHP with J2ME:
· HTTP Simple
Fetch
· HTTP GET/POST
· Web Services
· Fetching Images
Requirements
This article uses
both J2METM and PHP. You will need the J2ME TM Development kit from http://wireless.java.sun.com
and PHP from http://www.php.net. As well you
need to install php with a web server, in this article I will be using Apache.
Apache can be obtained from http://www.apache.org.
Please consult theses sites for installation instructions. Once you?ve
successfully installed the software continue with the article.
Simple HTTP Fetch
Here is a simple example of fetching information in text file.
J2ME Source
Code:
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class SimpleFetch
extends MIDlet {
private Display
display;
String url = "http://127.0.0.1/midlet/helloworld.txt";
public SimpleFetch()
{
display = Display.getDisplay(this);
}
public void startApp() {
try {
getViaStreamConnection(url);
} catch (IOException e) {
//Handle Exceptions any other way you like.
System.out.println("IOException " + e);
e.printStackTrace();
}
}
public void pauseApp() { }
public void destroyApp(boolean unconditional) { }
/**
* Read URL as Stream
*/
void getViaStreamConnection(String url) throws IOException {
StreamConnection streamConnection = null;
InputStream inputStream = null;
StringBuffer b = new StringBuffer();
TextBox textBox = null;
try {
streamConnection = (StreamConnection)Connector.open(url);
inputStream = streamConnection.openInputStream();
int ch;
while((ch = inputStream.read()) != -1) {
b.append((char) ch);
}
textBox = new TextBox("Simple URL Fetch", b.toString(), 1024, 0);
} finally {
if(inputStream != null) {
inputStream.close();
}
if(streamConnection != null) {
streamConnection.close();
}
}
display.setCurrent(textBox);
}
}
PHP Source
Code:
In this case there really is not source code, only a text file with the following
contents
Hello World!
by Jason Lam
The name of the
text file as indicated in the J2ME code is helloworld.txt.
Simple
HTTP GET
Here is an example invoking a PHP with GET parameters.
J2ME Source Code:
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class SimpleGETExample extends MIDlet {
private Display
display;
String url = "http://127.0.0.1/midlet/testGET.php?type=2";
public SimpleGETExample()
{
display = Display.getDisplay(this);
}
public void startApp()
{
try {
testGET(url);
} catch (IOException e) {
System.out.println("IOException " + e);
e.printStackTrace();
}
}
public void pauseApp()
{ }
public void destroyApp(boolean unconditional) { }
void testGET(String
url) throws IOException {
HttpConnection connection = null;
InputStream is = null;
OutputStream os = null;
StringBuffer stringBuffer = new StringBuffer();
TextBox textBox = null;
try {
connection = (HttpConnection)Connector.open(url);
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty("IF-Modified-Since","20 Jan 2001
16:19:14 GMT");
connection.setRequestProperty("User-Agent","Profile/MIDP-2.0
Confirguration/CLDC-1.0");
connection.setRequestProperty("Content-Language", "en-CA");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
os = connection.openOutputStream();
is = connection.openDataInputStream();
int ch;
while ((ch = is.read()) != -1) {
stringBuffer.append((char) ch);
}
textBox = new TextBox("Simple GET Test", stringBuffer.toString(),
1024, 0);
} finally {
if(is!= null) {
is.close();
}
if(os != null) {
os.close();
}
if(connection != null) {
connection.close();
}
}
display.setCurrent(textBox);
}
}
PHP Source Code:
$response = "Hello";
if (isset($_GET))
{
switch ($_GET["type"]) {
case 1: $response = "Good Morning"; break;
case 2: $response = "Good Afternoon"; break;
case 3: $response = "Good Evening"; break;
default: $response = "Hello"; break;
}
}
echo $response;
?>
Depending on what
the midlet sends to the testGET.php script in the GET parameter different results
are returned. If you are already familiar with using GET and POST, you can see
that there isn't really much of difference, it is quite trivial.
Extra Note:
The results would be the same if you decided to make a POST call instead of
a GET call, of course both the J2ME and PHP source code would have to be changed
accordingly to handle POST instead of GET.
Simple WebService
You probably know
you can provide web services with PHP and NuSoap. One of the great the advantages
a web service is the fact that it provides independence from operating systems
and platforms. To learn more about web services refer to Ahm Asaduzzaman?s
excellent article on Building XML Web Services with PHP NuSOAP published at
http://www.devbuilder.org/asp/dev_article.asp?aspid=12
In this example
you will also need the appropriate libraries for the midlet to run correctly:
· kSOAP - http://ksoap.enhydra.org/
· kXML - http://kxml.org
In this example
we are using the 1.x versions of kSOAP and kXML.
J2ME Source:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;
import javax.microedition.io.*;
import org.ksoap.*;
import org.ksoap.transport.*;
import org.ksoap.SoapObject;
public class SimpleWebService
extends javax.microedition.midlet.MIDlet {
private Display display;
private String url = "http://127.0.0.1/midlet/webservice/service.php";
TextBox textbox = null;
public SimpleWebService() {
display = Display.getDisplay(this);
}
public void startApp()
{
try {
testWebService();
} catch (Exception ex) {
System.out.println(ex);
}
}
public void pauseApp()
{
}
public void destroyApp(boolean
unconditional) {
}
public void testWebService() throws Exception {
StringBuffer stringBuffer = new StringBuffer();
TextBox textBox = null;
// First WebService - echos name that is passed in, in this case 'Jason'
SoapObject client = new SoapObject(url,"hello");
client.addProperty("name","Jason");
HttpTransport ht = new HttpTransport(url,"hello");
stringBuffer.append(ht.call(client));
// 2nd WebService
- Supply 2 numbers and the result is the sum of the
// two numbers
client = new SoapObject(url,"add");
client.addProperty("x","7");
client.addProperty("y","6");
ht = new HttpTransport(url,"add");
stringBuffer.append("\nAdd Result: " + ht.call(client));
// display results in textbox
textBox = new TextBox("Simple WebService Test", stringBuffer.toString(),
1024, 0);
display.setCurrent(textBox);
}
}
PHP Source Code:
// include NuSOAP library
require_once('nusoap.php');
// Create Web Service
Server
$server = new soap_server;
// Register Services
$server->register('hello');
$server->register('add');
// Define Services
function hello ($name){
return "Hello $name";
}
function add ($x,$y){
return $x + $y;
}
$server->service($HTTP_RAW_POST_DATA);
?>
Was that not easy
or what? The beauty of this is now you can easily interface your new PHP web
service(s) with any device, whether it be WebTV/iTV, SIP device, mobile device
running something else other then J2ME (Symbian, PalmOS, MoPhun, Brew,MS SmartPhone)
or voice enabled only.
Simple Image Fetch
You can even retrieve
binary data such as images. If the mobile device is capable of view documents
like word or PDF you should be able to send those by HTTP as well.
J2ME Source Code:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
public class SimpleImageFetch
extends MIDlet
{
private Display display;
private String URL = "http://127.0.0.1/midlet/image/test.php";
private Form formImage;
public SimpleImageFetch()
{
try {
display = Display.getDisplay(this);
Image im = getImage(URL);
formImage = new Form("Simple Image Test");
formImage.append(im);
display.setCurrent(formImage);
} catch (Exception ex) {
System.out.println(ex);
}
}
public void startApp()
{ }
public void pauseApp() { }
public void destroyApp(boolean unconditional) { }
private Image
getImage(String url) throws IOException
{
ContentConnection connection = (ContentConnection) Connector.open(url);
DataInputStream iStrm = connection.openDataInputStream();
Image im = null;
try {
byte imageData[];
ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
int ch;
while ((ch = iStrm.read()) != -1)
bStrm.write(ch);
imageData = bStrm.toByteArray();
bStrm.close();
im = Image.createImage(imageData, 0, imageData.length);
} finally {
if (iStrm != null)
iStrm.close();
if (connection != null)
connection.close();
}
return (im == null ? null : im);
}
}
PHP Source Code:
$filename = "./phpjava.png";
$handle = fopen ($filename, "rb");
$contents = fread ($handle, filesize ($filename));
fclose ($handle);
header("Content-type: image/gif");
header("Content-length: ".(string)(filesize($filename)));
echo $contents
?>
Beyond Basic HTTP
Communication
In general, we?ve
only dealt with basic HTTP communications. There are other methods of communication
you may want to consider as well when using PHP, like SMS, email or sockets.
Remember the above
examples are very simplistic and are meant for demonstration purpose only. For
more production ready code you should be aware of the:
· The way
J2ME handles Session and Cookies
· J2ME and PHP page caching
· Detection of HTTP_USER_AGENT
· Encryption, Base64, MD5, Bouncy Castle ( http://www.bouncycastle.org
) with MIDP 2 comes with PKI support
· Latency,
· Size data being transferred,
· Frequency of data being transferred
The listed above
things to beware of is really only related to the communication aspect. There
are other considerations that out the scope from this document such as performance,
data persistence and porting constraints to name a few.
Summary
The goal of this article
is to introduce to you several ways of interacting PHP and J2ME. In the J2ME world
there are dozens of tutorials that already show network examples between J2ME
and JSP/Servlets and briefly mention that is possible to interact with other server-side
languages/scripts. On the flip side of things there are dozens of examples of
different ways PHP can interact with other PHP pages on different servers, while
briefly stating it is possible to interact PHP with other non PHP scripts as well.
Hopefully
|