J2ME-TUTORIALS

PART-1 

 

J2ME  FOR NETWORKS, DATASTORE AND MULTIMEDIA

part-2  (CLICK HERE)

J2ME & XML, J2ME & EJB

 

J2ME FOR NETWORKS

 DATASTORE &  MULTIMEDIA 

          by

 Mrs.Geetha Ganesan,M.C.A, M.Phil

  

-------------------------------------

    There is a great increase in the number of mobile phone  users in India , nowadays.  Mobile phones are increasingly being used not only for talking but for games, data access , networking and web access. J2me is the leading technology used in mobile devices.

 

Recently, Google has created Android platform for mobile devices. We can develop programs using Android SDK, using Java, though it is slightly different from J2me. My  aim is to  cover the basics of j2me development first and then to explore the recent developments.Students, developers and employers alike are now interested in practical skills in j2me. I hope that the experiments given here, will help.These tutorials are meant for learners with good knowledge of core java( especially iostreams & networking) and basic servlets.

 

    The experiments will cover the following topics.

    1)  GUI and events

    2)  Graphics   

    3)  Networking.

    4)  Midlet-Servlet communication      

    5)  R.M.S. ( local database)

        ( Record Management System).

    6)  multi-media( audio & video)

 

     In the next installment, I will cover

J2me in Enterprise level such as WebService

and also Location-based systems.

   

  

--------

    These experiments are  based on well-known books on J2me. More importance is given to coding and execution,instead of  much  theory, which , readers can get from  books  or from  websites(can be got by google search for j2me ).

----------   

This tutorial is based on the following books.

a) Basic level

-----------

    i) J2ME Complete Reference

           -          (TMH publication)

    ii) Wireless Java-

       Jonathan Knudsen(APress)

  iii) Wireless Java programming with

       J2me-

       Dr.Jun Zhu,  Yu Feng (Techmedia/SAMS)

       ( best book).

--------------------------------------

b) Advanced level

-------------

(

   iv) Wireless Java for Enterprise

       Applications- Dan Harkey.

       ( Wiley-DreamTech)   

    v) Pro Java Mobile Media API

        - Vikram Goel ( APress)  

 

***********************************

TOPIC-1

=======

1) GUI and Event-handling.

   

  J2ME programs are known as Midlets.

A typical midlet program looks like a Java desktop application.Let us consider a simple midlet.

********

//demo1  ( buttontext.java)

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

 

 

 

public class buttontext   extends MIDlet

              implements CommandListener

{

Display      display;

Form         form1;

TextField    text1,text2;

Command      button1,button2;

 

     public  buttontext()

     {

     display = Display.getDisplay(this);

     form1 = new Form("demo1");

     text1 = new TextField

           (null,"",100,TextField.ANY);

     text2 = new TextField

           (null,"",100,TextField.ANY);  

 

     form1.append(text1);

     form1.append(text2);

 

     button1 = new Command

           ("show",Command.OK,  1 );

     button2 = new Command

           ("clear",Command.EXIT,  0 );

 

     form1.addCommand(button1);

     form1.addCommand(button2);

 

     form1.setCommandListener(this);

 

     }

  

  public void startApp()

     { display.setCurrent(form1); }

 

  public void pauseApp() { }

 

 public void destroyApp(boolean  b) { }

  //------

     public void commandAction

         (Command c, Displayable d)

     {

     if(c==button1)

     {

      String  s1=   text1.getString();

         text2.setString(s1);

     }

 

     if(c==button2) // clear

     {

      text1.setString("");

      text2.setString("");    

     }

  }

}

==========================================

   The above code reads so much like a typical java frame program that it needs very little explanation.

 

We begin with declarations of display, form, textfields and buttons. This is followed by the constructor, where we define the gui elements.The textboxes can take 'ANY' type of data ( string, number etc). Very often , the first parameter is the label for the control. For instance,we have specified that there is null label for text1 and text2. The second parameter is the content ( blank string). The button has three parameters. ( caption, type, priority). The buttons will not appear inside the display but just outside. These are known as 'soft keys'.Finally , we add the command listener to the form.The  functions like startApp, stopApp and destroyApp follow. Finally, we have the event handler. This will be the pattern of all the midlet programs, whatever be their purpose.We can avoid unnecessary repetition, if we remember this basic structure.

--

   There are various versions of J2me wireless toolkit from SUN. We will use wtk104 and wtk2.3 , in our experiments.

These are also known as MIDP Emulators.

Basic experiments can be done using wtk104 and we need wtk2.3 only for advanced topics.

--

  We can install wtk104 in C-Drive. We can create our source files in

 c:\deviq folder.The wtk is an IDE for developing and testing midlets. It is very simple to use. Just navigate to

c:\wtk104\bin and type 'ktoolbar'. We will get the IDE screen. Click on new project button and give name for the project. It can be 'deviq'.You will then be informed that  folders like src,lib,res have been created and you must place your midlet source code in wtk\apps\deviq\src folder.

   So copy 'buttontext.java' from

 c:\deviq   to

 c:\wtk104\apps\deviq\src

-

Click on 'build' button.

Then click on 'run' button.

You will  get  two textboxes.Type 'DAS'  in text and click the softbutton 'show'. You will   see DAS  in text2.

as  shown below.

 

This is the procedure for all midlets.

 

 

-----------------------------------

    There are just a few GUI elements in j2me. They are Form, TextBox, List &  Alert. Unlike JDK's AWT, these are all screen elements.

 

Let us see a few typical constructors.

 

a) Alert  alert = new Alert

    ("title","message","image","type");

display.setCurrent(alert);

 

(ex) ("error","not Available",

       null,Alert.FOREVER);// modal

-------------------------------------

 

b) TextBox is the simplest screen.

TextBox     textbox =

 new TextBox("email","hello ",48,0);

display.setCurrent(textbox);

 

Third parameter is max number of characters.The last parameter '0' indicates that there is no validation.

-------------------------------------------

// demo-2 ( textboxdemo.java)

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import javax.microedition.io.*;

import java.io.*;                    

 

public class textboxdemo extends MIDlet  

       implements       CommandListener

{

 Display          display;

 Form             form;

 Command          button1,button2,button3;

 TextBox          textbox;

 

 

   public textboxdemo()

   {

      display = Display.getDisplay(this);

      form      = new Form("demo2");

      button1    = new Command

                 ("Back",Command.BACK,2);

      button2    = new Command

                 ("Exit",Command.EXIT,1);

      button3    = new Command

                 ("info",Command.HELP,3);

     

      textbox      = new TextBox

     ("info",  "this is the info!",40,0);

      textbox.addCommand(button1);

      form.addCommand(button2);

      form.addCommand(button3);

 

      form.setCommandListener(this);

      textbox.setCommandListener(this);

      }

   public void startApp()

   { display.setCurrent(form);  }

 

   public void pauseApp()  {}

   public void destroyApp

          (boolean b) {}

   public void commandAction

        (Command cmd,Displayable d)

   {

      if(cmd==button1)

      {display.setCurrent(form);  }

 

      if(cmd==button2)

      {  destroyApp(false);

      notifyDestroyed();   }

 

      if(cmd==button3)

      { display.setCurrent(textbox);}

    }

 

}

==========================================

We can have multiple midlets in a single project. However, it is better to remove existing midlet from the project 'deviq' and add the new midlet ,by using the settings tab in the IDE and test our demos one at a time.The midlet source files can remain in src folder. It is enough if we just remove the existing midlet from the project bundle

and add the new midlet, through the settings tab in IDE.But, if you prefer, you can go on adding your midlets to the same project bundle, as I have done.

 

 

 

===================================

c) Next comes List.

It can be of three types.

 

   i) EXCLUSIVE( radio buttons)

  ii) MULTIPLE ( checkboxes)

 iii) IMPLICIT ( simple list)

 

Here is a full code example.

// demo -2     simplelist.java

 

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

 

public class simplelist extends MIDlet

             implements CommandListener

{

Display      display;

List         list1;

Command      button1;

Alert        alert;

 

     public  simplelist()

     {

     display = Display.getDisplay(this);

 

   button1 = new Command

                 ("exit",Command.EXIT,0 );

 

     list1=new List("menu",List.IMPLICIT);

     list1.append("red",null);

     list1.append("blue",null);

     list1.append("green",null);

     list1.addCommand(button1);

     list1.setCommandListener(this);

     }  

 public void startApp()

    {display.setCurrent(list1);   }

 public void pauseApp() { }

 public void  destroyApp   (boolean b) { }

 

  public void commandAction

              (Command c, Displayable d)

     {

     if(c==List.SELECT_COMMAND)

     {

   String  s1=   list1.getString(list1.getSelectedIndex());

    alert=new Alert("option selected",s1,null,null);

         alert.setTimeout(Alert.FOREVER);

         alert.setType(AlertType.INFO);

         display.setCurrent(alert);

     }

     else if(c==button1)

     {

       destroyApp(false);

       notifyDestroyed();

     }

  }

}

 

-----------------------------------

The following code shows a checkbox type of list ( multiple selection).Note the syntax carefully.

These are checkboxes and so we can select more than one item.

 

// demo3   (checklist.java)

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

 

public class checklist extends MIDlet

             implements CommandListener

{

Display      display;

List         list1;

Command      button1;

Alert        alert;

 

  public  checklist()

  {

   display = Display.getDisplay(this);

 

   button1 = new Command

                 ("exit",Command.EXIT,0 );

 

   list1=new List("cities",List.MULTIPLE);

 

     list1.append("Bangalore",null);

     list1.append("Chennai",null);

     list1.append("Delhi",null);

 

     list1.addCommand(button1);

     list1.addCommand(button2);

 

     list1.setCommandListener(this);

 

     }   

  public void startApp()

      {display.setCurrent(list1);   }

 

  public void pauseApp() { }

  public void  destroyApp  (boolean b) { }

 

     public void commandAction

          (Command c, Displayable d)

     {    

     if(c==button1)

     {

      int   n = list1.size();

 boolean[]   array = new boolean[n];

 

 StringBuffer buffer=new StringBuffer();

  list1.getSelectedFlags(array);

  for(int j=0; j<n;j++)

  {

    if(array[j])

    {

     String   s = list1.getString(j);

      buffer.append(s+"\n");

    }

  }

 

         alert=new Alert("cities",buffer.toString(),null,null);

         alert.setTimeout(Alert.FOREVER);        

         display.setCurrent(alert);

         list1.removeCommand(button1);

    }

}

    

 

============

iv) Form.

--------

   Finally, we have the Form. Controls like TextField, DataField, ImageItem, StringItem , Gauge and Ticker    can be added to the form.

 The following code-snippets illustrate these controls.

 

a) Form   form = new Form("");

--

TextField   text1=

   new TextField

("name?"," ",40,TextField.ANY);

form1.append(text1);

---

b)Ticker

--------

 Form   form = new Form("");

Ticker   ticker1 = new Ticker

("this is a demo for ticker");

form.setTicker(ticker1);

-----

 

c) StringItem

Form   form = new Form("");

 

StringItem  stringitem=

new StringItem("capital","delhi");

 

form.append(stringitem);

 

------

d) ImageItem

-------------

 This is similar to displaying an image in Swing, by simply placing the image on a JLabel control. No graphics is involved.

 

A complete code example is given to show the correct syntax for getting the local image file.

The image should be of *.png type only.

( portable network graphics). Other types are not accepted.

Secondly, the image file should be placed in c:\wtk104\apps\demos\res  folder.

 

If you want color displayed, remember to select the device as 'DefaultColorPhone' from the combo in the IDE.

----------------

// demo5    (itemimage.java)

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

 

import java.io.*;

 

public class itemimage extends MIDlet

{

Display    display;

Form       form;

ImageItem   item;

Image      image1;

 

      public itemimage()

      {

  display = Display.getDisplay(this);

         

  try

  { image1 =

  Image.createImage("/jpower.png");

  }    catch(Exception e1) { System.out.println(""+e1);}

  System.out.println("image created");

           

 item  = new ImageItem(null,image1,

            0,"alternate text");

// third parameter 0 for DEFAULT-LAYOUT

 System.out.println("item ready");

 

 form = new Form("");

 

 form.append(item);

 

Ticker  ticker = new Ticker

("demo for image item");

form.setTicker(ticker);

         

  }      

        

 public void startApp()

 {  display.setCurrent(form);  }

 public void pauseApp() { }

 

 public void destroyApp (boolean b) { }

    

}

==============================

 That is a sufficient level of introduction to j2me gui. We move on to graphics now.

------------

 

TOPIC-2

=======

GRAPHICS

 

. We use a canvas for drawing whatever we want. .

--

The  code   is very  much like a regular jdk frame program.So, it is enough if we mention the syntax for various graphics functions.

g.drawRect(x,y,w,h);

 

We can get screen size by:

  int  width=getWidth();

  int  height=getHeight();

w is the width of rectangle drawn.

h is the height of rectangle drawn.

x is the left property

y is the top property

--

g.setColor(0,0,255); // blue

g.drawRect(10,10,70,70);

g.fillArc(x,y,w,h,  a1, a2);

( a1 = start angle)

( a2 = angle of travel)

--

 These will be useful in creating bar charts and piecharts.

But do we have g.drawOval(x,y,w,h)?

Checkup!

 

A demo for displaying an image from file on a canvas is given below.

 

// demo-5 ( canvasimage.java)

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import java.io.*;

 

public class canvasimage extends MIDlet 

             implements CommandListener

{

Display    display;

Form       form;

mycanvas   canvas1;

Image      image1;

Command     button1;

 

      public canvasimage()

      {

  display = Display.getDisplay(this);         

  try

  {

  image1 = Image.createImage("/jedit.png");

  }    catch(Exception e1)

    { System.out.println(""+e1);}

  System.out.println("image created");

            canvas1 = new mycanvas();

            form    = new   Form("");

 button1 = new Command("show",Command.OK,1);

     form.addCommand(button1);

     form.setCommandListener(this);      

      }     

   //-------------

        

     public void startApp()

     { display.setCurrent(form);   }

     public void pauseApp() { }

     public void  destroyApp(boolean b) { }  

 

     public void    commandAction

      (Command c, Displayable d)

     {

      if(c==button1)

      {

        display.setCurrent(canvas1);

      }

     }

    

     class mycanvas extends Canvas

     {

         public void paint(Graphics g)

         {

          g.drawImage(image1,0,0,0);

         }

     }                

}

***************************************

 

 

 

// demo-6  ( shapes.java).

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

 

 

public class shapes extends MIDlet

          implements CommandListener

{        

Display      display;

Form         form1;

Command      button1;

 

     public shapes()

     {

     display = Display.getDisplay(this);

     form1 = new Form("SHAPES");

 

     button1 = new Command

                 ("Show",Command.OK,1);

          form1.addCommand(button1);                

          form1.setCommandListener(this);

     }

 

     public void startApp()

     { display.setCurrent(form1);   }

 

     public void pauseApp() { }

 

     public void destroyApp(boolean b) { }

 

     public void commandAction

       (Command c,Displayable d)

     {

      if(cmd == button1)

       {

    mycanvas   canvas1= new mycanvas();

      display.setCurrent(canvas1);

       }

     }

    //--------

 

     class   mycanvas extends Canvas

     {

          public void paint(Graphics g)

          {

               g.setColor(255,0,0);

               g.drawRect(10,20,30,30);

 

               g.setColor(0,255,0);

               g.fillRect(10,70,30,30);

 

               g.setColor(0,0,255);

              g.fillArc(50,20,30,30,0,90);

 

               g.setColor(0,255,255);

              g.drawArc(10,70,30,30,0,90);

          }

     }

}

 

 

That is enough for Graphics in j2me.Let us move on to the all-important topic of j2me networking. The cell-phone is a very limited memory device(at present!).But, it can be a  very effective tool if used in network mode for serious work, because the business logic and data will be in the server and the j2me device will work just like a browser or a simple network client. It makes the device an equal and efficient partner in Enterprise computing as well as Entertainment field!

==========================================

 

TOPIC-3

NETWORKING

==========

  J2me provides facilities for the following types of networking.

 a) Http

 b) Sockets ( like ServerSocket in jdk)

 c) Datagrams(like DatagramSocket in jdk)

 d) Serial Port( jdk also has provision)

 e) File

---

   The Generic Connection Framework provides all the above types and a common

method to open any connection.

( Not all implementations may provide all these features, however!).

 

(syntax  examples)

a) Connection connection=

  Connector.open 

            ("http://localhost/data.txt");

b) Connection   connection=

    Connector.open
             ("socket://localhost:1234");

 

c) Connection   connection=

     Connector.open

            ("datagram://localhost:2000");

 

d) Connection   connection=

      Connector.open

             ("comm:baudrate=9000");

e)  Connection  connection=

        Connector.open

              ("file:/data.txt");

-------------------------------------------

Let us now see code-examples for http,

socket and datagram  applications.

 

The first demo is for the familiar Socket server connection. The server-side code is identical to the standard jdk version.

This is compiled as in jdk and server started in a dos window.

----------------

// demo-6a

// c:\deviq\socketserver.java

 

import java.net.*;

import java.io.*;

 

class socketserver

{

  public static void main(String  args[])

  {

   try

   {

   ServerSocket  server =

              new ServerSocket(1234);

   System.out.println("server ready");

 

   while(true)

   {

   Socket  sock = server.accept();

   System.out.println("client accepted");

 

   DataInputStream  dis =

   new DataInputStream

                (sock.getInputStream());

   String  a = dis.readUTF();

 

   System.out.println(a);

 

   DataOutputStream  dos =

      new DataOutputStream

               (sock.getOutputStream());

   dos.writeUTF(a);

 

   System.out.println("echo sent");

   }

   } catch(Exception e1)

     {System.out.println(""+e1);}

 

   }

}

====================================

 

The corresponding socketmidlet is given below. It is created in c:\deviq folder and copied to c:\wtk104\apps\deviq\src  folder.

and executed. Whatever we type in text1 is sent to the socket server and is echoed. The echo is displayed in text2. Tested and found to work smoothly.

//demo-6b

// c:\deviq\socketmidlet.java

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import java.io.*;

import javax.microedition.io.*;

 

public class socketmidlet   extends MIDlet implements CommandListener

{

Display     display;

Form         form1;

TextField    text1,text2;

Command      button1,button2;

 

     public  socketmidlet()

     {

     display = Display.getDisplay(this);

     form1 = new Form("socket demo");

     text1 = new TextField

            (null,"",100,TextField.ANY);

     text2 = new TextField

            (null,"",100,TextField.ANY);   

 

     form1.append(text1);

     form1.append(text2);

 

     button1 = new Command

                 ("show",Command.OK,1 );

     button2 = new Command

                 ("exit",Command.EXIT,0 );

 

     form1.addCommand(button1);

     form1.addCommand(button2);

 

     form1.setCommandListener(this);

 

     }   

     public void startApp()

     { display.setCurrent(form1);       }

        public void pauseApp() { }

 public void  destroyApp(boolean b  ) { }

//----

  public void commandAction

                (Command c, Displayable d)

     {

     if(c==button1)

     {

      String  s1=   text1.getString();

 

      try

      {

      String   s = socket://127.0.0.1:1234";

                 // 127.0.0.1 is localhost

      StreamConnection  connection =

     (StreamConnection) Connector.open(s);

      System.out.println

      ("socket server contacted");

      OutputStream    os  = (OutputStream) 

             connection.openOutputStream();   

 

      DataOutputStream   dos=

        new DataOutputStream(os);

      System.out.println("dostream  ready");

      dos.writeUTF(s1);

      System.out.println("data sent!");      //-------------------------------------

 

      InputStream   ins =

           connection.openInputStream();

      System.out.println("ins   ready");  

      DataInputStream   dis =

          new DataInputStream(ins);

       System.out.println("dis   ready");

 

      String   r = dis.readUTF();

      text2.setString(r);

      }      catch(Exception e1)

        { System.out.println(""+e1);  }

     }

 

     if(c==button2)

     {

      text1.setString("");

      text2.setString("");    

     }

  }

}

============================================

 

For the next example, we read a textfile named 'webtech.txt'  , placed in

c:\inetpub\wwwroot.  This is the root directory of personal webserver, in Windows-98. ( I am working in windows-98).This is an illustration for Http method of 'GET and the correct syntax.It makes use of the webserver but reads the file by socket method as in demo6, where we created our own socket server listening at port 1234.

 

----------------------------

// demo-7 ( urlfile.java)

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import javax.microedition.io.*;

import java.io.*;

                                    

public class   urlfile extends MIDlet

           implements CommandListener

{

Display    display;

Form       form;

Item       item1;

Command    button1,button2;

 

 

 public urlfile()

 {

  display = Display.getDisplay(this);

  button1 =  new Command

             ("quit",Command.EXIT,1);

            button2 = new Command

             ("show",Command.OK,2);

   form = new Form("");

   form.addCommand(button1);

   form.addCommand(button2);

   form.setCommandListener(this);

 }     

 public void startApp()

        {display.setCurrent(form); }    

 public void pauseApp() { }

 public void  destroyApp(boolean  b) { }

//***************************************

 public void commandAction

                (Command c,Displayable d)

 {

 if(c == button1)  // QUIT

 {destroyApp(false);notifyDestroyed();  }

 

  if(c == button2)   // SHOW

   {

   try

   {

  String url="socket://localhost:80";

  System.out.println(url);

 

  StreamConnection   connection =

 (StreamConnection) Connector.open(url);

 System.out.println(" connection opened");

 

 PrintStream    ps   = new PrintStream(connection.openOutputStream());

   System.out.println("ps  ready");

 

ps.println

("GET /webtech.txt  HTTP/0.9\r\n");// note

     ps.flush();

System.out.println("GET  request  sent!");

//----------------------------------        

 InputStream        dis =                    connection.openInputStream();

System.out.println("stream ready!");

StringBuffer   sb = new StringBuffer();

System.out.println("string buffer ok");

             int     ch;

 System.out.println

   ("beginning reading the chars");

 

  while((   ch = dis.read()) !=   -1)

    {

    char   k = (char) ch;

    sb.append(k);

    }

 System.out.println("buffer ready");

 String  r = sb.toString();

 System.out.println(r);

 

    form.append(r);

    ps.close();

    dis.close();

    connection.close();        

 

    } catch(Exception e1)

     {    System.out.println(""+e1);  }         

}

}

 

}

//------------------------

********************************************

In the above example(demo-7), I have made use of socket connection to connect to a webserver, using http protocol. But, there is an easier method. It is to use the HttpConnection class.

 

   There are many advantages in using the HttpConnection class. To quote from the book by Dr.Jun Zhu, 

   a) Not every MIDP device supports socket and datagram communication but all devices support Http Communication.

   b) J2me wireless applications developed by using HttpConnection are very portable across different wireless networks.

 

 

 

   In the next demo, I have placed a png image "jedit.png" in c:\inetpub\wwwroot

(ie) the root directory of personal webserver.( I have chosen PWS as it is always running. If I use Tomcat or Apache, I have to start them.). This is an interesting and important demo. It makes use of HttpConnection. Secondly, note how the bytes are read into an array and an image constructed out of that array.The image thus created is attached to an ImageItem and the imageitem is appended to the form.

 

// demo-8  (webimage.java)

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import javax.microedition.io.*;

 

import java.io.*;

import java.util.*;

                                   

public class   webimage extends MIDlet implements CommandListener

{

Display    display;

Form       form;

Image      image;

Item       item1;

Command    button1,button2;

 

public webimage()

     {

  display = Display.getDisplay(this);

button1=new Command("quit",Command.EXIT,1);            button2 = new Command("show",Command.OK,2);

form = new Form("");

            form.addCommand(button1);

            form.addCommand(button2);

            form.setCommandListener(this);

      }     

   public void startApp()

         { display.setCurrent(form);   }    

   public void pauseApp() { }

   public void  destroyApp(boolean b) { }

   //======     

   public void commandAction

                 (Command c,Displayable d)

   {  if(c==button2)

      {

      try

       {

 String  url="http://localhost/jedit.png";

             System.out.println(url);

 HttpConnection   connection =

   (HttpConnection)Connector.open(url);

 System.out.println(" connection opened");

 

 int length =( int )connection.getLength();

  byte[]   array  = new byte[length];

 

 DataInputStream    dis   =

  new DataInputStream(connection.openInputStream());

 

  System.out.println("ins ready");

      dis.readFully(array);     

  //*********************            

 Image image  = Image.createImage

           (array,   0,     array.length);

 ImageItem  item  = new ImageItem

                (null, image, 0, "");

    form.append(item);

     dis.close();

     connection.close();   

    } catch(Exception e1) 

    {    System.out.println(""+e1);  }

         

   }

 }         

}

//------------------------

 

Let us now make use of the same HttpConnection class to read the urlfile(textfile) as in demo-8.  The code will be almost same except that the the  characters read are appended to a string and displayed.

To avoid repetition of gui and event-handling code and to save space, I am giving the code on button2 only.

------------

if(c==button2) // show

      {

      try

       {

 String  url="http://localhost/webtech.txt";

             System.out.println(url);

 HttpConnection   connection =

   (HttpConnection)Connector.open(url);

 System.out.println(" connection opened");

 DataInputStream    dis   =

  new DataInputStream(connection.openInputStream());

 

  System.out.println("ins ready");

String   s = "";

char     ch;

 while((ch = dis.read()) !=  -1)

 {

  char  k = (char) ch;

   s = s+k;

  }

    form.append(s);

     dis.close();

     connection.close();   

} catch(Exception e1)

 { System.out.println(""+e1);}

===================================

 

Finally, let us see a Datagram  example.

 

The basic concepts, advantages and drawbacks of UDP  are the same as in JDK .However, datagram method is sometimes very important in j2me.

a) When raw speed of communication is more important than transmitting every bit correctly. In real time, wireless audio/video, this is critical.

b) When socket communication is not supported at all, which is the case in packet-switched  wireless networks.

-----

Unlike the previous examples, here we are using two instances of the emulator ide. It is equivalent to communicating between two devices.

To use datagram communication in a J2ME application, a datagram connection has to be opened first.Here is how to do that:

 

DatagramConnection  connection=               (DatagramConnection)

Connector.open("datagram://localhost:9000");

-----------------------

 

If the host field is missing in the connection string,the connection is created in "server" mode.For example, here is how a server mode connection is created:

 

DatagramConnection connection=(DatagramConnection)

Connector.open("datagram://:9000"); 

 

A "server" mode connection means that the connection can be used both sending and receiving datagrams via same port.So we specify only one port number.( the receiving port is dynamically created and allotted).

 

A "client" mode datagram connection is created with the host specified in the connect string.

 

 

A "client" mode connection can be used only for sending datagram messages.

 

The following two programs ( one for emulator1 and the other fot emulator2 illustate the syntax).

 

----------------

// demo9-a

( for listening and echoing)

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import java.io.*;

import javax.microedition.io.*;

 

public class dgmserver   extends MIDlet

{

Display     display;

Form         form1;

TextField    text1;

 

 public  dgmserver()

 {

  display = Display.getDisplay(this);

  form1 = new Form("buttontext");

  text1 = new TextField

      (null,"",10,TextField.ANY);

  form1.append(text1);

 }      

 

   public void startApp()

   {   display.setCurrent(form1);

   try

   {

    String   url = "datagram://:9001";

  DatagramConnection  connection =

    (DatagramConnection)

       Connector.open(url);

  System.out.println("server ready");

  Datagram dg1 = connection.newDatagram

     (connection.getMaximumLength());

  System.out.println("Object Ready");

  connection.receive(dg1);

 

        

    byte[]    data=  dg1.getData();

    int m=    dg1.getLength();

    String s1=new String(data,0,m);

    text1.setString(s1);

    String ad = dg1.getAddress();

    String s2 = text1.getString();

    Datagram dg2 =connection.newDatagram

      (connection.getMaximumLength());

    int n =s2.length();

    byte[]  data1  = new byte[n];

System.arraycopy

    (s1.getBytes(),0,data1,0,n);

      dg2.setData(data1,0,n);

      dg2.setAddress(ad);

      connection.send(dg2);

 

    }

    catch(Exception e1)

   { System.out.println(""+e1);}

 

   }

   public void pauseApp() { }

   public void destroyApp(boolean b) { }

  //-----------------------------------

 

}

 

//***************************************

 

The corresponding datagramclient is given below.

 

// demo9-b

// sends a message to localhost:1

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import java.io.*;

import javax.microedition.io.*;

 

public class dgmclient extends MIDlet

 implements CommandListener

{

Display     display;

Form         form1;

TextField    text1,text2;

Command      button1,button2;

 

 public  dgmclient()

 {

  display = Display.getDisplay(this);

  form1 = new Form("buttontext");

  text1 = new TextField

  ("what message?","",100,TextField.ANY);

  text2 = new TextField

    (null,"",100,TextField.ANY);

  form1.append(text1);

  form1.append(text2);

   

 button1 = new Command("show",Command.OK,1);

 button2 = new Command("exit",Command.EXIT,0);

  form1.addCommand(button1);

  form1.addCommand(button2);

  form1.setCommandListener(this);

 }

 

 public void startApp()

 {

   display.setCurrent(form1);

 }

public void pauseApp() { }

public void destroyApp(boolean b){ }

 

public void commandAction

            (Command c, Displayable d)

  {

 if(c==button1)

 {

 String  s1=   text1.getString();

 try

 {

 String   s = "datagram://:9000"; //sending

 DatagramConnection  connection =

    (DatagramConnection)Connector.open(s);

                   

 System.out.println("server contacted");

 

 Datagram  dg1 = connection.newDatagram

  (connection.getMaximumLength(),

             "datagram://localhost:9001");

  // receiving computer and port number

 

 int n = s1.length();

 

 byte[]   data = new byte[n];

 

 System.arraycopy

             (s1.getBytes(),0,data,0,n);

       dg1.setData(data,0,n);

       dg1.setLength(n);

       connection.send(dg1);

       byte[] data1  = dg1.getData();

       String s3 = new String

             (data1,0,dg1.getLength());

       text2.setString(s3);

     }

 

      catch(Exception e1)

     { System.out.println(""+e1); }

   }

 

   if(c==button2)

     {

      text1.setString("");

      text2.setString("");

     }

 

  }

}

//**************************************

 

 To execute these program:

 

 >ktoolbar

  compile and run "dgmserver"

 Again,

  >ktoolbar

   compile and run "dgmclient"

 

 Now we are having two instances of the IDE. Type in text1 of the dgmclient and click 'show'.( this will send the message to the other IDE.).  We will be able to see the sent string in the dgmserver IDE.

The echoed string will be displayed in text2 of the dgmclient.

This has been tested and found to work correctly.

---

 

 

TOPIC-5

 

MIDLET-SERVLET COMMUNICATION

  

  

The BEST method ofcourse is to connect to a servlet from the midlet. Let us now see a program for sending a query to the servlet and getting the result.

----

 

// demo-10 (a)..midlet

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import javax.microedition.io.*;

import java.io.*;

 

public class querymidlet extends MIDlet         

            implements CommandListener

                                

{

   Display          display1;

   Form             form1,form2;

   Command          button1,button2;

   TextField        text1;

   public querymidlet()        

   {

   display1 = Display.getDisplay(this);

   text1    = new TextField

             (null,"a",100,TextField.URL);

   form1    = new Form("");

   form1.append(text1);

 button1=new Command("SEND",Command.OK,1); 

 button2=new Command("BACK",Command.OK,1);

   form1.addCommand(button1);

   form1.setCommandListener(this);

   }

   public void startApp()

   {

      display1.setCurrent(form1);

   }

   public void pauseApp()  {}

   public void destroyApp(boolean b) {}

   public void commandAction

             (Command cmd,Displayable d)

   {

String   url=

 "http://localhost:8080

        /servlet/j2mequeryservlet";

 if(cmd==button1)

 {

  try

  {

   String s=text1.getString();

   url=url+"?text1="+s; // note

   System.out.println(url);

 HttpConnection    connection=

     (HttpConnection)Connector.open(url);

 connection.setRequestMethod  

            (HttpConnection.POST);

 DataOutputStream dos=new DataOutputStream  

          (connection.openOutputStream());

 dos.writeUTF(s);

 dos.flush();

 System.out.println(s + "sent");

 //----

 DataInputStream dis = new DataInputStream         

           (connection.openInputStream());

 System.out.println("ready to hear from

                              server");

 

 String    r=dis.readUTF();               

 System.out.println(r);    

 form2=new Form("Get result");

 System.out.println(r);

 StringItem  item =

       new StringItem(null,r);

 form2.append(item);

 form2.addCommand(button2);

 form2.setCommandListener(this);

 display1.setCurrent(form2);

        

  System.out.println("Displayed")

}catch(Exception e1)

 { System.out.println(" "+e1);  }

else if(cmd==button2)

 {

      text1.setString(" ");

      display1.setCurrent(form1);

  }

 }

}

 

==========================================

 

The corresponding servlet code is given below.

// demo10-b( j2mequeryservlet.java)

 

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

 

public class j2mequeryservlet extends

                           HttpServlet

{

  public void doPost

           (HttpServletRequest request,

            HttpServletResponse response)

       throws ServletException,IOException

    {      

String   a = request.getParameter("text1");

       System.out.println(a);

       String a1=a+"%";

       System.out.println(a1);

String sql=

"select * from table1 where name like '"+a1+"'   ";

      System.out.println(sql);

 

       querybean bean1=new querybean();

       String r=bean1.getresult(sql);

       System.out.println(r);

 

 

 DataOutputStream dos =

            new DataOutputStream(response.getOutputStream());

       dos.writeUTF(r);

      

     }

}

=========================================

 It will be noticed that we are using a querybean component based on jdbc. As it is presumed that readers will be familiar with simple  jdbc code, it is not repeated here.

 This will work with tomcat3.2(I am using tomcat3.2 to avoid the drudgery of making xml entries in web.xml as in Tomcat4 and Tomcat5). It is not required here and will only add one more layer of work and difficulty, for learners.

( set classpath=c:\deviq;c:\tomcat3.2\lib\servlet.jar). Compile the bean and servlet. Copy the bean and servlet class files to tomcat3.2\webapps\root\web-inf\classes.

Start the tomcat server ( after setting java_home as c:\jdk1.3).

Now copy querymidlet.java to c:\wtk104\apps\deviq\src

compile and execute the midlet by typing (say) 'd'. We get result as 'david,3421' as there is an entry like that in table1.

 

******************************************

 

 

TOPIC-6

 

R.M.S

(Record Store Management).

 

   The typical j2me device ( cell-phone) has very limited memory and we cannot have 

full-blown database system in the device. But the user needs  atleast a small database in the device however, for things like games, contacts info , appointments schedule, etc. For this purpose, J2me has privided  RMS( Record Management System). It is a very simple and primitive database which stores strings as bytearrays. The API has provision for adding , editing , deleting  and finding records. We can also  find the total number of records and display all of them.

  Basically, when we add a record, an id as int is returned by RMS. This  id is automatically generated. Using this id, we can edit, show and delete the concerned record.

 

  The following example illustrates this.

RecordStore is the starting point.

 

RecordStore       recordstore=

RecordStore.openRecordStore("contacts",true).

 

'contacts' is the file name of the database and 'true' means, if it does not exist, it is created.

 

I have provided a list for 4 operations(add,edit,find and delete). There are two text fields( text1 and text2). text1 is used for entering the record string. and text2 is used for entering the id value for operations like find,edit and delete.

 

The syntax for the 4 operations is given below.

 

a)add

======

   String   s = text1.getString();

   byte[]   array = s.getBytes();

   int  id = rs.addRecord

           (array, 0, array.length);

-------------------------------------

b) show

=======

   String   a = text2.getString();

   int   id = Integer.parseInt(a);

 

   byte[]  array = rs.getRecord(id);

   String   s    = new String(array);

   text1.setString(s);

--------------------------------------

c) edit

=======

   String   a = text2.getString();

   int   id = Integer.parseInt(a);

 

 String  s= text1.getString();// new

 byte[]  array = s.getBytes();

 rs.setRecord(id,array,0,array.length);

--------------------------------------

d) delete

=========

   rs.removeRecord(id);

======================================

e) showall

==========

   How do we know the id of all the records in the store? There is a provision for that.

RecordEnumeration     enum =

         recordstore.enumerateRecords

                    (null,null,false);

 

      int   t = enum.numRecords();

This enumeration collects all the records.

 

From this enumeration, we can get the id.

 int   id = enum.nextRecordId();

Using this id, we can get at the required record.

It is a good practice to close the recordstore after the operations.

The recordstore is available for all the midlets within a the same project. This is a nice feature.But, it cannot be accessed from other projects. That preserves the integrity of the database.While defining the RecordEnumeration, the first parameter is RecordFilter, the second is RecordComparator and the third is 'updated'). Using these , the search becomes more efficient , if our database has a lot of records( ofcourse, within the constraints of the device). For simplicity, we have omitted these options.

 

 

 

// demo-11( rmsdemo.java)

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import javax.microedition.io.*;

import javax.microedition.rms.*;

import java.io.*;  

 

public class rmsdemo extends MIDlet

        implements  CommandListener                        

{

   Display          display;

   Form             form1,form2;

   ChoiceGroup      group1;

   Command     button1,button2,button3;

   TextField        text1,text2;

 

   RecordStore         recordstore;

 

   public rmsdemo()         // constructor

   {

      display = Display.getDisplay(this);

   group1 =      new ChoiceGroup  

             ("RMS",Choice.EXCLUSIVE);

      group1.append("add",null);

      group1.append("edit",null);

      group1.append("show",null);

      group1.append("remove",null);

 

   button1 =  new Command                     ("Exit",Command.EXIT,1);

    button2 =  new Command                           ("execute",Command.SCREEN,1);

      button3     =    new Command                           ("Menu",Command.OK,1);

      form1     = new Form(" ");

      form1.append(group1);

      form1.addCommand(button1);

      form1.addCommand(button2);

      form1.setCommandListener(this);

 text1 = new TextField("id","",60,0);

 text2 = new TextField("record","",60,0);

      form1.append(text1);

      form1.append(text2);

      form2  = new Form("");

      form2.addCommand(button3);

      form2.setCommandListener(this);

      try

      {

       recordstore =

RecordStore. openRecordStore("contacts",true);

       System.out.println("recordstore

               'contacts ready'  ");

      }

      catch(Exception e1)

    { System.out.println(""+e1); }

   }

 

   public void startApp()

   {

      display.setCurrent(form1);

   }

 

   public void pauseApp()  {}

   public void destroyApp(boolean b) {}

   public void commandAction

                (Command c,Displayable d)

   {

   if(c==button1)// exit

   {destroyApp(false);notifyDestroyed();}

     

  //=================================

   if(c==button2) // execute

   {

  int    n = group1.getSelectedIndex();

  String   s = group1.getString(n);

 

//***********************************

  if(s.equals("add"))

    {

    try

    {       

      String   r  = text1.getString();

      byte[]   array = r.getBytes();

   int  id = recordstore.addRecord

                 (array, 0, array.length);

      form2.append(" ");

      form2.append("record added"+id);

      display.setCurrent(form2);

 System.out.println("record added...."+id);

    } catch(Exception e1)

        { System.out.println(""+e1);}

 }

 

 //************************************

    if(s.equals("edit"))

    {

    try

    {         

      String   r = text2.getString();

      int id = Integer.parseInt(r);  

 

      String   m = text1.getString();  

      byte[]   array1  = m.getBytes();

      int n4=array1.length;                                        

      recordstore.setRecord

                    (id,array1,0,n4);

      form2.append(" ");

      form2.append("record edited..."+id);

      display.setCurrent(form2);

      System.out.println

                  ("record edited..."+id);

      }

     catch(Exception   el)

             {System.out.println(" "+el);}

    }

   ======================================

 

   if(s.equals("show"))

    {

     try

      {       

      String a=text2.getString();

      int id=Integer.parseInt(a);

       byte[]  array =

        recordstore.getRecord(id);

      String    r  = new String(array);

      form2.append(" ");

      form2.append(r);

      display.setCurrent(form2);

       System.out.println(r);

     } catch(Exception e2)

      { System.out.println(""+e2);}

   }

 =======================================

 

   if(s.equals("remove"))

    {

    try

    {

      String   r  = text2.getString();

      int id=Integer.parseInt(r);

       recordstore.deleteRecord(id);

        form2.append(" ");

       form2.append("record deleted");

      display.setCurrent(form2);

       System.out.println

              ("Record deleted");      }

       catch(Exception e5)

       {System.out.println(""+e5);}      

    }

 

    if(s.equals("showall"))

    {

    try

    {

      RecordEnumeration     enum =

         recordstore.enumerateRecords

                    (null,null,false);

 

      int   t = enum.numRecords();

      System.out.println(t);

      String   ts = ""; // total

 

      for(int  j=1;    j<t-1; j++)

       { 

       int   id = enum.nextRecordId();

       byte[]     ar =

              recordstore.getRecord(id);

       String     cs  = new String(ar);

       t = ts  +cs + "\n";

     

       }

       System.out.println(ts);

       form2.append(ts);

        display.setCurrent(form2);

 

 

    }  catch(Exception e1) {System.out.println(""+e1);}

 

   }

 

  }

  //*********************************

  if(c==button3) // BACK TO MENU

  {

  display.setCurrent(form1);

  }     

 }

}

==========================================

 

demo-12 (videodemo.java)

 

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import javax.microedition.io.*;

import javax.microedition.media.*;

import javax.microedition.media.control.*;

                                   

 public class   videodemo extends MIDlet

  {

   Display    display;

   Form       form;

   Player     player;

 

    public videodemo()

     {

      display = Display.getDisplay(this);

      form = new Form("");

      System.out.println("constructor ok");

     }

     

    public void startApp()

    {

     try

     {

     String url = "http://localhost/taj.mpg";

     player   = Manager.createPlayer(url);

     player.realize();

     System.out.println("player realized");

   //------

    VideoControl videocontrol =

    (VideoControl) player.getControl("VideoControl");

    System.out.println("videocontrol ok");

    Item         videoItem = (Item)

    videocontrol.initDisplayMode

     ( VideoControl.USE_GUI_PRIMITIVE, null);

    form.append(videoItem);

    player.start();

    }

    catch(Exception e)

    {System.out.println(" "+e);}

     display.setCurrent(form);

    }

  //---------------------

    public void pauseApp() { }

    public void  destroyApp(boolean unconditional)

    {

     try

      {

       if(player!= null) { player.close();}

      }  catch(Exception  e)

      {System.out.println(" "+e);}

     }

}

 

 

 

 

 

 

 

 

 

 

 

 

Acknowledgements:

=================

 I have been influenced by an earlier tutorial by Devasena in DeveloperIQ on J2ME graphics and  piechart . And for coding style and presentation by my guide Sri.R.S.Ramaswamy, through his articles in DeveloperIQ  back issues.