Skip to main content

Working with the Java ME FileConnection API on Physical Devices

March 29, 2007

alt="{cs.r.title}" border="0" align="left" hspace="10" vspace="0">
name="title">

name="id_author2" before=" and " hrefaction="pub">

/>

Cell phones, like computers, have a well-defined internal file
structure to store information. Phone books, images, music, and even
applications are stored in various folders under a root directory.
However, the classes in the core "http://java.sun.com/javame/index.jsp">Java ME packages cannot
fully use these folders and files. "http://jcp.org/en/jsr/detail?id=75">JSR 75 provides an
optional API that enables MIDlets to access the internal
directories and files in a mobile phone.

In this article we'll use the classes in JSR 75 to build a
simple application, FileTester, that moves images from a mobile
handset into a server. The emphasis here will mainly be on some of
the intricacies involved in handling files in real devices. I
assume the reader is familiar with Java ME. In order to build and
use the application developed here, the following resources will be
required:

There are a number of articles and books on installation and use
of WTK22. "http://www.mobilefish.com/emulators/j2me_wt/j2me_wt_quickguide_22_build3.html">
This tutorial
is one of them. Tomcat is a servlet container and
will be used as a server for this application. You will need to
download and install Tomcat on your PC to run the application. If
you are new to Tomcat and would like some help to download and
install it, I would suggest that you refer to Marty Hall's

tutorial
.

In order to run the example, you will need a mobile phone that
implements the FileConnection API and the system property used in
this article, has a pre-assigned folder for images and is internet-capable. You will also need a suitable data plan for your phone.
Your PC should also be connected to internet and should have,
preferably, a static IP address.

The Need for the FileConnection API

Even without the FileConnection (FC) API, it is possible to
read from files using classes available in Java ME. The FC API is
required for manipulating files in all the other ways listed in the
documentation. The FC API also comes in handy in browsing and
locating predefined folders as explained in the discussion on the
example MIDlet.

The API for file access is a part of JSR 75, the rest of the JSR
being devoted to handling the PIM database like the Phonebook. The
JSR 75 is an optional API and, therefore, cannot be expected on
every device. The first step in running an application based on the
FC API is to ascertain whether it is supported on a given device. To
do this, use the following statement:


String versioninfo = System.getProperty
    ("microedition.io.file.FileConnection.version");

If the platform supports the API, the version number (currently
1.0) will be returned. Otherwise null will be
returned. A short MIDlet (CheckAPI) is available in
the Resources section for checking API
availability. You can build this MIDlet and run it on a phone to
check if the FC API is available. Figure 1 shows the screenshot of
CheckAPI being run on the WTK22 emulator.

<br "Checking API availability" width="250" height="333" />
Figure 1. Checking API availability

Theoretically, an FC-API-based application can be expected to
run once a version number is returned. In practice, this may not be
the case. Some manufacturers may restrict the actual use of this
API to signed MIDlets only.

Before we plunge into our example application, let's take a
quick look at the classes and interfaces that make up the API. The
FC API is contained in the javax.microedition.io.file
package and incorporates the following
classes/interfaces:

  • interface FileConnection: Defines the process of
    accessing the onboard and removable file systems on a device.
  • interface FileSystemListener: Enables an
    application to sense when a file system (like a card) is added or
    removed.
  • class FileSystemRegistry: Central registry for
    file system listeners.
  • class ConnectionClosedException: Thrown when an
    application tries to operate on a closed file connection.
  • class IllegalModeException: Thrown when an
    application with proper security clearance tries to access a file
    with a wrong mode. For example, if an application has opened a file
    connection in READ mode but tries to write to the connection,
    this exception will be thrown.

It would be a good idea to download the "http://jcp.org/aboutJava/communityprocess/final/jsr075/index.html">
API documentation
for reference.

Opening a connection to a file is similar to opening a network
connection. The method used is Connector.open(), with
the resulting Connection object being cast to
FileConnection (where filename includes the path):


FileConnection fc = 
    (FileConnection)Connector.open(String filename);

The process for accessing a file is settling on a root folder
and opening a connection to it. The listRoots() method
of the FileSystemRegistry class returns an enumeration
listing all available file system roots. Obviously, an application
can start from here and go on to explore the file system on a
device. This can be done by opening a connection to a root and
listing its contents:


FileConnection fc = 
    (FileConnection)Connector.open(String root);
Enumeration contents = fc.list();

However, there are other ways of getting straight to a specific
folder, as we shall see when we discuss our example MIDlet.

Once a connection to a file has been opened, an input or output
stream needs to be obtained so that the file can be read from or
written into. Note that many other operations (rename, delete,
create, and so on) are possible. For a complete list of operations,
refer to the API documentation. The fundamentals of the FC API have
been explained with great clarity in an "http://developers.sun.com/techtopics/mobility/apis/articles/fileconnection/">
article by Qusay Mahmoud
.

The handling of files in a mobile device is influenced by the
security models of Java ME as well as those adapted by device
manufacturers. Applications running on MIDP-2.0-compliant handsets
are subject to security restrictions applicable to their domain
classification. MIDlets like FileTester would be
classified as "untrusted," since they do not incorporate verifiable
security credentials. At runtime, such MIDlets have to explicitly be granted
permission by the user to access files.

In addition to the above, applications are also subject to
restrictions placed by device manufacturers. Some folders may not
be accessible to all user applications. Such restrictions may
differ from device to device and it is necessary to study
manufacturers' documentation in order to make an application able
to operate on as wide a selection of platforms as possible. More on
this when we discuss FileTester.

MIDlets have an alternative to files for storing information--record stores. It must be emphasized that the FC API
cannot access record stores.

The Example

FileTester is an application that uploads images
from a mobile phone to a server. A simple servlet is also included
to complete the demonstration.

The application has the following classes to do the actual
work:

  • FileTester: The MIDlet.
  • FileSelPage: The class that reads and shows the
    contents of the system folder that contains photos.
  • SendFile: The class that reads the image file
    and sends it to the server.

In addition, it has three more classes that serve to display
messages:

  • MessageCanvas: A window-like screen to display
    messages.
  • TextFormatter: A companion class for
    MessageCanvas that breaks long strings into lines that can fit into
    the screen.
  • CommMessage: A subclass of MessageCanvas that
    can abort an ongoing communication task.

When the MIDlet is launched, its startApp() method
is invoked after the constructor has returned. In this case, the
startApp() method instantiates
FileSelPage, which, as mentioned above, reads the
contents of the folder in which images are stored (we'll call it
the IMAGES folder from now on) and displays the list for
selection.

The FileSelPage class is of interest to us and we
shall look at it in some detail.

In order to display the contents of IMAGES, the proper folder
has to be located. There are several options for this, such
as:

  • The path to IMAGES could be hardcoded into the class. This is
    not a good option, because different models of handsets store images
    in different folders. So the actual name of the IMAGES folder and its
    path will vary from phone to phone. Obviously, hardcoding the
    filename will make the application usable only on a specific
    handset.

  • As we have seen in the preceding section, it is possible to
    start at the root of the internal file system of the device and
    navigate manually through the chain of folders until we come to the
    desired folder. This exploratory action could be built into the
    application the way code for attaching files to an email allows us
    to browse. This too has disadvantages. For one thing, this manual
    browsing on a mobile would be tedious. The other problem is that on
    some devices, access to the root of the internal file system is
    restricted and this would prevent the browsing action.

The method adapted for FileSelPage uses the
getProperty() method of System class. In
many devices the following call to getProperty()
returns the path to the folder that the device uses for saving
photos:


String srcdir = System.getProperty("fileconn.dir.photos");

This avoids the disadvantages mentioned above. Note that
properties are available for all commonly predefined folders. For
more information, refer to Java ME Developer's Library 1.2, which can
be downloaded from "http://www.forum.nokia.com/info/sw.nokia.com/id/35cee3ff-9053-4892-b413-64c6165032cc/Java_ME_Developers_Library_v1_2.zip.html">
Forum Nokia
.

Once the folder has been located, a connection is opened to it
and an Enumeration object containing a list of the
files in the photos folder is obtained. All the items in
the Enumeration object are then cast to
Strings and are appended to FileSelPage,
which extends List:


if (srcdir != null)
{
    //if there is such a folder open connection to it
    srcconn = (FileConnection)Connector.open(srcdir);

    //get a list of its contents and add to list
    Enumeration files = srcconn.list();
    while (files.hasMoreElements())
    {
        String file = (String) files.nextElement();
        append(file, null);
    }

    if(size() == 0)
    {
        //the list is empty
        append("The folder is empty", null);
        removeCommand(CMD_SUBMIT);
    }

    //successful
    return "Done";
}

When the showFiles() method of
FileSelPage returns, FileTester displays
FileSelPage. The user can now select the item to be
uploaded and activate the Submit command. When this is
done FileTester starts a thread--SendFile--for transmitting the file to the
server.

SendFile again locates the folder and then the
selected file. It then opens an HTTP connection to the server,
opens the required input and output streams, reads the file, and
transmits it over the HTTP connection. Finally, it reads and
displays the response from the server.

The servlet, FCServlet, is very simple. When it is
initiated, it checks to see if there is an Album folder under
C:\. If such a folder does not exist, then it
creates the folder.

When a client logs in and the doPost() method is
invoked, input and output streams are opened. The first information
to be read is the name of the image file. Once the file name is
known a new file is set up in the Album folder and a
FileOutputStream is opened on this file. Next, the size
of the file is read and the input stream is piped into the file
output stream so that the incoming file gets copied. Finally, a
response is sent to the client.

Compatibility Issues

Any application based on an optional API cannot be expected to
run on all devices, as such an API is unlikely to be universally
implemented. We have also seen earlier that the availability of the
FC API does not, by itself, guarantee that an application using
this API will be permitted to run on a given handset. Further, we
must remember that the use of system properties for locating a
folder as shown above is not supported by all phones. Fortunately, a
large number of devices using the S60 and S40 platforms (from Nokia
and some other manufacturers) do support this functionality. The
"http://developer.sonyericsson.com/site/global/docstools/java/p_java.jsp?cc=gb&lc=en&ver=4000&template=ps1&zone=ps&lm=ps1">
developer guidelines
from Sony Ericsson shows that this
manufacturer too provides system properties for folder access. But
there are other manufacturers that do not. We can see, therefore, that
to implement a folder location method that can be used more
universally, a two-pronged approach may be advisable:


String srcdir = System.getProperty("fileconn.dir.photos");
if (srcdir != null)
{
        //use the method shown above
        .
        .
        .
}
else
{
        //start from the root and browse manually
}

The devices that do not allow the method demonstrated here
usually do not restrict access to file system roots, so the
fallback should work. I would also like to point out that I have
worked here on the assumption that the folder to access is located
in the phone memory and not on an add-on file system like a
micro-SD card. If this assumption is invalid, browsing may be the
only option. This means the user should be able to decide whether
to override the system property approach even though it may be
supported by her phone.

Today, using the FC API is a bit complicated. But there is good
news for the future: JSR 75 has been made mandatory under "http://jcp.org/en/jsr/detail?id=248">Mobile Service
Architecture
(MSA), the next generation of the Java ME
specification. As MSA takes root, the FC API will be available on
all new Java-compliant mobile devices and, hopefully, the gray
areas will be gradually resolved into black or white.

Conclusion

This article shows a way to simplify access to predefined
folders using a facility not mandated by the FC API but available
on many popular phones. It also points out a number of issues that
one has to contend with when coding an application using the FC API
to be deployed on real physical devices.

FileTester has the features that are just essential
to illustrate the subject at hand. It is possible to enhance it in
many ways--some minor and some not so minor--to make it more
usable and meaningful. The servlet, to consider one example, may be
modified such that the incoming file is copied into the target
folder only after the entire file is received. This will ensure
that an interrupted internet connection does not result in a
partially copied file.

Not to be forgotten is the matter of user authentication. Some
sort of password protection should be considered if the servlet is
kept active for extended periods.

Finally, note that the FC API allows us to reverse the direction
of information flow quite easily. So it is relatively simple to
create an upload/download package for sharing mobile content.

Resources

cellpadding="0" cellspacing="0" width="100%" bgcolor="#000000">
src="http://today.java.net/im/a.gif"
width="1" height="1" border="0" alt=" "
>
Biswajit Sarkar is an electrical engineer with specialization in Programmable Industrial Automation. Biswajit is the author of "LWUIT 1.1 for Java ME Developers" published by PACKT Publishing.
Related Topics >> Mobility   |