08 - Record Management System in J2ME

Record Management System

So far, when we exit our MIDlets we were losing any data we entered. But MIDP provides a mechanism for MIDlets to persist data so it can be used in later executions of the MIDlet, or to be shared among MIDlets. This mechanism is known as a Record Management System.

Record Stores

The record stores have the following properties:

  1. Each RecordStore is composed of zero or more records.
  2. RecordStore names are case sensitives
  3. Within the same suite, there cannot be two RecordStores with the same name.
  4. If a MIDlet suite is deleted, all the RecordStores of that suite are deleted.
  5. It is possible for a MIDlet to acces a RecordStore from another suite, but only when the suite has given access to that RecordStore.

Each RecordStore handles multiple records, and each record is formed of: a RecordID and byte array.

          

Every RecordStore has the following properties:

  1. Name: Unique among MIDlet suites
  2. Version: it is an integer number that increases with every operation performed on the RecordStore.
  3. Timestamp: this timestamp stores the last time of the last operation performed in milliseconds.

Operations with Record Stores

Creation of Record Stores

We use the following static method to open a RecordStore:

static RecordStore openRecordStore(String name, boolean createIfNeccesary)

 

This method will open a RecordStore with the name specified and if the createIfNeccesary is set to true it will create the RecordStore if it does not exist.

Managing Records

Once we have the RecordStore opened or created we can read, write, update or delete records as needed. For this we can use the following methods:

  1. int addRecord(byte[] data, int offset, int numBytes)
  2. void deleteRecord(int id)
  3. int getNextRecordId
  4. byte[] getRecord(int id)
  5. int getRecord (int id, byte[] buffer, int offset)
  6. int getRecordSize(int id)
  7. void setRecord(int id, byte[] data, int offset, int numBytes)
package my.demo;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreFullException;
import javax.microedition.rms.RecordStoreNotFoundException;
public class HelloWorld extends MIDlet implements CommandListener {
    private RecordStore myRecordStore;
    private static int FIRST_EXECUTION_VAL = 1;
    private boolean FIRST_EXECUTION = false;
    private Display myDisplay;
    private Form myForm = new Form("Form");
    private Command exitCommand = new Command("Exit", Command.EXIT, 1);
    private Command deleteCommand = new Command("Delete RS", Command.EXIT, 1);
    private StringItem myStringItem;
    private int executionNumber = -1;     
    public HelloWorld() {
        openRecordStore();
        readRecord();
        writeRecord();                    
        myDisplay = Display.getDisplay(this);        
        myStringItem = new StringItem("Execution", "" + executionNumber );
        myForm.append(myStringItem);
        myForm.addCommand(exitCommand);
        myForm.addCommand(deleteCommand);
        myForm.setCommandListener(this);
    }
    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        closeRecordStore();
        //deleteRecordStore();
        notifyDestroyed();
    }
    protected void pauseApp() {
    }
    protected void startApp() throws MIDletStateChangeException {
        myDisplay.setCurrent(myForm);
    }
    public void commandAction(Command c, Displayable d) {
        if (c == exitCommand) {
            try {
                destroyApp(false);
            } catch (MIDletStateChangeException e) {
                e.printStackTrace();
            }
        }
        else if (c==deleteCommand) {
            closeRecordStore();
            deleteRecordStore();
        }
    }
    public void openRecordStore() {
        try {
            myRecordStore = RecordStore.openRecordStore("HelloWorldRS", true);
            if (myRecordStore.getNumRecords()==0) {
                FIRST_EXECUTION = true;
            }
        } catch (RecordStoreFullException e) {
            e.printStackTrace();
        } catch (RecordStoreNotFoundException e) {
            e.printStackTrace();
        } catch (RecordStoreException e) {
            e.printStackTrace();
        }
    }
    public void writeRecord() {
        byte[] record;
        try {
            if (FIRST_EXECUTION) {
                record = intToBytesArray(FIRST_EXECUTION_VAL); //First Execution
                myRecordStore.addRecord(record, 0, record.length);
            }
            else {
                record = intToBytesArray(++executionNumber);
                myRecordStore.setRecord(1, record, 0, record.length);
            }
        } catch (RecordStoreException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public void readRecord() {
        byte[] record = new byte[4];
        if (!FIRST_EXECUTION)
            try {
                record = myRecordStore.getRecord(1);
                executionNumber = byteArrayToInt(record);
            } catch (RecordStoreException e) {
                e.printStackTrace();
            }
        else
            executionNumber = FIRST_EXECUTION_VAL;
        record = null;
    }
    public void closeRecordStore() {
        try {
            myRecordStore.closeRecordStore();
        } catch (RecordStoreException e) {
            e.printStackTrace();
        }
    }
    public void deleteRecordStore() {
        try {
            RecordStore.deleteRecordStore("HelloWorldRS");
        } catch (RecordStoreException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    private byte[] intToBytesArray(int i) {
          return new byte[] {
            (byte) ((i >>> 24) & 0xff),
            (byte) ((i >>> 16) & 0xff),
            (byte) ((i >>> 8) & 0xff),
            (byte) (i & 0xff),
          };
        }
    private int byteArrayToInt(byte[] b) 
    {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (4 - 1 - i) * 8;
            value += (b[i] & 0x000000FF) << shift;
        }
        return value;
    }
}

Once we execute this MIDlet, the first time it should display a screen like this:

          

If we exit and execute the MIDlet again, we will see that the execution number increases each time.

          

If we select the Delete RS option, then the RecordStore will be deleted, so if we exit and execute the MIDlet after this, we will see that the execution number was restarted.

          

Like us on Facebook