Thursday, April 3, 2008

Transmit J2ME app as a Background Process

Rarely do any of us want to wait very long to send and receive transmissions. Most of us want instant gratification. Unfortunately, network communications are sometimes slow and unable to meet our expectations. Although you are at the mercy of the network infrastructure for the speed of your transmission, you can improve the perception that users have of your application by making transmissions a background process. Running your application as a background process enables users to run another process while transmission occurs in the background.


You can run an application as a background process by using a thread. The below list illustrates how this is done. The list contains the JAD file for the sample program. The list is a skeleton of an application to which you’ll need to add code that handles the transmission, which is discussed throughout this chapter. You’ll also need to include the other process that runs in the foreground.

Two classes are defined in the program. The first is the MIDlet and the other is the Process class containing code for the transmission. The MIDlet class is very similar to other MIDlets discussed in this chapter in that a form is created containing Start and Exit command buttons. The Start button launches the background process and the foreground process. Take a look at the start section of the commandAction() method and you’ll notice that an instance of the Process class is created; then the start() method of the instance is called to begin the background process as a thread. You place code that starts the foreground process below the call to the start() method.

The Process class defines the start() method. The start() method creates a thread and then calls the start() method to run the thread. The run() method calls the transmit() method. The transmit() method contains all the code to send or receive a transmission.


Transmitting a Background Process


Here are the steps required to transmit a background process:

1. Declare references.

2. Obtain a reference to the instance of the Display class.

3. Create an instance of a Command class to exit the MIDlet.

4. Create an instance of a Command class to start the MIDlet.

5. Create an instance of the Form class.

6. Associate the instance of the Command class to the instance of the Form class.

7. Associate a CommandListener with the instance of the Form class.

8. Display the instance of the Form class on the screen.

9. Create a processing class that runs a thread and contains a method that defines the background process.

10. If the Start command is selected, create an instance of the processing class.

11. Call the start() method of the processing class.

12. Call the foreground process.

13. If the Exit command is selected, terminate the MIDlet.

14. Trap exceptions thrown within the commandAction() method.

15. If the MIDletStateChangeException is thrown, indicate that conditions are now safe to terminate the MIDlet by assigning a true value to the exit flag variable.

16. Terminate the MIDlet when the Exit command is entered the second time.


Code:

import java.io.IOException;

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.midlet.MIDlet;

public class BackgroundProcessing extends MIDlet implements CommandListener {

private Display display;

private Form form;

private Command exit;

private Command start;

public BackgroundProcessing() {
display = Display.getDisplay(this);
form = new Form("Background Processing");
exit = new Command("Exit", Command.EXIT, 1);
start = new Command("Start", Command.SCREEN, 2);
form.addCommand(exit);
form.addCommand(start);
form.setCommandListener(this);
}

public void startApp() {
display.setCurrent(form);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void commandAction(Command command, Displayable displayable) {
if (command == exit) {
destroyApp(false);
notifyDestroyed();
} else if (command == start) {
Process process = new Process(this);
process.start();
// Do foreground processing here

}
}
}

class Process implements Runnable {
private BackgroundProcessing MIDlet;

public Process(BackgroundProcessing MIDlet) {
this.MIDlet = MIDlet;
}

public void run() {
try {
transmit();
} catch (Exception error) {
System.err.println(error.toString());
}
}

public void start() {
Thread thread = new Thread(this);
try {
thread.start();
} catch (Exception error) {
}
}

private void transmit() throws IOException {
// Place code here to receive or send transmission.
}
}


The JAD file

MIDlet-Name: BackgroundProcessing
MIDlet-Version: 1.0
MIDlet-Vendor: MyCompany
MIDlet-Jar-URL: BackgroundProcessing.jar
MIDlet-1: BackgroundProcessing, , BackgroundProcessing
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-JAR-SIZE: 100

Wednesday, April 2, 2008

How to write data to a file in Java ME

This article shows, how to write data to a file by using FileConnection API (JSR-75). This example MIDlet has a TextBox, where text can be entered. Then the text can be saved to readme.txt file, which is in this case created under Gallery's Images folder.

The full source code for a test MIDlet:

WriteMIDlet.java

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.file.*;
import javax.microedition.io.*;
import java.io.*;

public class WriteMIDlet extends MIDlet implements CommandListener
{
private TextBox textbox;
private String photos = "fileconn.dir.photos";
private Command saveCommand;
private Command exitCommand;
private String path;

public void startApp() {
textbox = new TextBox("WriteMIDlet", "", 1000, TextField.ANY);
saveCommand = new Command("Save", Command.SCREEN, 1);
exitCommand = new Command("Exit", Command.EXIT, 1);
textbox.addCommand(saveCommand);
textbox.addCommand(exitCommand);
textbox.setCommandListener(this);
Display.getDisplay(this).setCurrent(textbox);
path = System.getProperty(photos);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

private void saveFile(String path, String name) {
try {
String url = path + name;
String string = textbox.getString();
byte data[] = string.getBytes();
FileConnection fconn = (FileConnection)Connector.open(url, Connector.READ_WRITE);
if (!fconn.exists()) {
fconn.create();
}
OutputStream ops = fconn.openOutputStream();
ops.write(data);
ops.close();
fconn.close();
}
catch (IOException ioe) {
System.out.println("IOException: "+ioe.getMessage());
}
catch (SecurityException se) {
System.out.println("Security exception:" + se.getMessage());
}
}

public void commandAction(Command c, Displayable d) {
if (c == saveCommand) saveFile(path, "readme.txt");
if (c == exitCommand) this.notifyDestroyed();
}
}

Wednesday, February 27, 2008

Verisign signing - Java ME

Verisign signing - Java ME

A commercial application which requires access to some specific APIs like JSR 75, JSR 205, JSR 135 etc. benefits from getting signed with a commercial certificate from third party certificate providers like VeriSign or Thawte. Before buying any certificate from these third parties, you have to make sure that the target phone's of your device has the corresponding root certificate installed and set to allow MIDlet signing. You can check this from the settings of the target mobile device.

The following paragraphs contain the description of the process and steps required to get a certificate from VeriSign and to sign & test you MIDlet.

Getting the certificate

Step 1

Make sure, you have the latest JDK installed on your computer.

Step 2

Create a keystore

You have to generate a public/private key pair, for this enter the following command, specifying a name for your keystore and an alias as well.

 C:\jdk1.3\bin\keytool -genkey -keyalg rsa -keystore 
-alias

Keytool prompts you to enter a password for your keystore, your name, organization, and address. The public/private key pair generated by keytool is saved to your keystore and will be used to sign J2ME applications. This key is never sent to VeriSign and is required to sign code. So you should make a copy of the public/private key pair and store it in a safe deposit box or other secure location. If the key is lost or stolen, contact VeriSign immediately to have it revoked.

Step 3

Create a CSR

You need to generate a Certificate Signing Request (CSR) for the enrollment process.

1. The following command requests Keytool to create a CSR for the key pair in the keystore:

 C:\jdk1.3\bin\keytool -certreq -file certreq.csr -keystore 
-alias

2. Begin the enrollment process for a Code Signing ID from the products and services section of the VeriSign Web site.

3. Copy the contents of the CSR and paste them directly into the VeriSign enrollment form. Open the file in a text editor that does not add extra characters (Notepad or Vi are recommended).

This is the end of requesting the certificates from VeriSign.

Signing the MIDlet

Step 1

After VeriSign has verified your request, they will send an email with the digital id attached. You have to import it to the keystore.

To import your Sun Java Signing Code Signing Digital ID into your keystore, enter the following code with the path correct name for your file (for example, "cert.cer") to your Code Signing Digital ID.

 C:\jdk1.3\bin\keytool -import -trustcacerts -keystore 
-alias -file cert.cer

Step 2

Now sign the application by the two command prompt

 java -jar JadTool.jar [ -addcert -alias keyAlias [ -keystore keystore ]
[ -storepass password ]-inputjad inputJadFile -outputjad outputJadFile ]

java -jar JadTool.jar [ -addjarsig [ -jarfile jarFile ] -alias keyAlias
[ -keystore keystore ]-storepass password -keypass keyPassword
-inputjad inputJadFile -outputjad outputJadFile ]

For all the signing steps, Courtesy:

Monday, February 25, 2008

Reading an image from Gallery in Java ME

How to read an image from Gallery in Java ME

This article shows, how to read an image from Gallery by using FileConnection API (JSR-75) and show it on Form. The Gallery folders can be accessed by using system properties, or example: System.getProperty("fileconn.dir.photos"). File contents are read by using InputStream, data is saved to a byte array and Image object is created by using Image.createImage() method.

The full source code for a test MIDlet:

ReadImage.java

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.file.*;
import javax.microedition.io.*;
import java.io.*;

public class ReadImage extends MIDlet implements CommandListener
{
private Form form;
private
String photos = "fileconn.dir.photos";
private
Image image;
private Command exitCommand;

public
void startApp() {
form = new Form
("ReadMIDlet");
exitCommand = new Command
("Exit", Command.EXIT, 1);
form.
addCommand(exitCommand);
form.
setCommandListener(this);
Display.
getDisplay(this).setCurrent(form);
String path = System.getProperty(photos);
form.
append(readFile(path + "image.png"));
}

public
void pauseApp() {
}

public
void destroyApp(boolean unconditional) {
}

public
Image readFile(String path) {
try
{
FileConnection fc =
(FileConnection)Connector.open(path, Connector.READ);
if(!fc.exists()) {
System.out.println("File doesn't exist!");
}
else {
int size = (int)fc.fileSize();
InputStream is = fc.openInputStream();
byte bytes[] = new byte[size];
int length = is.read(bytes, 0, size);
image =
Image.createImage(bytes, 0, size);
}

} catch (IOException ioe) {
System.out.println("IOException: "+ioe.getMessage());
} catch (IllegalArgumentException iae) {
System.out.println("IllegalArgumentException: "+iae.getMessage());
}
return image;
}

public
void commandAction(Command c, Displayable d) {
if (c == exitCommand) this.notifyDestroyed();
}
}

Code Optimization - Java ME

Code Optimization - Java ME

Since mobile phones have low heap memory, restrictions on jar sizes supported, and slow CPU's, optimizations can be employed to improve your applications performance. Consider your usage of memory, application size, and CPU overhead.

Here is a compilation of code optimization techniques which may be quite helpful to reduce jar size and memory usage.

1. Use an obfuscator like the free Proguard or Retroguard. They can remove unused code and perform other optimizations to decrease MIDlet size (JAR file size).
2. Use minimum number of classes, even a mostly-empty class uses space.
3. Avoid unnecessary object creation.
4. Reuse objects when possible.
5. For saving memory, explicitly set unused object to null.
6. Beware of calling garbage collection, calling system.gc to free memory may cause slowdowns because in certain phones it is a blocking statement.
7. Use only minimum images in the application to save space.
8. If not using an obfuscator
1. All the variable, method & class name should be small
2. Remove any unwanted code
3. The package structure should be as minimum as possible, if possible avoid packages