By katia
What bluetooh is
Bluetooth is a simple, wireless and safe technology that permits communication among devices, such as smartphones, computers, mouses, keyboards, etc.
What PIM API is
PIM API is a group of interfaces and classes that allow access to personal information databases. This optional package permits CRUD (create, retrieve, update, and delete) operations on: Contact lists, Event lists, and To-Do lists.
What our midlet do
Our midlet uses bluetooth to send contacts (name, address, and phone) among devices and to discover how many contacts in common have between two devices.
How our midlet join Bluetooth and PIM API
- Send contacts among devices
The bluetooth communication among devices is based on messages (String). The client chooses one device to send a string containing the contact’s name,address, and phone . The string format is: “name #/# address#/#phone”, we use “#/#” to separate the fields, but you can use any character set you want. When the server receives a string, we use a function to get each field and create a new contact on user’s contact list. The user can have more than one contact list, but only the first contact list will save the new contact.
The server just receives a string through bluetooth containing name, address and telephone, and save the new contact on one the user contact list.
The fields name, address and phone was chosen because they are the most important fields when we create a new contact on contact list. The others fields (birthday, e-mail, nickname, photo, etc) could also be used, although in order to make things easier to understand we use only the three main fields.
We tested our midlet in two devices and was verified that each one has two contact lists. The contact list name is different from one device to another. You can get all contact list names by using “String [] myList = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST).” On our example you are able to choose any contact list and any contact you want to send.
Code (client)
After choosing a contact the next step is to choose which device is going to receive the contact. We use the lines below to make the local device discoverable and to find other devices.
local_device = LocalDevice.getLocalDevice();
disc_agent = local_device.getDiscoveryAgent();
local_device.setDiscoverable(DiscoveryAgent.GIAC);
disc_agent.startInquiry(DiscoveryAgent.GIAC, this);
uuid = new UUID(0x0003);
After choosing one device we open a connection, transform our contact into a string using the function “sendContato” and finally send the contact through bluetooth.
String url = servico
.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
try{
//openning a connection
conn = (StreamConnection)Connector.open(url);
sendContato(conn.openOutputStream());
conn.close();
display.setCurrent(new Alert("Contact sent!"), previousForm);
} catch (Exception e) {
e.printStackTrace();
}
private void sendContato(OutputStream output) {
String s = "";
if (contato.getPIMList().isSupportedField(Contact.FORMATTED_NAME)) {
s += contato.getString(Contact.FORMATTED_NAME, 0)+" #/#";
} else {
s += " #/#";
}
if (contato.getPIMList().isSupportedField(Contact.FORMATTED_ADDR)) {
s += contato.getString(Contact.FORMATTED_ADDR, 0)+" #/#";
} else {
s += " #/#";
}
if (contato.getPIMList().isSupportedField(Contact.TEL)) {
s += contato.getString(Contact.TEL, 0);
} else {
s += " ";
}
try {
output.write(s.getBytes());
output.flush();
output.close();
} catch (IOException e) {
}
}
Code (server)
The server opens a connection and wait until a client sends the contact, open a InputStream to receive data from the client, turn the inputStream into a string using the function “slurp”and save the contact using the function “salva contato”.
UUID uuid = new UUID(0x0003);
LocalDevice localDevice = LocalDevice.getLocalDevice();
localDevice.setDiscoverable(DiscoveryAgent.GIAC);
// open a connection
con = (StreamConnectionNotifier)Connector.open("btspp://localhost:"+uuid
+";name=examplo;authorize=false");
// the code below blocks the thread until establish a contact with a client
StreamConnection conn = con.acceptAndOpen();
InputStream input = conn.openInputStream(); //========
String recebido = slurp(input); //=======
salvaContato(recebido);
public String slurp(InputStream in) throws IOException {
String s = "";
int len;
while ((len = in.read())>=0) {
s += (char)len;
}
return s;
}
private String salvaContato(String s) {
String nome = s.substring(0, s.indexOf("#/#"));
s = s.substring(s.indexOf("#/#")+3);
String endereco = s.substring(0, s.indexOf("#/#"));
s = s.substring(s.indexOf("#/#")+3);
String tel = s;
ContactList contacts = null;
try {
// Retrieve the contact list
contacts = (ContactList)PIM.getInstance()
.openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);
Contact contact = contacts.createContact();
if (contacts.isSupportedField(Contact.FORMATTED_NAME)) {
contact.addString(Contact.FORMATTED_NAME, PIMItem.ATTR_NONE, nome);
}
if (contacts.isSupportedField(Contact.TEL)) {
contact.addString(Contact.TEL, Contact.ATTR_HOME, tel);
}
if (contacts.isSupportedField(Contact.FORMATTED_ADDR)) {
contact.addString(Contact.FORMATTED_ADDR, PIMItem.ATTR_NONE, endereco);
}
contact.commit();
contacts.close();
} catch (Exception e) {
}
return nome+" / "+endereco+" / "+tel;
}
- Common contacts among devices
In the following example we will use bluetooth to discover common contacts among devices. In the beginning of our MIDlet the user chooses if s/he wants to share his/her contacs. To explain the code we are using two devices (device A and device B) and supposing that both are able to share contacts. The device A searches and chooses other devices looking for commom contacts and device B waits connections and sends contacts.
After chossing the option “Buscar contatos em comum” the device A chooses and stablishes a connection with device B. The device “B” sends a string to device “A” with all user contact’s phones. The string format is: “phone#/#phone#/#… .” When the device “A” receives the string, the function “busca” is used to search for common contacts between device A and device B (if the phone number has more than eight digits, the comparison is made by the last ten digits ).
The function “busca” gets each contact’s phone from device “A” and verifies if there is on the string received from device “B”, a substring corresponding to the contact’s phone. If exists, we found a contact in common and we store this contact in a vector.
public static Vector busca(String telefones) throws Exception {
Vector answer = new Vector();
String[] lists = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST);
ContactList contactList;
Enumeration items;
String tel = "";
for (int i = 0; i<1; i++) {
contactList = (ContactList)PIM.getInstance().openPIMList(PIM.CONTACT_LIST,
PIM.getInstance().READ_WRITE, lists[i]);
if (contactList.isSupportedField(Contact.TEL)) {
items = contactList.items();
while (items.hasMoreElements()) {
Contact contact = (Contact)items.nextElement();
if (contact.countValues(Contact.TEL)>0) {
tel = contact.getString(Contact.TEL, 0);
if (tel.length()>8){
tel= tel.substring(tel.length()-10, tel.length()-1);
}
if (telefones.indexOf(tel)>-1) {
answer.addElement(contact);
}
}
}
}
}
return answer;
}
The code below is a function we used to transform all contacts into string format “phone#/#phone#/#… .”
public static String TransformAllContactsToString() throws Exception {
String answer = "";
String[] lists = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST);
ContactList contactList;
Enumeration items;
for (int i = 0; i<lists.length; i++) {
contactList = (ContactList)PIM.getInstance().openPIMList(PIM.CONTACT_LIST,
PIM.getInstance().READ_WRITE, lists[i]);
if (contactList.isSupportedField(Contact.TEL)) {
items = contactList.items();
while (items.hasMoreElements()) {
Contact contact = (Contact)items.nextElement();
if (contact.countValues(Contact.TEL)>0) {
answer += contact.getString(Contact.TEL, 0)+"#/#";
}
}
}
}
return answer;
}
- Screenshots
Below the first screen of our MIDlet. There the user can choose if s/he wants to share his/her contacts among devices.

The next screen is the main screen. There are 5 options: list contacts, search contacts, send contact, receive contact , and buscar contatos em comum .

==== Sending contacts among devices ====
If the user chooses “send contact”, the next screen shows all available contact lists. After choosing one available list the next screen will look like this:

The user must choose one contact and select “send”.

After this, our MIDlet will look for available devices. The result appears on another screen.

After choosing the device, If everything runs ok the next screen on client is:

On server the next screen is an alert with the message “Contact received”.
==== Searching commom contacts among devices ====
(We suppose that the device B accepted the option of share contacts. As soon as the user chooses the option “yes”on the first screen, a connection wiil be open and will wait until a device make a request ).
The device A chooses the option “Buscar contatos em comum” on the main screen:

After that the device will search for available bluetooth devices. After finishing the search the next screen will look like this:

After choosing one device the next screen is an alert. If there is no contact in common, the alert message is:”Nenhum contato em comum”, but if there are more than one contact in common, the alert message is: “Temos X contatos em comum”. The letter “X” represents the number of commom contacts. The next screen will show a list with all contacts in commom.

By thiagosales
The MathKids application is an educational math game based on the Tux of Math Command tutor. It is similar to SpacInvaders, where actions depend on the mathematical problem solving. The application was developed by Fernando Maia (fernandohenrimaia at gmail dot com) from Federal University of Campina Grande during the Embedded Effort Competition 2009.1. The following figures show some screenshots. You can download the application in the Applications section.


By katia
= Bluetooth (JSR 82)==
Bluetooth is a simple, wireless and safe technology that permits communication among devices, such as smartphones, computers, mouses, keyboards, etc.
There are three types of communication protocols defined inside Bluetooth technology: OBEX, L2CAP and RFCOMM. The JSR 82 API has the capability to provide all those three kinds of communication. In this article I will show a simple example using RFCOMM due to its the simplest protocol to send strings between devices.
P.s: According to [1], Symbian’s current implementation of JSR 82 does not support OBEX API. As a consequence, it does not have a javax.obex packege.
== What does our MIDlet do ==
It is a simple “Hello World” between client and server. The server waits for a client to send a message (formatted in string) and after receiving it the server displays on device’s screen what was received. The client searches for available devices which have bluetooth, chooses one of them to establish connection, and tries to send the message “Hello Server”.
== Code and Explanation ==
= Server =
In our example the server is a device which will run and wait until a client sends the message. To create a server, the class must implement Runnable. Every Bluetooth device contains the local Bluetooth object that helps communication between devices. Below I will show and explain the code used to create our server.
Every bluetooth application have an unique UUID. This UUID is useful to check if the application running on server is the same application running on client.
UUID uuid = new UUID(0×0003);
In the next two lines it is executed the function “getLocalDevice()” which returns the local Bluetooth device object, and the function “setDiscoverable(DiscoveryAgent.GIAC)” which makes the server (a divice) visible for other devices.
LocalDevice localDevice = LocalDevice.getLocalDevice();
localDevice.setDiscoverable(DiscoveryAgent.GIAC);
The line below opens a StreamConnectionNotifier. The URL has the format “btspp://localhost:”+uuid
+”;name=service_name;authorize=false”.
btspp - Represents the protocol used (in our case RFCOMM).
uuid - Represents our unique identification
name - Represents our bluetooth service’s name.
authorize - if a remote device is authorized to open a blueooth connection
con = (StreamConnectionNotifier)Connector.open("btspp://localhost:"+uuid
+";name=example;authorize=false");
The line below opens a connection and blocks the application until receiving a request from a client to open a connection with the server.
StreamConnection conn = con.acceptAndOpen();
Now I create an InputStream to receive a message sent by any client. I receive a byte array that I can convert into string using the method slurp.
InputStream input = conn.openInputStream();
messageForm.deleteAll();
messageForm.append("Received from client: "+slurp(input));
display.setCurrent(messageForm);
After all communication it is important to close all opened connections.
input.close();
conn.close();
= Client =
In our example the client chooses one available device in a list and sends the message “Hello Server” to the server. To create a client, the class must implement Runnable and DiscoveryListener.
A class that implements DiscoveryListener needs to implement four methods:
- deviceDiscovered(RemoteDevice arg0, DeviceClass arg1)
- inquiryCompleted(int discType)
- servicesDiscovered(int arg0, ServiceRecord[] servRecord)
- serviceSearchCompleted(int transID, int respCode)
The method deviceDiscovered(RemoteDevice arg0, DeviceClass arg1) is called from the device application manager everytime the local device finds another bluetooth device.
The method inquiryCompleted(int discType) is called when the search for bluetooth devices is completed. The field discType can assume three values (static and final values in DiscoveryListener interface):
- DiscoveryListener.INQUIRY_COMPLETED
- DiscoveryListener.INQUIRY_TERMINATED
- DiscoveryListener.INQUIRY_ERROR
The method servicesDiscovered(int arg0, ServiceRecord[] servRecord) is called everytime the local device finds a service of a target device.
The method serviceSearchCompleted(int transID, int respCode) is called when the search for services is completed. The field respCode can assume five values:
- DiscoveryListener.SERVICE_SEARCH_TERMINATED
- DiscoveryListener.SERVICE_SEARCH_ERROR
- DiscoveryListener.SERVICE_SEARCH_NO_RECORDS
- DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE
- DiscoveryListener.SERVICE_SEARCH_COMPLETED
The first and third lines below are the same on server. The function “getLocalDevice()” is called and returns the local Bluetooth device object, and the function “setDiscoverable(DiscoveryAgent.GIAC)” makes the server visible by other devices. The function getDiscoveryAgent() is called to indicate that the local device is capable to search other devices.
local_device = LocalDevice.getLocalDevice();
disc_agent = local_device.getDiscoveryAgent();
local_device.setDiscoverable(DiscoveryAgent.GIAC);
The line below enables the local device to search bluetooth devices.
disc_agent.startInquiry(DiscoveryAgent.GIAC, this);
We creat a UUID. This field have to be the same on server, otherwise server and cliente will never communicate each other because they will have different services.
uuid = new UUID(0x0003);
The line below makes the local device searches for available services on the server.
int transationID = disc_agent.searchServices(new int[] { 0×0100 },
new UUID[] { uuid }, otherDevice, this);
After finding on server the same service running on client, we get the URL using the method getConnection(), open a StreamConnection,and create an OutPutStream because we want to send the message “Hello Server”.
OutputStream is used to send messages and InputStream is used to receive messages.
String url = servico.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT,
false);
StreamConnection conn;
(...)
conn = (StreamConnection)Connector.open(url);
OutputStream output = conn.openOutputStream();
To send a string using OutputStream we need to convert our string into byte array using the method getBytes(), write the byte array generated into our instance of OutputStream, call the method flush(), and finally close the OutputStream. Finally we close the connection using the method “close()” and finish our application.
String hello = "Hello Server!";
output.write(hello.getBytes());
output.flush();
output.close();
conn.close();
Source code
Download source code here
Bibliography
[1] Jode, Martin de. Programming the Java 2 Micro Edition on Symbian OS: A developer’s guide to MIDP 2.0, ON: Wiley, 2004. ISBN 0-470-09223-8.
By katia
PIM API introduction
PIM API is a group of interfaces and classes that allow access to personal information databases. This optional package permits CRUD (create, retrieve, update, and delete) operations on: Contact lists, Event lists, and To-Do lists. It’s important to know that not all devices support PIM API and for those devices which support this package they can have more than one personal database. For further information, take a look at: http://developers.sun.com/mobility/apis/pim/pim2/
Warning
To prevent exceptions on your midlet using PIM API, always check before using a field if it is supported.
What does our MIDlet do?
This MIDlet is able to list and search device’s contacts (tested on Nokia 5200).
In order to list device’s contacts, there are two contact list called “celular” and “PIM” (each device has its personal database names). After choosing one of listed lists, another form containing a list of contact’s name will appear. To show more details about one contact select the option “details”, by doing this another form will show contact’s name, phone-number and address.
To search a contact you have to put the name to be found inside the textfield and select “search”. On the same form, the search result will appear. If there is no contact with the specified name the message “No results found.” will appear. Otherwise, the number of matched contacts, their names, and phone numbers will appear.
Code explanation
Below there are some snippets of code and a brief explanation.
The code below lists all contact lists available in the device. The method “listPIMLists” can also be used to list Event lists, and To-Do lists.
To list Event lists and To-Do lists we replace “PIM.CONTACT_LIST” with “PIM.EVENT_LIST” or “PIM.TODO_LIST” respectively.
String[] list = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST)
The code below shows how to get a contact list. It’s important to know that every contact list is ordered by contact’s name. The last parameter (list[i]) corresponds to which device’s contact list you want. The method openPIMList can also receive two parameters (PIM.CONTACT_LIST, and
PIM.getInstance().READ_WRITE). In this case, the first name returned on method ( PIM.getInstance().listPIMLists(PIM.CONTACT_LIST)) is the device’s contact list chosen.
ContactList contactList = (ContactList)PIM.getInstance().openPIMList(PIM.CONTACT_LIST,
PIM.getInstance().READ_WRITE, list[i]);
Each contact list is composed by an enumeration of contacts. The code below shows how to get an enumeration of contacts.
Enumeration items = contactList.items();
Not all devices support all contact fields. So it’s important to check, before using a field, if it is supported. The code below shows how to check name, address and telephone fields on an contact list given.
Contact contact = (Contact)items.nextElement();
if (contactList.isSupportedField(Contact.FORMATTED_NAME)) {
texto += "Name: "+contact.getString( Contact.FORMATTED_NAME, 0)+"\n\n";
}
if (contactList.isSupportedField(Contact.FORMATTED_ADDR)) {
texto += "Address:"+contact.getString(Contact.FORMATTED_ADDR,0)+"\n\n";
}
if (contactList.isSupportedField(Contact.TEL)) {
texto += "Tel:"+contact.getString(contact.TEL, 0)+"\n\n";
}
Screenshots
Below the first and main screen can be seen. There are two options: list contact and search contact.

The option “list contact” will look for available databases. After choosing one database the following screen will appear showing all database contacts sorted by name.

After choosing one contact and select “details” the contact’s name and phone number will appear.

By thiagosales
In the J2SE and J2EE platforms, the log4j API offers a hierarchical way to insert logging statements within a Java program[1]. The API offers multiple output formats and multiple levels of logging information, allowing developers to get different kinds of log messages. In the context of the J2ME platform, a powefull Logging API is called Microlog (created by Johan Karlsson), which is based on the log4j API. For more additional information, see the MicroLog official website. First of all, you can download the lastest API release at the sourceforge repository. MicroLog is open-source and you can also download the source-code. Become a contributor!
The use of MicroLog revolves around 3 main classes:
- public final class Logger: Logger is responsible for handling the main log operations.
- public interface Appender: Appender is responsible for controlling the output of log operations.
- public interface Formatter: Formatter is responsible for formatting the output for Appender
With these 4 aforementioned concepts, it is possible to log different kinds of log messages.
Logger Component
The logger is the main component. In addition to other operations, the Logger component can be used to set up the Logger Level, such as DEBUG, ERROR or INFO. In the MicroLog API, the following log levels are available:
- static Level DEBUG: The DEBUG Level designates fine-grained informational events that are most useful to debug an application.
- static Level INFO: The INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
- static Level WARN: The WARN level designates potentially harmful situations.
- static Level ERROR: The ERROR level designates error events that might still allow the application to continue running.
- static Level FATAL: The FATAL level designates very severe error events that will presumably lead the application to abort.
A logger will only output messages that are of a level greater than or equal to it. As we can see in Table 1, if you set the Level (or global Level) to WARN, only WARN, ERROR and FATAL will be displayed.

To initiate your loggin process, first you can create a new Logger instance (as discussed ealier). There are many ways to do that, such as:
Logger logger = LoggerFactory.getLogger();
Creates a logger without a name
Logger logger = LoggerFactory.getLogger(String loggerName);
Creates a logger passing a logger name (loggerName variable)
Logger logger = LoggerFactory.getLogger(Class class);
Creates a logger with a class reference, such as your MIDlet class.
The process of logging requires that you define the messages output interface, such as to a file, to a console or to a bluetooth connection. Like Log4j, MicroLog also defines many kinds of appenders. RecordStoreAppender, where you can store your log messages in the RecordStore, BluetoothSerialAppender, where you can send your log messages to a bluetooth connection and FormAppender, where you can show the messages into a Form (LCDUI) interface.
For instance, the following code example shows how to send log messages to a Form (LCDUI). After creating a Logger reference (which has “Form Logger” as its name), we created a new FormAppender instance, passing our Form reference (which will display the log messages). log.addAppender(appender) can be used to associate our new appender reference. It is important to point out that you can create as many appenders as you wish, just calling addAppender(). As a result, you can send log messages, at the same time, to a File (through FileConnectionAppender) and to a datagram connection.
public class FormExample extends MIDlet {
public FormExample() {
this.d = Display.getDisplay(this);
this.f = new Form("Loggin");
this.log = LoggerFactory.getLogger("Form Logger");
this.appender = new FormAppender(this.f);
this.log.addAppender(this.appender);
this.log.debug("Constructed object!");
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {}
protected void pauseApp() {}
protected void startApp() throws MIDletStateChangeException {
this.d.setCurrent(this.f);
this.log.debug("Starting midlet...");
}
And the result is:

Note that the log messages were sent to the form reference that was created previously. The disadvantage of this approach is that when our application is closed, we will lost all log messages sent to the view. On the other hand, MicroLog offers other appenders that will allow to save them after closing the application, such as the RecordStoreAppender and the FileConnectionAppender. The following example shows how to store log messages in a file.
public class FileExample extends MIDlet {
private Logger log;
private Appender appender;
public FileExample() {
this.log = LoggerFactory.getLogger(FileExample.class);
this.appender = new FileConnectionAppender();
this.log.addAppender(this.appender);
this.log.debug("Constructed object!");
this.log.close();
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {}
protected void pauseApp() {}
protected void startApp() throws MIDletStateChangeException {}
}
If you are running the application in the WTK toolkit emulator, you can see the file output in appdb/”you_device_emulator_name”/filesystem/root1/microlog.txt.
To format a message, an Appender must have an associated Formatter object. MicroLog has two different formatters: (1) The SimpleFormatter is the default and the simplest formatter, and (2) the PatternFormatter offers more flexibility for choosing which information will appear in the log message. If you are not satisfied with them, you can also create your own formatter class and define your own message format.
The following steps show how to associate a formatter to an appender reference (in this context, the log messages will be sent to the console).
Logger log = LoggerFactory.getLogger("Logger With SimpleFormatter");
ConsoleAppender appender = new ConsoleAppender();
Formatter formatter = new SimpleFormatter();
appender.setFormatter(formatter);
log.addAppender(appender);
log.debug("Constructed object!");
The SimpleFormatter would print:
0:[DEBUG]-Constructed object!
That’s all. If you wish to get more code examples, take a look at here.
By katia
Article FileConnection
FileConnection (JSR75) allows access to removeable storage devices, such as externable memory cards that many of today’s devices support. It was specially developed based on mobile devices limitation so it is simple and lightweight.
FileConnection gives the functionality to create, remove directories and files, list directory content, set permissions, get file information, and perform I/O operations on files.
All you have to know before writing files in mobile devices
- Internal files (file systems on mobile devices or external memory cards) cannot be accessed and the reason is simple: Not all MIDP devices have file systems, and the creators may not want to expose them to applications.
- Developers don’t have permition to write anything directly on root directories because of security reasons.
- S60 devices have a private directory where files can be written. If your MIDlet will be used with S40 devices, be careful because you don’t have this directory. However, don’t worry there are other directories where you can write files (for example: file:///c:/My files/Images/, file:///c:/My files/Tones/, etc).
What does our sample Code do?
Our MIDlet is a simple example of how to write a text file. Running our MIDlet you will see a textbox where you can write something and save it. The file called “thiago.txt” will be saved inside photo directory in a folder named “bruno”. You can run the MIDlet with your favorite IDE or with your mobile device.
Used classes and information
To read and write files we used FileConnection class that was specially created based on mobile devices limitations. Our device have to implement JSR 75 to run this MIDlet properly.
As used in J2SE we need to use streams for connection. To open a connection we use “Connection.open()” and to open a strem we can use openInputStream(), openOutputStream(), openDataInputStream(), or openDataOutputStream().
Pay special attention to always check file’s or directory’s existence after a connection is established to determine if the file or directory actually exists. You can face exceptions or erros if you forget this. The same holds true using delete() method, and developers should close the connection immediately after deletion to prevent exceptions from accessing a connection to a non-existent file or directory.
Inside the method Connection.open() we can use “file:///c:/My files/Images/” or “System.getProperty(”fileconn.dir.photos”)”, but it is better to use System.get.Property because from device to device this path can change so you will face some problems. If you don’t know the list of properties you can check it here :http://wiki.forum.nokia.com/index.php/TSJ000306_-_MIDP:_System_properties
For futher information about FileConnection check this link: http://developers.sun.com/mobility/apis/articles/fileconnection/
Code
The full code is below to facilitate your understanding.
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class MIDletfinal extends MIDlet implements CommandListener {
Command save, exit;
TextBox text;
Display display;
public MIDletfinal() {
text = new TextBox("", "", 400, TextField.ANY);
save = new Command("Save", Command.SCREEN, 1);
exit = new Command("Exit", Command.EXIT, 1);
text.addCommand(save);
text.addCommand(exit);
text.setCommandListener(this);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// TODO Auto-generated method stub
}
protected void pauseApp() {
// TODO Auto-generated method stub
}
protected void startApp() throws MIDletStateChangeException {
display = Display.getDisplay(this);
display.setCurrent(text);
}
public void commandAction(Command arg0, Displayable arg1) {
if (arg0 == save) {
saveFile();
// Alert used for notify the user that the file had already been
// saved
Alert alert = new Alert("File saved.");
alert.setTimeout(Alert.FOREVER);
display.setCurrent(alert, this.text);
}
if (arg0 == exit)
;
{
try {
destroyApp(true);
this.notifyDestroyed();
} catch (MIDletStateChangeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void saveFile() {
try {
// Creating a connection.
FileConnection c = (FileConnection) Connector.open(System
.getProperty("fileconn.dir.photos")
+ "bruno/", Connector.READ_WRITE);
// Checking if the directoy exists or not. If it doesn't exist we
// create it.
if (c.exists()) {
System.out.println("existe");
} else {
System.out.println("nao existe");
c.mkdir();
c = (FileConnection) Connector.open(System
.getProperty("fileconn.dir.photos")
+ "bruno/thiago.txt", Connector.READ_WRITE);
// create the file
c.create();
// create an OutputStream
OutputStream out = c.openOutputStream();
// Get the user text
String userText = text.getString();
// write out the user's text into the file
out.write(userText.getBytes());
out.flush();
out.close();
// Never forget to close a connection or you can face problems.
// Pay attention here! If you close the connection before and
// later try to
// write something it will throw an exception.
c.close();
// Openning the file again and
// show what was saved in console.
c = (FileConnection) Connector.open(System
.getProperty("fileconn.dir.photos")
+ "bruno/thiago.txt", Connector.READ_WRITE);
//
InputStream in = c.openInputStream();
byte[] b = new byte[50];
in.read(b);
System.out.println(new String(b, 0, b.length));
}
} catch (Exception e) {
}
}
}
By katia
The Mobile Media API (MMAPI) is a flexible and powerful API that allows the rendering and capture of audio and video data. As a simple and lightweight optional package, it allows Java developers to gain access to native multimedia services available on a given device. This article describes how to use MMAPI to take snapshots, record videos and play music. For more information you can access here.
You can download the source code here.
You can download .jar here.
Warning
These examples below may not work on emulations.
Useful classes
In this example we need to use Manager and Player classes from audio package javax.microedition.media and concepts of thread.
The Manager class is the access point for obtaining system dependent resources such as Players for multimedia processing. A Player is an object used to control and render media that is specific to the content type of the data. Content types identify the type of media data. For example, here are a few common content types examples extracted from class Manager:
-
Wave audio files: audio/x-wav
-
AU audio files: audio/basic
-
MP3 audio files: audio/mpeg
-
MIDI files: audio/midi
-
Tone sequences: audio/x-tone-seq
If you want to know more about content types click here.
Once a Player is created an application can request Control objects that encapsulate behaviors to control the media playback, capture, and so forth. The Control objects available vary depending on the media supported by the player. Figure 1 shows how the Manager, Player, and Control classes relate.

Figure 1. Manager, Player, Control: Relationship of the
framework classes and interfaces used to manage
multimedia using the Mobile Media APIs.
A Player has five states : UNREALIZED, REALIZED, PREFETCHED, STARTED, and CLOSED. The following figure shows the five states and the state transition methods. For more information about Player’s states and transition methods click here.

Figure 2. Life of a Player: The State diagram below shows the Player lifecycle.
Taking pictures
In this example we take a picture and later we can see it on a Form. Before taking the picture we can see on display what the camera is capturing and choose the best position to take the picture.
Taking pictures requires one instance of Player, one instance of VideoControl and one instance of Display. VideoControl is used to control the video coming from the camera and display it in a Canvas/Form. First we create a instance of Player and set it to realize state.
// “capture://image” is used to indicate that we want a image.
// If we put another string here, we cannot use the method getSnapshot()
//in VideoControl .
Player mPlayer = Manager.createPlayer("capture://image");
mPlayer.realize();
Then we initialize one instance of VideoControl and append the video in the Canvas/Form, doing this the video become visible.
VideoControl mVideoControl=(VideoControl) mPlayer.getControl("VideoControl");
Form form = new Form("Camera form");
Item item = (Item) mVideoControl.initDisplayMode(
GUIControl.USE_GUI_PRIMITIVE, null); form.append(item);
We use the method getSnapshot() from VideoControl to capture pictures. This method returns a byte array corresponding to our picture. Displaying this image requires an instance of Image for append it on the screen. Later we set our player’s state to “close” and set to null our instance of VideoControl.
// Get the image.
byte[] raw = mVideoControl.getSnapshot(null);
Image image = Image.createImage(raw, 0, raw.length);
// Place it in the main form.
if (this.size() > 0 && this.get(0) instanceof StringItem)
this.delete(0);
append(image);
// Flip back to the main form.
mDisplay.setCurrent(this);
// Shut down the player.
mPlayer.close();
mPlayer = null;
mVideoControl = null;
Recording video
In this example we can record a video and after recording we can play it. As in the previous section recording videos requires one Player instance and one VideoControl instance. But in this case we change the string inside the method createPlayer to “capture://video”.
Player myPlayer = Manager.createPlayer("capture://video");
myPlayer.realize();
videoControl = (VideoControl) myPlayer.getControl("VideoControl");
Showwing on the screen what the camera is capturing requires create another class called “VideoCanvas”. Our MIDlet is not recording anything yet it is just showing what the camera is capturing.
In VideoCanvas we added one command called “cmd_capture”. When we action this command RecordCammera is called. RecordCamera is a thread responsible for recording a video and put the content in an byte array.
class RecordCamera extends Thread { // RECORDING!!!.....
RecordControl rc;
public void run() {
try {
rc = (RecordControl) myPlayer.getControl("RecordControl");
if (rc == null) {
return;
}
output = new ByteArrayOutputStream();
rc.setRecordStream(output);
rc.startRecord();
} catch (Exception e) {
e.printStackTrace();
}
}
//method called when the user stops the recording
public void StopRecord() {
try {
if (rc != null) {
rc.stopRecord();
rc.commit();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Displaying what was recorded involves getting the byte array created when we recorded the video, setting our player’s type, setting our player’s status to realize, setting the VideoControl again because kind of the data changed and finally display the byte array as a video using the class VideoCanvas.
ByteArrayInputStream bis = new ByteArrayInputStream(output.toByteArray());
myPlayer = Manager.createPlayer(bis, "video/3gpp");
myPlayer.realize();
videoControl = (VideoControl) myPlayer.getControl("VideoControl");
if (videoCanvas != null) {
videoCanvas.initControls(videoControl, myPlayer);
display.setCurrent(videoCanvas);
myPlayer.start();
}
Playing music
In our example we will play a mp3 music that is stored into a folder called “res”. Playing music requires a InputStream to store the music and one instance of Player. Our class has to implement Runnable because the music is played by another thread.
The string “audio/mpeg” inside the method createPlayer indicates that the music is in mp3 format.
InputStream in = getClass().getResourceAsStream("/123.mp3");
player = Manager.createPlayer(in, "audio/mpeg");
player.prefetch();
player.start();
By thiagosales
Web Services are software components that allow machine-to-machine interoperability and are platform and programming language independent. A WSDL (Web Service Description Language) file describes a web service encoded in XML format. The JSR 172 specification is an optional package that helps J2ME programmers to consume services inside a J2ME application and is designed to work with J2ME profiles based on either the Connected Device Configuration (CDC) or the Connected Limited Device Configuration (CLDC 1.o or CLDC 1.1).
To work with JSR 172, we need to generate “stub classes”, which will make all the “hard work” inside a J2ME application, such as the connection with the remote host. To do this, we will need to use the “Stub Generator” tool, available in the WTK (Wireless Toolkit) from Sun Microsystems. Once you have a WSDL file of your service, everything will be straightforward as we can see below.

Firstly, we set the WSDL filename or its URL in the upper field. Secondly, we set the stub classes output path, which can be the project’s “src” folder. Finally, we set the package output where the stub source code will be saved (in this case, br.Services). Press “Ok” to generate the stub classes.
In our example, we have a method called “echo” from MyService service, which receives a string and returns it. MyService_PortType_Stub class was generated in the mentioned process and it will open the connection with the remote host and make “echo” method available. A MyService_PortType_Stub instance will access “echo” method in a “localhost view”, however, in a background view, this method will serialize and send data to the remote host, as we can see below:
String echoStr = null;
MyService_PortType_Stub myStubObject = new MyService_PortType_Stub();
try {
echoStr = myStubObject.echo("J2ME Programming");
} catch (RemoteException e) {
e.printStackTrace();
}
this.formObj.append(new StringItem("Echo", echoStr));
The result is:

Albeit an easy solution, JSR 172 are not available for all devices. So, before using this JSR, be carefull the range of devices you are focusing to.
[]’s
By thiagosales
The XML (eXtensible Markup Language) is a very flexible standard for describing tree-based data format. It is playing an important role due to its way of achieving interoperability among different applications by sharing structured data and being able to define new elements by its users.
In the J2ME platform, there are some APIs for parsing XML file texts. Below we can see some of the available APIs for MIDP:
Although existing many solutions for parsing XML file format in J2ME platform, NanoXML seams to be the easist one to do that (in my opinion, despite the lack of a good documentation!)
The best way of understanding how NanoXML works is though an example. Consider the following XML file:
<BreakFast_Menu>
<food Type="Mass">
<name>Macaroni</name>
<price>3.0</price>
<description>Fetucinni</description>
<calories>213</calories>
</food>
<food Type="desert">
<name>chocolat</name>
<price>6.0</price>
<description>laka</description>
<calories>334</calories>
</food>
</BreakFast_Menu>
The example above describes a menu containing two types of food (mass and a type of desert). Though NanoXML API, I will show you how to create and read an XML file with this kind of information. The code below demonstrates how to create the XML file. For each new food, we create a new child and adds it to the tree structure (mainElement):
private kXMLElement createElement(String name, String str) {
kXMLElement element = new kXMLElement(name);
element.setContent(str);
return element;
}
public void addNewFood(String foodName, double price, ...) {
kXMLElement child = new kXMLElement("food");
child.addChild(createElement("name", foodName));
child.addChild(createElement("price", String.valueOf(price)));
child.addChild(createElement("description", description));
child.addChild(createElement("calories", String.valueOf(calories)));
child.addProperty(type, typeName);
mainElement.addChild(child);
}
... ....
addNewFood("Macaroni", ... ...)
addNewFood(Chocolat", ... ...)
To save this new data, we will use JSR 75 (FileConnection).
private void initFileSystem() {
connection = (FileConnection)Connector.open("file:///"+
rootFileSystem+"Foods/");
if(!connection.exists())
connection.mkdir();
connection = (FileConnection) Connector.open("file:///"+
rootFileSystem+"Foods/food.xml", Connector.READ_WRITE);
if(!connection.exists())
connection.create();
}
private void save() {
try {
OutputStream out = connection.openOutputStream();
out.write(mainElement.toString().getBytes());
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
To retrieve the information just saved, we just open an input stream reader and apply the data to a KXMLElement reference, as follows:
private readFile() {
mainElement.parseFromReader(new InputStreamReader(
connection.openInputStream()));
}
public void readMenu(kXMLElement element) {
Enumeration e = element.enumerateChildren();
kXMLElement childElement = null;
while(e.hasMoreElements()) {
childElement = (kXMLElement) e.nextElement();
if(childElement.getTagName().equals("food")) {
this.formView.append(new StringItem("Tipo",
childElement.getProperty("Tipo")));
readMenu(childElement);
} else {
this.formView.append(new StringItem(
childElement.getTagName(), childElement.getContents()));
}
}
}
getTagName() and getContents() methods return the tag name (”name”, “price”, “calories”) and it’s values, respectively. On the other hand, childElement.getProperty(String) returns an attribute tag value, desert or mass, for instance.

By cayo
Floggy framework is a totally Brazilian persistence framework for J2ME platform, licensed by Apache License version 2.0, with a view to facilitating the persistence of objects for J2ME applications. The traditional RMS persists only array of bytes, making it difficult to implement for the persistence of more complex objects.
To persist an object through the framework it is only necessary to implement the interface net.sourceforge.floggy.persistence.Persistable. However there are only a few objects supported and some restrictions.
Supported types
- All primitive types: boolean, byte, char, double, float, int, long and short;
- Package java.lang: Boolean, Byte, Character, Double, Float, Integer, Long, Short, String, StringBuffer;
- Package java.util: Calendar, Date, Stack, Vector;
- All objects which implements net.sourceforge.floggy.persistence.Persistable;
- One-dimensional array of any supported type like byte[], Integer[], Date[] or Persistable[].
- Coming soon : java.util.Hashtable
Restrictions
- Bidirectional relationships;
- n:n relationships.
Architecture:
The architecture is divided into two levels: compilation/packaging and application. In the compiling level, the waever is responsible for receiving the bytecode and unifies it to the code of persistence. In packaging, the API framework floggy is “pushed” into the application logical. Finally, during the implementation step, the framework Floggy can be used through its methods making persistence, removals, object editions and queries tasks on the implementation of RMS.
source: http://floggy.sourceforge.net/
Instalation in eclipse IDE:
To use the framework floggy in the eclipse is quite simple. The installation can be done in the self IDE by following the below steps:
- help >> Software Updates >> Find and Install >> Search for new features to install
- Next >> New remote Site >> http://floggy.sourceforge.net/eclipse/
More details: http://floggy.sourceforge.net/
After installing, to use the floggy, click with the right mouse button on the project and enable the option of floggy. If there is no option, it should have happened a problemduring the installation process. Perform all steps again.
Here is a small sample code that persists an object with the floggy persistence framework:
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.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import net.sourceforge.floggy.persistence.FloggyException;
import net.sourceforge.floggy.persistence.PersistableManager;
public class ExampleFloggy extends MIDlet implements CommandListener {
private TextField tfield;
private Command savecmd;
private Display display;
private Form form;
private TextField tfieldN;
private Command exitcmd;
public ExampleFloggy() {
tfield = new TextField("name:", "", 15, TextField.ANY);
tfieldN = new TextField("age:", "0", 15, TextField.NUMERIC);
savecmd = new Command("save", "save file", Command.ITEM, 0);
exitcmd = new Command("exit","exit",Command.EXIT,1);
form = new Form("Floggy example.");
form.append(tfield);
form.append(tfieldN);
form.addCommand(savecmd);
form.addCommand(exitcmd);
form.setCommandListener(this);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
notifyDestroyed();
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
display = Display.getDisplay(this);
display.setCurrent(form);
}
public void commandAction(Command cmd, Displayable arg1) {
if (cmd == savecmd) {
Date dateOut = new Date(tfield.getString(), Integer.parseInt(tfieldN
.getString()));
int id;
try {
id = PersistableManager.getInstance().save(dateOut);
Date dateIn = new Date();
PersistableManager.getInstance().load(dateIn, id);
form.append(dateIn.toString());
} catch (FloggyException e) {
e.printStackTrace();
}
}else if (cmd==exitcmd){
try {
destroyApp(true);
} catch (MIDletStateChangeException e) {
e.printStackTrace();
}
}
}
}
In the MIDlet class above, the constructor creates a form with two fields: name and age. When completed filled and clicked the command ’save file’, it launched an event for the very class triggering the method commandAction (). The commandAction () handles the event retrieving the command driven. As the triggered command was the ’save file’, it will createan object Date and will be persisted through the framework Floggy.
The class below is the Date class, which an object was persisted in the sample midlet. Note that it implements the interface Floggy.persistence.Persistable. It is mandatory for persisting the object using Floggy. Just as in JSE, transient variables are not persisted.
import net.sourceforge.floggy.persistence.Persistable;
public class Date implements Persistable {
private String name;
private int age;
private transient int num;
public Date() {
}
public Date(String name, int age) {
this.nome = name;
this.idade = age;
}
public String toString() {
return "";
}
}