Networking with J2ME

Getting Java applications to network on small devices

If you've been following Soma Ghosh's articles here on the Wireless zone, you've learned how to use your Java skills to build simple applications for handheld devices. Now how do you link those devices to the outside world? In this article, Ghosh discusses the javax.microedition.io and java.io classes that lie at the heart of J2ME networking. You'll learn how J2ME applications handle URLs and accept input, and even be taken through a sample program that downloads currency exchange information to any network-accessible, J2ME-compatible device.

Share:

Soma Ghosh (sghosh@entigo.com), Application Developer, Entigo

A graduate in computer science and engineering, Soma Ghosh has developed a wide range of Java applications in the areas of e-commerce and networking over the past seven years. She believes that wireless commerce represents the near future of the industry and has recently been drawn to wireless initiatives of existing desktop components and models. Soma is currently an application developer with Entigo, a pioneer and industry leader in real e-business solutions and B2B sell- and service-side e-commerce products. She can be reached at sghosh@entigo.com.



01 September 2002

J2ME I/O and networking: An overview

The Java 2 Platform, Micro Edition (J2ME) provides networking features that extend the resources available on a network into the mobile space. It is now possible to get up-to-the-minute stock quotes or updated currency exchange rates on a mobile phone or palmtop.

The javax.microedition.io classes and interfaces handle the networking capability of the Mobile Information Device Profile (MIDP), a platform for development of applications for mobile devices. (For more on MIDP, check out the Resources section below for links to my previous developerWorks articles on the subject.)

The java.io package, on the other hand, provides input/output (I/O) capability to MIDP. Its various classes and interfaces provide for system input and output for data streams. This J2ME package, a subset of the Java 2 Platform, Standard Edition (J2SE) java.io package, handles data I/O at a low level.

The most critical aspect of J2ME network connectivity is communication between a mobile device and Web server. This is essentially a client/server mechanism in which the mobile device acts as a Web client and is capable of interfacing with enterprise systems, databases, corporate intranets, and the Internet.

J2ME networking activity falls into a number of categories, depending on communication protocols. We'll discuss each category in turn in the following sections.

Low-level IP networking

This category involves socket, datagram, serial port, and file I/O communication. Socket-based communication conforms to the connection-oriented TCP/IP protocol. Datagram-based communication, on the other hand, conforms to the connectionless UDP/IP protocol. UDP provides a way for applications to send encapsulated raw IP datagrams without having to develop a connection. Unlike the connection-oriented protocol, which requires source and destination addresses, the datagram only requires a destination address. The following is a URI for a datagram connection for accepting datagrams on a certain port:

datagram://:1234

And here is a URI for a datagram connection for sending to a server on a certain port:

datagram://123.456.789.12:1234

Low-level IP networking can also handle file I/O and can allow a MIDlet to register for network access to a local serial port.

Secure networking

Secure Networking in J2ME involves additional interfaces available for secure communication with Web-based network services. Secure interfaces are provided by HTTPS and SSL/TLS protocol access over the IP network.

HTTP networking

The communication between a mobile device and a Web server is based on HTTP (Hypertext Transfer Protocol). HTTP is a connection-oriented request-response protocol in which the parameters of the request must be set before the request is sent.

Figure 1 shows the mechanism for communication between a mobile device and a Web server.

Figure 1. Connection mechanism between mobile device and Web server
Connection mechanism between mobile device and Web server

The connection framework

J2ME networking was designed to address the diverse needs of a wide spectrum of mobile devices. At the same time, the networking system must be device specific. To meet these challenges, it introduces the concept of a generic connection framework.

The idea of the generic connection framework is to define the abstractions that cover the general aspects of the networking and file I/O in the form of Java interfaces. This architecture enables support for a broad range of handheld devices, and leaves the actual implementations of these interfaces to individual device manufacturers. A device manufacturer chooses which interface to implement in its particular MIDPs based on the actual capabilities of its devices.

The general aspects defined by the Java interfaces take the form of the following basic types of communication:

  • Basic serial input (defined by javax.microedition.io.InputConnection)
  • Basic serial output (defined by javax.microedition.io.OutputConnection)
  • Datagram communications (defined by javax.microedition.io.DatagramConnection)
  • A sockets communications notification mechanism (defined by javax.microedition.io.StreamConnectionNotifier) for client-server communication
  • Basic HTTP communication (defined by javax.microedition.io.HttpConnection) with a Web server

URL handling in J2ME

URL handling in J2ME involves opening a connection to the Web server from the mobile device and handling data I/O between the two. The process happens in the following stages:

  • Setup, in which the connection has not yet been made to the server. The mobile device prepares a bundle of request parameters, and prepares to accept and interpret the subsequent response.
  • Connected, in which the connection has been made, request parameters have been sent, and the response is expected.
  • Closed, in which the connection has been closed.

J2ME defines the javax.microedition.io.Connector class, which contains the static methods used to create all the connection objects. This is done by dynamically looking up a class based on the platform name and the protocol of the requested connection.

In URL handling, Connector.open() is used to open a URL; it returns an HttpConnection object. The string parameter to the Connector.open() method is a valid URL. The URL string varies depending on the communication protocol, as Listings 1 through 5 below demonstrate.

Listing 1. Invoking HTTP-based communication
Connection conn = Connector.open("http://www.yahoo.com");
Listing 2. Invoking stream-based socket communication
Connection conn = Connector.open("socket://localhost:9000");
Listing 3. Invoking datagram-based socket communication
Connection conn = Connector.open("datagram://:9000");
Listing 4. Invoking serial port communication
Connection conn = Connector.open("comm:0;baudrate=9000");
Listing 5. Invoking file I/O communication
Connection conn = Connector.open("file://myfile.dat");

The Connector.open() method also accepts the access mode (values READ, WRITE, and READ_WRITE), and a flag to indicate that the caller wants a timeout notification.

In secured networking, an HttpsConnection is returned from Connector.open() when an https:// connection string is accessed. A SecureConnection is returned from Connector.open() when an ssl:// connection string is accessed.

No matter what type of URL is used, invoking Connector.open() opens an input stream of bytes from the Connection to the java.io.InputStream. This method is used to read every character until the end of the file (marked by a -1). If an exception is thrown, the connection and stream are closed.

Similarly, a java.io.OutputStream representing an output stream of bytes is opened from a Connection for output purposes.

The counterparts of InputStream and OutputStream are java.io.DataInputStream and java.io.DataOutputStream, respectively. A DataInputStream lets an application read primitive Java data types from an underlying input stream in a machine-independent way. The java.io.DataOutputStream lets an application write primitive Java data types to an output stream in a portable way.

Listing 6 shows how data can be input from a URL using HttpConnection.

Listing 6. Inputting data from a URL using HttpConnection
String getViaHttpConnection(String url) throws IOException {
         HttpConnection c = null;
         InputStream is = null;
              StringBuffer str = new StringBuffer();

              try {
                  c = (HttpConnection)Connector.open(url);



                // Getting the InputStream will open the connection
                // and read the HTTP headers. They are stored until
                // requested.
                is = c.openInputStream();
 
            
 
                // Get the length and process the data
             int len = (int)c.getLength();
             int ch;
             while ((ch = is.read()) != -1) {
                 str.append((char)ch);
             }
             
          } finally {
          if (is != null)
              is.close();
          if (c != null)
              c.close();
        }

A currency exchange application

We'll illustrate the concepts outlined so far with a currency exchange application, which will display the current exchange rate between U.S. dollars (USD) and British pounds (GBP). It will also display any related information with the current date and time.

The application's UI is comprised of a Form that embeds a StringItem representing a display-only string and an exit command that lets the application exit when invoked.

On launching the application, a URL request is prepared. The essential currency symbols are provided to the request. Next, we need to open a URL connection between the mobile device and the Web server. An HttpConnection is opened and an InputStream is established for data input. The data obtained is a stream of characters, which are appended in a String. The resulting String represents HTML output. Because the browser on our mobile device cannot display HTML, we will parse the HTML String to get the currency value and any related information.

Our program will search for a particular pattern, USDGBP, within the HTML String. Once the position of this pattern is determined, the search looks for a decimal value. When the decimal position is obtained, digit values are retrieved and arranged in proper order to get the currency value. Listing 7 shows how the currency value is obtained.

Listing 7. Retrieving currency value
            String retVal = "";
            int dec = 0;

            int index = str.indexOf("USDGBP");
            if (index != -1)
                   str = str.substring(index, str.length());



            if ( (( dec = str.indexOf(".")) != -1) && (!(str.endsWith(".")))
             && Character.isDigit(str.charAt(dec+1)) )
{
  String front = "";
  int find = dec-1;
  while (Character.isDigit(str.charAt(find)))
  {
    front += str.charAt(find);
    find--;
    }
  retVal += new StringBuffer(front).reverse().toString();
  retVal += ".";

  String back = "";
  int bind = dec+4;
  while (Character.isDigit(str.charAt(bind)))
    {
     back += str.charAt(bind);
     bind--;
    }
  retVal += new StringBuffer(back).reverse().toString();

}

The related information is also obtained by looking for certain string patterns. Once the data's position in the HTML String is determined, an offset is applied to get the date and time. This information is appended with the string pattern originally used for the search. Listing 8 shows how this works.

Listing 8. Retrieving related information
// Get the time of Currency Exchange and Related information
  int timeIndex = str.indexOf("U.S. Markets Closed.");
  String retTime = "";
  if (timeIndex != -1)
  {
   retTime = str.substring(timeIndex-34, timeIndex);
   retTime += " U.S. Markets Closed ";
  }

Listing 9 contains the code for the currency exchange application in its entirety.

Listing 9. Complete currency exchange example
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
import java.lang.*;
import java.util.*;

//A first MIDlet with simple text and a few commands.
public class CurrencyExchange extends MIDlet 
               implements CommandListener {

  //The exit commands
  private Command exitCommand; 
  
  
  
  //The display for this MIDlet
  private Display display;
  
  Form displayForm;
  
  public CurrencyExchange() {
    display = Display.getDisplay(this);
    exitCommand = 
    new Command("Exit", Command.SCREEN, 1);

  }




 // Start the MIDlet by creating the Form and 
  // associating the exit command and listener.
  public void startApp() {
   displayForm = new Form("Exchange Rate");
   displayForm.addCommand(exitCommand);
   displayForm.setCommandListener(this);


try
{

   String result = getViaHttpConnection
   ("http://finance.yahoo.com/m5?a=1&s=USD&t=GBP");
   displayForm.append(" " + result);



}
catch (Exception exc)
{
   exc.printStackTrace();
}
display.setCurrent(displayForm);


  }
  
  
  
   // Pause is a no-op because there is no   background
  // activities or record stores to be closed.
  public void pauseApp() { }

  // Destroy must cleanup everything not handled 
  // by the garbage collector.
  // In this case there is nothing to cleanup.
  public void destroyApp(boolean unconditional) { }

 // Respond to commands. Here we are only  implementing
 // the exit command. In the exit command,  cleanup and
 // notify that the MIDlet has been destroyed.
  public void commandAction(
  Command c, Displayable s) {
    if (c == exitCommand) {
     destroyApp(false);
     notifyDestroyed();
    }

  }
  
String parse(String str)
{
   // Get the time of Currency Exchange and Related information
   int timeIndex = str.indexOf("U.S. Markets Closed.");
   String retTime = "";
   if (timeIndex != -1)
   {
     retTime = str.substring(timeIndex-34, timeIndex);
     retTime += " U.S. Markets Closed ";
   }
 
   String retVal = "";
   int dec = 0;

   int index = str.indexOf("USDGBP");
   if (index != -1)
     str = str.substring(index, str.length());



if ( (( dec = str.indexOf(".")) != -1) && (!(str.endsWith("."))) 
&& Character.isDigit(str.charAt(dec+1)) )
{
   String front = "";
   int find = dec-1;
   while (Character.isDigit(str.charAt(find)))
   {
      front += str.charAt(find);
      find--;
   }
   retVal += new StringBuffer(front).reverse().toString();
   retVal += ".";

   String back = "";
   int bind = dec+4;
   while (Character.isDigit(str.charAt(bind)))
   {
     back += str.charAt(bind);
     bind--;
   }
   retVal += new StringBuffer(back).reverse().toString();

}
System.out.println(retVal);

 return "USD/GBP " + retVal + " at " + retTime ;



}

String getViaHttpConnection(String url) throws IOException {
         HttpConnection c = null;
         InputStream is = null;
         StringBuffer str = new StringBuffer();

         try {
             c = (HttpConnection)Connector.open(url);



             // Get the ContentType
             String type = c.getType();
 
             // Getting the InputStream will open the connection
             // and read the HTTP headers. They are stored until
             // requested.
             is = c.openInputStream();
 
            
 
             // Get the length and process the data
             int len = (int)c.getLength();
             int ch;
             while ((ch = is.read()) != -1) {
                    str.append((char)ch);
                 }
             
         } finally {
             if (is != null)
                 is.close();
             if (c != null)
                 c.close();
         }


// Before returning, the resultant String should be parsed to get Exchange Rate

String val = parse(str.toString());
System.out.println(val);
return val;
     }
 
 
 
 }

The currency value and other related information soon appear on the mobile device's user interface. Figure 2 shows the results displayed.

Figure 2. The currency exchange application running on a handheld device
The currency exchange application running on a handheld device

The bottom line

J2ME has a uniquely compact way of handling data input/output in a constrained environment. With this capability, the Java-enabled mobile gadget is not a simple communication device, but can act as a mini-browser, providing important information on the move.

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=10706
ArticleTitle=Networking with J2ME
publish-date=09012002