Friday, February 20, 2009

J2ME: Browsing File System on Mobile Device using FileConnection APIs

There can be application where we need to browse through different files on our mobile phone, File Viewer, File Uploader are few to name. Here I’m going to provide a complete program that helps you browse through your file on mobile device and therefore helps you develop more sophisticated applications using it. Its based on J2ME FileConnection APIs (JSR 75) which is a optional package within MIDP. Though the midlet code provided is quite simple and straightforward and needn’t much explanation, however, please consult JavaDoc for FileConnection API for details which is available here. The midlet allows the user to browse through file system on the Java Enabled devices.
There are some other ways to open file connection but they open connection to specific folders e.g. System.getProperty("fileconn.dir.photos") which retruns the path to ‘photos’ folder to which connection can be opened. Moreover this method might not be supported by the some of the devices. In my case, I tried this approach for SE K800i and Nokia 6630 where it worked but not for Motorola V3. In that case, the approach outlined by the code snippet here is more suitable.

Note: FileConnection APIs (JSR 75) being an optional package of MIDP might not be available on the all the devices. So you’ll have to check if the particular device has support for it using system property System.getProperty("microedition.io.file.FileConnection.version").


/**
*
* @author Atifs
*/
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

public class BrowserLauncher extends MIDlet implements CommandListener {

private Display display;
private final Command CMD_EXIT = new Command("Exit", Command.EXIT, 1);
FileSysBrowser fsb;

public BrowserLauncher() {
display = Display.getDisplay(this);
}

protected void startApp() {
fsb = new FileSysBrowser(this);
fsb.showFiles();
}

public Display getDisplay() {
return display;
}

protected void destroyApp(boolean unconditional) {
}

protected void exitApp() {
destroyApp(false);
notifyDestroyed();
}

protected void pauseApp() {
}

public void commandAction(Command c, Displayable d) {
if (c == CMD_EXIT) {
exitApp();
}
}
}


/**
*
* @author Atifs
*/
import java.io.IOException;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
import java.util.*;

public class FileSysBrowser extends List implements CommandListener {
// 'DATHHEAD' holds the root, please see javadoc for details
// This may vary for different devices.
String DATHHEAD = "file:///";
private Command CMD_SUBMIT = new Command("Open", Command.ITEM, 0);
private Command CMD_EXIT = new Command("Exit", Command.EXIT, 1);
private Command CMD_BACK = new Command("Back", Command.BACK, 1);
private BrowserLauncher fl;
private String path = null;
private String selectedItem = null;
FileConnection srcconn = null;

public FileSysBrowser(BrowserLauncher fl) {
super("File List", List.IMPLICIT);
addCommand(CMD_SUBMIT);
addCommand(CMD_EXIT);
addCommand(CMD_BACK);
setCommandListener(this);
this.fl = fl;
}

protected void showFiles() {
if (path == null) {
Enumeration e = FileSystemRegistry.listRoots();
path = DATHHEAD;
setTitle(path);
while (e.hasMoreElements()) {
String root = (String) e.nextElement();
// you can pass an 'image' object instead of 'null' to
// append method
append(root, null);
}
fl.getDisplay().setCurrent(this);
} else {
if (selectedItem != null) {
setTitle(path + selectedItem);
} else {
setTitle(path);
}
try {
// works when users opens a directory
if (selectedItem != null) {
srcconn = (FileConnection) Connector.open(path + selectedItem, Connector.READ);
} else // works when presses 'Back' to go one level above/up
{
srcconn = (FileConnection) Connector.open(path, Connector.READ);
}
// Check if the selected item is a directory
if (srcconn.isDirectory()) {
if (selectedItem != null) {
path = path + selectedItem;
selectedItem = null;
}
Enumeration files = srcconn.list();
while (files.hasMoreElements()) {
String file = (String) files.nextElement();
append(file, null);
}
//
fl.getDisplay().setCurrent(this);
try {
if (srcconn != null) {
srcconn.close();
srcconn = null;
}
} catch (IOException ex) {
ex.printStackTrace();
}
}//if (srcconn.isDirectory())
else {
// 'else' is unnecessary here, i just out here to signify the
// fact that you handle the selected item if it is a 'file'
// instead of a directory. For example you can display a file
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

protected String getDirectoryName() {
int select = getSelectedIndex();
return getString(select);
}

public void commandAction(Command c, Displayable d) {
if (c == CMD_SUBMIT) {
selectedItem = getDirectoryName();
deleteAll();
showFiles();
}
if (c == CMD_EXIT) {
fl.exitApp();
}
if (c == CMD_BACK) {
if (!path.equals(DATHHEAD)) {
int slashIndex = path.lastIndexOf('/', path.length() - 2);
path = path.substring(0, slashIndex + 1);
if (path.equals(DATHHEAD)) {
path = null;
}
deleteAll();
showFiles();
}
}
}
}


Disclaimer: The code provided has been written for exploratory purposes, not following the official guideline of Software Engineering and therefore has not been tested thoroughly. However, you are FREE to use the code for any purpose and be aware to test it before using for production uses!!!

6 comments:

Anonymous said...

can we access all images listed in Gallary folder..Am getting an error while opening images in Nokia 40 plattform emulattor saying"file format not support".pls reply

Atif said...

Please elaborate a little more, I cant figure out what you are facing. It did work for me on the mobile phones i tried on as i mentioned in the original post. It should work for Gallery folder as well, as far as I know. The code in the post only helps to browse through directory when it comes to a 'file' i.e. jpg, png etc, you have to write your own code to handle that part. I guess you are trying open some file (in your part of code) that is not supported. That's why you are getting that error.

M.M.M.R.B. Mudannayake said...

Hey Atif,

Thanks for this amazing program. I am a newbie to J2ME and im wondering how can i get the path of a selected file..?

I need to pass that path into ; let's say to an alert. What needs to be done?

Hope you will reply ASAP. Thanks again for this program and for the reply in advance.

Atif said...

Please look through the provided code for path and selectedItem String variables, they together form the complete path.

Lokesh Mittal said...

I m not able to use file connection api in j2me. when i try to import javax.microedition.io.file package the it is giving the error as this cant be resolved......plz solve this problem

Atif said...

please use
import javax.microedition.io.file.*;