|
Eighth example
Purpose: Mobile phones are mainly used for communication purposes. In old days they were limited to wireless voice communications. Then came SMS and the more sophisticated MMS. Today internet access is common and it is used for surfing the Web and sending/poping E-mails. Tomorrow there will be all kind of client/server communications using TCP sockets, e.g. to link multiuser games or to establish database access. J2ME is specially suited for these kind of applications because of the rather simple and well designed class library in the WMA (Wireless Mobile API). The Gidlet framework puts another layer of simplicity on top of WMA.
For a simple demonstration, a SMS is sent to a given phone number. If the recipient uses a MIDlet ad not the default SMS application to take the SMS, a SMS port number must be provided. If no MIDlet SMS listener or no port number is used, the recipient's default SMS application will take the SMS. In the Wireless Toolkit (WTK) a WMA console may be started (Menu Files -> Utilities) that simulates a sending or receiving phone with a virtual phone number (55500000 when started). On the other hand, when the phone emulator starts, a different virtual phone number is attributed to the simulated mobile phone.
// SmsSendGidlet.java
// A fixed recipients phone number is used
import ch.aplu.gidlet.*;
public class SmsSendGidlet extends Gidlet
{
private final String phonenumber = "5550000";
private final int portnumber = 5000;
private final String init = "Dear Peter, ";
public void main()
{
MTextBox tb =
new MTextBox("Enter text, press OK");
tb.setText(init);
tb.show();
waitOk();
String msg = tb.getText();
showTimedMessage("Trying to send SMS...", 0);
int rc = sendSMS(phonenumber, portnumber, msg);
switch (rc)
{
case 0:
showMessage("SMS successfully sent", false);
break;
case 1:
showMessage("Failed to send SMS", false);
break;
case 2:
String text =
"Failed to send SMS.\n" +
"It seems that the phone number\n" +
phonenumber + "\ndoes not accept SMS";
showMessage(text, false);
break;
}
notifyDestroyed();
}
}
|
Sender
(WTK emulator)
|
Recipient
(WMA console of WTK) |
Execute
SmsSendGidlet (if you have the Sun's Wireless Toolkit (WTK)
installed and the JAD extension registered. Learn
how to register the JAD extension). Execute SmsReceiveGidlet
at the same time to communicate (must be executed first).
Discussion: If the SMS should be caught by the recipient's default SMS application, the port number is not needed and sendSMS(phonenumber, msg) may be used. The user types the message in a textbox and clicks OK to send the SMS. Then a simple modeless message box is shown where status information is displayed.
Writing a SMS application that listens at a given SMS port number is very simple. The constructor of SmsReader() creates a thread that listens on the given port and triggers the callback method notifyIncomingSms() on each received SMS.
// SmsReceiveGidlet.java
import javax.wireless.messaging.*;
import ch.aplu.gidlet.*;
public class SmsReceiveGidlet extends Gidlet
{
private final int portnumber = 5000;
private MConsole c;
private SMSReader reader;
public void main()
{
c = new MConsole();
c.color(YELLOW);
c.println("Waiting for SMS on port " + portnumber);
reader = new SmsReader(portnumber);
}
public void notifyIncomingSMS(TextMessage msg)
{
c.color(YELLOW);
c.println("Received on:");
c.color(WHITE);
c.println(msg.getTimestamp().toString());
c.color(YELLOW);
c.println("Sender:");
c.color(WHITE);
c.println(msg.getAddress());
c.color(YELLOW);
c.println("Message:");
c.color(WHITE);
c.println(msg.getPayloadText());
}
public void doExit()
{
reader.stop();
notifyDestroyed();
}
}
|
|
Execute
SmsReceiveGidlet (if you have the Sun's Wireless Toolkit (WTK)
installed and the JAD extension registered. Learn
how to register the JAD extension).
Discussion: In this case a MConsole is used to display the information. The callback method uses a TextMessage type parameter, from which all relevant information (date/time, address, text) can be retrieved by getter methods. The callback method doExit() is declared in order to stop the SmsReader thread when the Exit button is hit.
Nineth example
Purpose: The HTTP protocol is widely used to transfer data from a Web server to a client. The client opens a IP socket normally at IP port 80 and reclaims a file from the server by sending a GET or POST command that may contain arguments as name-value pairs in the form argname=value. When using GET the
Uniform Resource Identifier (URI) packs all information in a single line like:
http://serveraddress/relpath?argname1=value1&argname2=value2...
When using a Web browser, the arguments are normally generated by HTML form elements. By clicking a submit-button the above line is generated, displayed in the browser URI text field and sent to the server, where the path to the requested file is extracted. If no arguments are used, the server just sends back the content of the requested file together with a few HTTP protocol information. This request-respond transaction is stateless, after the transfer the server forgets all about the transaction unless a server addon program is used. When such programs written in a high level language (e.g. C, Java) or scripting language (e.g. PHP, Perl) are used, the site is called a dynamic Web site. For Java, the code is run in a so-called container and is part of a Java class. This part written by the Web developer is called a Servlet or a Java Server Page (JSP). In JSP the Java code may be mixed with HTML and special JSP tags are used. With dynamic Web sites the HTTP request actually starts the addon code that extracts the arguments transferred in the URI and reacts as designed by the Web developer with only a few security restrictions.
For demonstration purposes the following program starts the dynamic Web page at www.google.ch/webhp (using a predefined index file in the given directory path). The argument hl determines the language of the response (en for English, de for German, it for Italian, etc.) .
// HttpGetGidlet.java
import ch.aplu.gidlet.*;
public class HttpGetGidlet extends Gidlet
{
private MConsole c;
private static final String uri =
"http://www.google.ch/webhp?hl=en";
public void main()
{
c = new MConsole();
HttpGetter hg = new HttpGetter(uri);
} |
|
public void notifyHttpResponse(String response,
int code)
{
c.color(YELLOW);
c.println("Response code:");
c.color(WHITE);
c.println(code);
c.color(YELLOW);
c.println("Response data:");
c.color(WHITE);
c.println(response);
}
}
|
Execute
HttpGetGidlet (if you have the Sun's Wireless Toolkit (WTK)
installed and the JAD extension registered. Learn
how to register the JAD extension)
Discussion: Creating a HttpGetter instance does all the work for you. The GET command will be sent to the server in a newly created thread, so the program does not block. HttpGetter waits for the reply from the server and then triggers the callback method notifyHttpResponse(), where we extract the string response and write it in a MConsole. The user may scroll through it using the cursor keys. Of course we are not running a Web browser, so the server response it not displayed as graphics.
It is also easy to retrieve binary data from a server such as a gif image. This requires a URI with a qualified filename and no arguments. We get the binary data in a byte array and convert it first to an Image, then to an ImageItem that can be displayed on a Form.
// HttpImageGidlet.java
import javax.microedition.lcdui.*;
import ch.aplu.gidlet.*;
public class HttpImageGidlet extends Gidlet
{
private MForm f;
private static final String uri =
"http://www.google.de/images/art.gif";
public void main()
{
f = new MForm();
f.show();
HttpGetter hg = new HttpGetter(uri);
}
|
|
public void notifyHttpResponse(byte[] data, int code)
{
int okStatusCode = 200;
if (code != okStatusCode)
{
showMessage("Can't copy from uri\n" + uri,false);
return;
}
Image image = Image.createImage(data, 0, data.length);
ImageItem imageItem = new ImageItem("Image from Google",
image, Item.LAYOUT_CENTER,
"Image not displayable");
f.append(imageItem);
}
} |
Execute
HttpImageGidlet (if you have the Sun's Wireless Toolkit (WTK)
installed and the JAD extension registered. Learn
how to register the JAD extension)
Tenth example
Purpose: Due to the slow speed and the high price, the amount of internet data transferred from and to the mobile phone should be kept as small as possible. On the other hand an internet server may easily connect to other Web servers or to databases and retrieve and process data before transferring the filtered data to the mobile phone. The server can also act perfectly as agent to store and exchange information between multiple mobile phones, typically in a chat application, a multiplayer game or an enterprise information system.
In the following example the mobile phone requests data from a SQL server (MySQL). To keep the demonstration simple, the user enters the family name and we just search the address and phone number of that person.
// SqlGetGidlet.java
import javax.microedition.lcdui.*;
import ch.aplu.gidlet.*;
public class SqlGetGidlet extends Gidlet
{
private MForm form;
private Item it1;
private Item it2;
private static final String
uri = "http://www.aplu.ch/gidsql/gidsql.jsp";
public void main()
{
form = new MForm("Search in phonebook");
|
|
it1 = form.addInputField("Enter familyname:", "");
it2 = form.addOutputField();
form.addOkButton();
form.show();
}
public void doOk()
{
String val = form.getText(it1);
new HttpGetter(uri + "?familyname=" + val);
form.setText(it2, "Connecting, wait...");
}
public void notifyHttpResponse(String response,
int code)
{
int okStatusCode = 200;
if (code != okStatusCode)
{
form.setText(it2, "Connection failed");
return;
}
// Get rid of JSP header junk
response = response.substring(10);
form.setText(it2, response);
}
}
|
Execute
SqlGetGidlet (if you have the Sun's Wireless Toolkit (WTK)
installed and the JAD extension registered. Learn
how to register the JAD extension).
Use family names Burri, Meyer or Zbinden as
test.
Discussion: We use a simple HTTP GET request to a dynamic Web page. The family name is transferred using a name-value pair. When the server gets the request, it opens a connection to a MySQL server and performs a SQL query. The result is sent back without any additional HTTP overhead.
On the server side we use JSP and JDBC in order to stay with Java. But any other language for dynamic Web sites, especially PHP, may be used. The database table should be created and populated with some other tool.
<%-- gidsql.jsp --%>
<%@page contentType="text/html; charset=iso-8859-1
errorPage="error.jsp"%>
<%@page import="java.sql.*"%>
<%
String host = "inet00.de";
String database = "usr_web486_2";
String username = "web486";
String password = "xxx";
String table = "person";
String driver = "org.gjt.mm.mysql.Driver";
String connection = "jdbc:mysql://" + host + "/" + database;
Class.forName(driver);
Connection con =
DriverManager.getConnection(connection, username, password);
String fname = request.getParameter("familyname");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM " + table +
" WHERE familyname='" + fname + "'");
if (!rs.last()) // ResultSet empty
out.write("No record found");
else
{
rs.first();
do
{
String firstname = rs.getString("firstname");
String familyname = rs.getString("familyname");
String address = rs.getString("address");
String phonenumber = rs.getString("phonenumber");
out.write(firstname + " " + familyname + "\n") ;
out.write(address + "\n");
out.write(phonenumber + "\n\n");
} while (rs.next());
}
rs.close();
con.close();
%>
|
|
| |