Wednesday, April 9, 2008

Adding contacts using JSR 75

Following code snippets show how to add contacts using JSR 75.

PIMWrite class
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;

public class PIMWrite extends MIDlet implements CommandListener
{
private Command PIMWriteCmd,exitCommand,generateName;
PIMImpl pimImpl;
private static Random random = new Random();
static String[] names;

public static Display display;
public static Form result;
private String sp,si,s1;
private String[] strJSR = new String[12];
private long l;
int noOfContacts;

TextField textfield = new TextField("Enter No of Contacts: ","",3,TextField.NUMERIC);


/*Constructs an Object
*/

public PIMWrite() {

display = Display.getDisplay(this);

PIMWriteCmd = new Command("PIMWrite", Command.SCREEN, 0);


exitCommand = new Command("Exit", Command.SCREEN, 0);

result=new Form("Write Contacts To PIM");
result.append(textfield);
System.out.println(" noOfContacts: "+noOfContacts);

result.addCommand(PIMWriteCmd);
result.addCommand(exitCommand);
result.setCommandListener(this);

}

public void startApp() throws MIDletStateChangeException {
display.setCurrent(result);

}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void commandAction(Command c, Displayable s)
{
if (c == exitCommand)
{
destroyApp(false);
notifyDestroyed();
}

else if(c == PIMWriteCmd)
{
noOfContacts = Integer.parseInt(textfield.getString());
createConatactName();
System.out.println(" noOfContacts: "+noOfContacts);
//Start the PIM thread and write contacts .
pimImpl = new PIMImpl();
pimImpl.start();


}
}

public void createConatactName()
{
names = new String[noOfContacts];
for (int i = 0; i < style="color: rgb(102, 204, 102);">){
names[i] = PIMWrite.generateName()+" "+PIMWrite.generateName();
System.out.println(" Names :"+ names[i]+ " i "+i);
}
}


public static String generateName()
{
return generateName(4, 7, true);
}


/** This method generates the random names
*
* @param minLength Minimum length of name
* @param maxLength Max length of name
* @param capitalize Captilize
* @return name
*/

public static String generateName(int minLength, int maxLength, boolean capitalize)
{

int limit = (random.nextInt(maxLength - minLength + 1)) + minLength;
StringBuffer s = new StringBuffer(limit);
for (int i = 0; i < style="color: rgb(102, 204, 102);">)
{
char c = (char)((random.nextInt(26)) + 'a');
s.append(c);
}
if (capitalize && (s.length() > 0)) s.setCharAt(0, Character.toUpperCase(s.charAt(0)));
return s.toString();
}
}
PIM Implementation class

/**
* PIM Implementation class
*/

import javax.microedition.pim.*;
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.Command;

public class PIMImpl extends Thread
{
static Alert check;

StringItem si;
//----------------------------------------Phone Book---------------------------------

int noOfRecords;
public static boolean pimTemp = false;
Random randPh = new Random();


public PIMImpl()
{

}

public void run()
{
writeData();
}



public synchronized void writeData()
{

String ph[] = new String[PIMWrite.names.length];
for (int i=0;inames.length ;i++ )
{

String r = Long.toString(randPh.nextLong());
if(r.startsWith("-"))
{
r = r.replace('-','9');
}
ph[i] =(r.length()>10)?(r.substring(0,10)):(r);



// System.out.println(" PH :"+ph[i] +"i:"+i);
}


int tc = 0;
PIM pim;
try{

ContactList contacts = null;
ContactList conT = null;
pim = PIM.getInstance();
try {

contacts = (ContactList) pim.openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);
} catch (PIMException e) {
// An error occurred
return;
}
for(int i=0;inames.length;i++)
{

Contact contact = contacts.createContact();
String[] name = new String[contacts.stringArraySize(Contact.NAME)];

// System.out.println("i = "+i);
if (contacts.isSupportedField(Contact.TEL))
{
contact.addString(Contact.TEL, Contact.ATTR_MOBILE, ph[i]);
}

if (contacts.isSupportedArrayElement(Contact.NAME, Contact.NAME_GIVEN))
name[Contact.NAME_GIVEN] = PIMWrite.names[i];
contact.addStringArray(Contact.NAME, PIMItem.ATTR_NONE, name);


try {
contact.commit();
} catch (PIMException e) {
// An error occured
}
PIMWrite.result.deleteAll();
String msg=" Contacts Adding :"+i;
si = new StringItem("",msg);
PIMWrite.result.append(si);

}
check = new Alert("Added","Added ",null,AlertType.CONFIRMATION);
check.setTimeout(Alert.FOREVER);
PIMWrite.display.setCurrent(check);

try {
contacts.close();
} catch (PIMException e) {
}

}catch(Exception e){
String er = e+" ; tc="+tc;
check = new Alert( "Response",er,null,AlertType.CONFIRMATION );
check.setTimeout(Alert.FOREVER);

PIMWrite.display.setCurrent(check);
}
// return true;

}

}

Tuesday, April 8, 2008

Reading contacts from Mobile using JSR 75

The below Midlet explains how to read the contact names and numbers from the Phonebook using JSR 75
PIMMidelt.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class PIMMidelt extends MIDlet
{
ReadPIM readPim;
Display display;

public void startApp()
{
display = Display.getDisplay(this);
readPim = new ReadPIM(this);
display.setCurrent(readPim);
}
public void pauseApp()
{
}
public void destroyApp(boolean uc)
{
}
}
ReadPIM.java
import javax.microedition.lcdui.*;
import javax.microedition.pim.*;
import java.util.*;
import java.io.*;
public class ReadPIM extends Form implements Runnable,CommandListener
{
PIM pim;
PIMList pimlist;
Contact contact=null;
Enumeration enumeration;
PIMMidelt midlet;

String contactName="";
String contactNo="";


StringItem name;
StringItem telno;
Thread thread=null;
Command exitCmd = new Command("Exit",Command.EXIT,1);

public ReadPIM(PIMMidelt midlet)
{
super("Reading contacts");
this.midlet = midlet;

pim = PIM.getInstance();

thread = new Thread(this);
thread.start();
addCommand(exitCmd);
setCommandListener(this);

}

public void run()
{
readContacts();
}

public void readContacts()
{
String[] lists = pim.listPIMLists(pim.CONTACT_LIST);
for (int i = 0; i < style="color: rgb(0, 102, 0);">length; i++)
{
try{
pimlist = pim.openPIMList(pim.CONTACT_LIST,pim.READ_WRITE);
}catch(Exception e){}


try{
enumeration = pimlist.items();
}catch(Exception e){}

while (enumeration.hasMoreElements())
{
contact = (Contact)enumeration.nextElement();

try{
if(pimlist.isSupportedField(Contact.FORMATTED_NAME)&& (contact.countValues(Contact.FORMATTED_NAME) >0))
{
contactName += contact.getString(Contact.FORMATTED_NAME,0) +"\r\n";;
System.out.println("COntact name:"+contactName);
}
}catch( Exception e){}

int phoneNos = contact.countValues(Contact.TEL);
try{
if(pimlist.isSupportedField(Contact.TEL) &&(contact.countValues(Contact.TEL) >0))
contactNo += contact.getString(contact.TEL,0) +"\r\n";
System.out.println("contact No :"+contactNo);
}catch( Exception e){}

}

name = new StringItem("Name",contactName);
telno = new StringItem("No",contactNo);
append(name);
append(telno);

}
}

public void commandAction(Command c , Displayable d) {
if(c == exitCmd) {
midlet.destroyApp(true);
midlet.notifyDestroyed();
}
}
}

Monday, April 7, 2008

Getting the IMEI Number of a Mobiles Using J2ME

International Mobile Equipment Identity (IMEI) is used to identify valid devices connected to GSM and UMTS network. This number can be accessed from a mobile phone by dialing *#06# on the keypad. IMEI is commonly use by software developers as part of software protection scheme to prevent it from being pirated. JavaME developers however suffers from a drawback because MIDP/CLDC specification does not include an API to obtain IMEI from mobile devices. However there are few phone manufacturers included this functionality through System.getPropery() calls. Here's how to get IMEI number from mobile devices of different manufacturers

Manufacturer Argument
Nokia Mobiles System.getProperty("com.nokia.mid.imei”);
Sony-Ericsson Mobiles System.getProperty("com.sonyericsson.imei");
Motorola Mobile System.getProperty("IMEI");
Motorola Mobile System.getProperty("com.motorola.IMEI");
Samsung Mobiles System.getProperty("com.samsung.imei");
Siemens Mobiles System.getProperty("com.siemens.imei");

System properties

The table below defines the generic system properties used by the S60 platform.

Generic system properties

System property Description Value
microedition.platform Name of the host platform or device. Defined in CLDC 1.0 and CLDC 1.1.
microedition.encoding Character encoding. Always returns ISO-8859-1.
microedition.configuration Name and version of the supported configuration value is either “CLDC-1.0” or “CLDC-1.1”, depending on which configuration is implemented. Defined in CLDC 1.0 and CLDC 1.1.
microedition.profiles Names of the supported profile as specified in the MIDP 2.1 API specification. Devices that implement other profiles will also return names of those profiles. Defined in MIDP 2.1 (java.lang package documentation).
microedition.locale* The value is determined according to the language settings of the device. Defined in MIDP 2.1 (java.lang package documentation).
microedition.commports
Defined in MIDP 2.1 javax.microedition.io.CommConnection.
microedition.hostname Returns the local host localhost
microedition.jtwi.version
Defined in Java Technology for the Wireless Industry API specification, version 1.0.

(* - The set of locales supported by the device depends on the languages and region.)

The table below defines the S60 specific system properties used by S60 platform. These system properties are available to the application by calling method java.lang.System.getProperty

Nokia system properties

The table below defines the S60 specific system properties used by S60 platform. These system properties are available to the application by calling method java.lang.System.getProperty

System property Description Value
com.nokia.network.access Returns the networking access point type. pd.GSM - Packet data in GSM network

pd.EDGE - Packet data in EDGE network pd.3G - Packet data in 3G network csd - Circuit switched data, for example GSM CSD/HSCSD data call bt_pan - Bluetooth PAN network wlan - Wireless network, for example 802.11b, 802.11G or WiMaX hsdpa - High speed downlink packet access for 3G networks na - Not applicable, the implementation can’t determine the type

com.nokia.mid.dateformat The preferred date format indicated as a string pattern, which is formatted according to the rules defined in Java 2, Standard Edition, version 1.4.1, java.text.SimpleDateFormat class documentation for date patterns.

Only subset of SimpleDateFormat defined pattern letters are used in this system property.


com.nokia.mid.timeformat The preferred time format indicated as a string pattern, which is formatted according to the rules defined in Java Standard Edition, version 1.4.1, java.text.SimpleDateFormat class documentation for time patterns.

Only subset of SimpleDateFormat defined pattern letters are used in this system property.

hh:mm a
com.nokia.memoryramfree This can be used to query the available RAM in the operating system.

This is a more realistic estimate of available RAM on the device than what is returned by Runtime.getRuntime().freeMemory(), which returns only free memory in the Java virtual machine. Note: This property is not available on all S60 3rd Edition devices.


com.nokia.mid.batterylevel The battery charge level of device. Returns the percentage value of battery level.
com.nokia.mid.countrycode Current network country code. Returns the two-letter country code defined in ISO-3361.
com.nokia.mid.networkavailability Network availability. The property return value can contain "available" or "unavailable". available or unavailable
com.nokia.mid.networkid Network identification parameters, such as network ID (NID in CDMA and MNC in GSM) and network short name. Returns two values:

network ID network short name

com.nokia.mid.networksignal Current (GSM/CDMA) network signal strength. Returns two values:

the number of bars the phone should display the signal strength in dBm

com.nokia.mid.imei The IMEI (International Mobile Equipment Identity) of the device. Returns a 14 digit decimal number that uniquely identifies the device.
com.nokia.mid.imsi The IMSI (International Mobile Subscriber Identity) stored in the SIM card. Note that the access to this system property is limited with com.nokia.mid.mobinfo.IMSI permission. By default this permission is available only in manufacturer and operator domain. Returns the subscriber number associated with the device. The IMSI number is usually 14 decimal digits long, but it may be shorter.

The com.nokia.mid.timeformat and com.nokia.mid.dateformat system properties indicate the user preferences of date and time formats. For example, in many devices there are settings available for user to indicate the date and time formatting settings: ordering of date, month and year components of date strings, separators used between components of date and time strings, whether 12 or 24 hour clock is used, and so on. The values of above system properties indicate the currently active user preferences for these settings. MIDlets can use these values to format date and time strings they, for example, need to display in user interfaces.

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();
}
}