NHCAD
NHCAD

Fun Projects in Mechanical Design & Custom Programming
Lebanon, NH


NHCAD Home

CAD(Computer Design)
Free CAD Software
SolidWorks
SolidWorks Macros
SolidWorks Custom Properties

CNC / Steppers
5804 Stepper Driver Circuit
Floppy Stepper Motors
DIY CD Plotter
DIY CNC Mill

J2ME Mobile Programs
Sprtint Wireless Toolkit
Device / ESN Activation
Favorite Apps
JPGViewer

1964 Oday Javelin
1964 Oday Javelin
Centerboard
Rudder
Tiller
Transom
Hull
Topside
Deck
Details
First Sail

JPGVIEWER

JPGVIEWER was developed using Sprint Wireless Toolkit for my V9m (Razr2). Because I have been dissapointed with Sprint's user interface, this app allows me to put pictures into folders and view them in organized sets - full screen! You should crop/resize photos before placing them on your mobile device. This is only a viewing utility, not an editor. - Joe Jones




CONTROLS
    Browsing Files D-Pad
  • UP - previous file in list
  • DOWN - next file in list
  • FIRE - open currently selected file full screen
    Full Screen Canvas D-Pad
  • UP - skip 10 previous files
  • DOWN - skip 10 next files
  • RIGHT - view next image in folder
  • LEFT - view previous image in folder
  • FIRE - return to file browser


I used the Sprint Wireless Toolkit to develop, build, and run this code. I am rather new to J2ME programming and relied heavily on existing code snippets to put this together.


INSTALLATION: jpgviewer needs to access protected APIs on your sprint phone. Note this is not a hack and will not void any waranty or service contract you have with Sprint. As a developer you will be given access to functions already in the phone.
  1. Register as a Sprint Developer http://developer.sprint.com/site/global/home/p_home.jsp
  2. Unlock protected API JSR-75 on your phone (they call it Device/ESN Activation) http://developer.sprint.com/site/global/develop/activation_device/p_device_activation.jsp
  3. Install the signed version of jpgviewer hosted at http://www.getjar.com/products/14744/jpgviewer


If you are able to install midlets yourself, you may find these files helpful:
Download jad/jar files unsigned jpgviewer_unsigned.zip
Download jad/jar files signed jpgviewer_signed.zip

JPGVIEWER Source Code

/*
*
* Modified 7/16/08 to work with Sprint Instinct (Samsung M800 - 240x430 res)
*
* jpgviewer.java
*
* Is a simple J2ME Midlet developed for Sprint V9m to browse to and open
* jpg files and scroll through subsequent files.  All files in the folder
* are assumed to be image files and similar resolution to the device
*
* Joe Jones - Feb 20, 2008
* sourcecode: http://www.nhcad.com/j2me/jpgviewer/
*
* References
* PDAPDemo.java, ViewPng2.java, ImageDemoCanvas.java
*
*/


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

public class jpgviewer extends MIDlet implements CommandListener {

    private Display display;
    private Form mainForm;
    private ImageItem imageItem; 
    
    private String currDirName;

    private Command view = new Command("View", Command.ITEM, 1);
    private Command back = new Command("Back", Command.BACK, 2);
    private Command exit = new Command("Exit", Command.EXIT, 3);

    private Image dirIcon, fileIcon;
    private Image[] iconList;

    private TestCanvas myCanvas;
    private Image image;

    int count;
    int maxfilecount;
    List browser;


    /* special string denotes upper directory */
    private final static String UP_DIRECTORY = "..";

    /* special string that denotes upper directory accessible by this browser.
     * this virtual directory contains all roots.
     */
    private final static String MEGA_ROOT = "/";

    /* separator string as defined by FC specification */
    private final static String SEP_STR = "/";

    /* separator character as defined by FC specification */
    private final static char   SEP = '/';

    public jpgviewer() {
        currDirName = MEGA_ROOT;
        try {
            dirIcon = Image.createImage("/icons/dir.png");
        } 
        catch (IOException e) {
            dirIcon = null;
        }
        try {
            fileIcon = Image.createImage("/icons/file.png");
        } 
        catch (IOException e) {
            fileIcon = null;
        }
        iconList = new Image[] { fileIcon, dirIcon };
    }

    public void startApp() {
  
        try {
            showCurrDir();
        } 
        catch (SecurityException e) {
            Alert alert = new Alert("Error",
                "You are not authorized to access the restricted API",
                null, AlertType.ERROR);
            alert.setTimeout(Alert.FOREVER);
            Form form = new Form("Cannot access FileConnection");
            form.append(new StringItem(null,
                "You cannot run this MIDlet with the current permissions. "
                + "Sign the MIDlet suite, or run it in a different security domain"));
            form.addCommand(exit);
            form.setCommandListener(this);
            Display.getDisplay(this).setCurrent(alert, form);
        } 
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean cond) {
        notifyDestroyed();
    }



    /**
     * Show file list in the current directory .
     */
    void showCurrDir() {
        Enumeration e;
        FileConnection currDir = null;

        try {
            if (MEGA_ROOT.equals(currDirName)) {
                e = FileSystemRegistry.listRoots();
                 browser = new List(currDirName, List.IMPLICIT);
            } 
            else {
                currDir=(FileConnection)Connector.open("file://localhost/" + currDirName);
                e = currDir.list();
                browser = new List(currDirName, List.IMPLICIT);
                // not root - draw UP_DIRECTORY
                browser.append(UP_DIRECTORY, dirIcon);
            }

            maxfilecount = 0;
            while (e.hasMoreElements()) {
                String fileName = (String)e.nextElement();
                if (fileName.charAt(fileName.length()-1) == SEP) {
                    // This is directory
                    browser.append(fileName, dirIcon);
                } 
                else {
                    // this is regular file
                    browser.append(fileName, fileIcon);
                    maxfilecount = maxfilecount + 1;
                }
            }

            browser.setSelectCommand(view);
            browser.addCommand(exit);
            browser.setCommandListener(this);

            if (currDir != null) {
                currDir.close();
            }

            Display.getDisplay(this).setCurrent(browser);
        } 
        catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }


    /*--------------------------------------------------
    * Show the current directory
    *-------------------------------------------------*/
    void traverseDirectory(String fileName) {

        if (currDirName.equals(MEGA_ROOT)) {
            if (fileName.equals(UP_DIRECTORY)) {
                // can not go up from MEGA_ROOT
                return;
            }
            currDirName = fileName;
        } 
        else if (fileName.equals(UP_DIRECTORY)) {
            // Go up one directory
            // TODO use setFileConnection when implemented
            int i = currDirName.lastIndexOf(SEP, currDirName.length()-2);
            if (i != -1) {
                currDirName = currDirName.substring(0, i+1);
            } 
            else {
                currDirName = MEGA_ROOT;
            }
        } 
        else {
            currDirName = currDirName + fileName;
        }
        showCurrDir();
    }


    public void commandAction(Command c, Displayable d) {       
        if (c == view) {
            List curr = (List)d;
            count = curr.getSelectedIndex();
            
            final String currFile = curr.getString(curr.getSelectedIndex());
            new Thread(new Runnable() {
                public void run() {
                    if (currFile.endsWith(SEP_STR)||currFile.equals(UP_DIRECTORY))
                    {
                        traverseDirectory(currFile);
                    } 
                    else {
                        ShowFullScreen();
                    }
                }
            }).start();
         
        } 
        else if (c == back) {
            showCurrDir();
        } 
        else if (c == exit) {
            destroyApp(false);
        } 
    }


    public void ShowFullScreen() {
        System.out.println("show full screen" + count);
        myCanvas = new TestCanvas();
        myCanvas.setFullScreenMode (true);
        myCanvas.setCommandListener (this);
        Display.getDisplay (this).setCurrent (myCanvas);
    }


    public class TestCanvas extends Canvas{
        
        private String myActionMsg="Use the joystick!";
        
        protected void keyPressed(int keyCode){
            int myGameAction = getGameAction(keyCode);

             switch(myGameAction){
                case UP:  {
                    // same as 2 on keypad
                    count = count - 10; 
                    if (count < 1) count = maxfilecount;
                    break;
                }
                case DOWN: {
                    // same as 8 on keypad
                    count = count + 10; 
                    if (count > maxfilecount) count = 1;
                    break;
                }
                case LEFT:  {
                    // same as 4 on keypad
                    count = count - 1; 
                    if (count < 1) count = maxfilecount;
                    break;
                }
                case RIGHT: {
                    // same as 6 on keypad
                    count = count + 1; 
                    if (count > maxfilecount) count = 1;
                    break;
                }
                case FIRE: {
                    // same as 5 on keypad or home button on instinct
                    showCurrDir();
                }
                case GAME_A: {
                    // same as 1 on keypad
                    System.out.println("Game A");
                    break;
                }
                case GAME_B: {
                    // same as 3 on keypad
                    System.out.println("Game B");
                    break;
                }
                case GAME_C: {
                    //same as 7 on keypad
                    System.out.println("Game C");
                    break;
                }
                case GAME_D: {
                    // same as 9 on keypad
                    System.out.println("Game D");
                    break;
                }
                case 0: {
                    // same as */0/# on keypad or back button on instinct
                    System.out.println("0");
                    count = count + 1; 
                    if (count > maxfilecount) count = 1;
                    break;
                }
            }

            repaint();            
        }

        
        public void paint(Graphics g){
            String fileName = (browser.getString(count));

            try {
                image = getImage("file://localhost/" + currDirName + fileName);
            }
            catch (Exception e) { 
                System.err.println("Msg: " + e.toString());
            }

            // paints a white background in case picture is smaller than display
            g.setColor(0xf0f0f0);
            g.fillRect(0,0,getWidth(),getHeight());

            g.drawImage(image, 0, 0, Graphics.TOP | Graphics.LEFT);
        }
    }


    /*--------------------------------------------------
    * Open connection and download png into a byte array.
    *-------------------------------------------------*/
    private Image getImage(String url) throws IOException {
        InputStream iStrm = (InputStream) Connector.openInputStream(url);
        Image im = null;
        try {
            ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
        
            int ch;
            while ((ch = iStrm.read()) != -1)
                bStrm.write(ch);

           // Place into image array
           byte imageData[] = bStrm.toByteArray();      
              
            // Create the image from the byte array
            im = Image.createImage(imageData, 0, imageData.length);        
        }

        finally {
            // Clean up
            if (iStrm != null)
            iStrm.close();
        }
        return (im == null ? null : im);
    }

}