2

我在这方面花了很长时间,但还没有成功。在我捕获图像并发送到服务器的应用程序中,我得到下面的 NullPointerException;

java.lang.NullPointerException:   0

at Files.CameraMIDlet.snap(CameraMIDlet.java:120)
at Files.CameraForm.commandAction(CameraForm.java:116)
at javax.microedition.lcdui.Display$ChameleonTunnel.callScreenListener(), bci=46
at com.sun.midp.chameleon.layers.SoftButtonLayer.processCommand(), bci=74
at com.sun.midp.chameleon.layers.SoftButtonLayer.soft2(), bci=173
at com.sun.midp.chameleon.layers.SoftButtonLayer.keyInput(), bci=78
at com.sun.midp.chameleon.CWindow.keyInput(), bci=38
at javax.microedition.lcdui.Display$DisplayEventConsumerImpl.handleKeyEvent(), bci=17
at com.sun.midp.lcdui.DisplayEventListener.process(), bci=277
at com.sun.midp.events.EventQueue.run(), bci=179
at java.lang.Thread.run(Thread.java:722)

错误发生在byte[] image = videoControl.getSnapshot("encoding = jpeg");CameraMIDlet 和midlet.snap();CameraForm 中,在下面的代码中。

CameraForm 的代码在这里:

package Files;

import javax.microedition.media.*;

import javax.microedition.lcdui.*;

import javax.microedition.media.control.*;

import java.io.IOException;

class CameraForm extends Form implements CommandListener {

private final CameraMIDlet midlet;

private final Command exitCommand;

private Command captureCommand = null;

private Command showImageCommand = null;


private Player player = null;

private static VideoControl videoControl = null;

private boolean active = false;

private StringItem messageItem;

public CameraForm(CameraMIDlet midlet) {
    super("Camera");
    this.midlet = midlet;
    messageItem = new StringItem("Message", "start");
    append(messageItem);
    exitCommand = new Command("EXIT", Command.EXIT, 1);
    addCommand(exitCommand);
    setCommandListener(this);
    try {
        //creates a new player and set it to realize
        player = Manager.createPlayer("capture://video");
        player.realize();
        //Grap the Video control and set it to the current display
        videoControl = (VideoControl) (player.getControl("VideoControl"));
        if (videoControl != null) {
            append((Item) (videoControl.initDisplayMode(
                    VideoControl.USE_GUI_PRIMITIVE, null)));
            captureCommand = new Command("CAPTURE", Command.SCREEN, 1);
            addCommand(captureCommand);
            messageItem.setText("OK");
        } else {
            messageItem.setText("No video control");
        }
    } catch (IOException ioe) {
        messageItem.setText("IOException: " + ioe.getMessage());
    } catch (MediaException me) {
        messageItem.setText("Media Exception: " + me.getMessage());
    } catch (SecurityException se) {
        messageItem.setText("Security Exception: " + se.getMessage());
    }
}

 *  the video should be visualized on the sreen
 *  therefore you have to start the player and set the videoControl visible

synchronized void start() {
    if (!active) {
        try {
            if (player != null) {
                player.start();
            }
            if (videoControl != null) {
                videoControl.setVisible(true);
                                   //midlet.snap();
            }
        } catch (MediaException me) {
            messageItem.setText("Media Exception: " + me.getMessage());
        } catch (SecurityException se) {
            messageItem.setText("Security Exception: " + se.getMessage());
        }
        active = true;
    }
}

 *  to stop the player. First the videoControl has to be set invisible
 *  than the player can be stopped

synchronized void stop() {
    if (active) {
        try {
            if (videoControl != null) {
                videoControl.setVisible(false);
            }
            if (player != null) {
                player.stop();
            }
        } catch (MediaException me) {
            messageItem.setText("Media Exception: " + me.getMessage());
        }
        active = false;
    }
}

 *  on the captureCommand a picture is taken and transmited to the server

public void commandAction(Command c, Displayable d) {
    if (c == exitCommand) {
        midlet.cameraFormExit();
    } else {
        if (c == captureCommand) {

                      midlet.snap();

        }

    }
}


}

CameraMIDlet 的代码如下:

package Files; 

import java.io.*;

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import javax.microedition.io.*;

import javax.microedition.media.control.*;

import java.io.IOException;

import javax.microedition.media.MediaException;


public class CameraMIDlet extends MIDlet {


private CameraForm cameraSave = null;

private DisplayImage displayImage = null;

    CameraForm  captureThread;

    private static VideoControl videoControl;

    private StringItem messageItem;

public CameraMIDlet() {
}
/*
 * startApp()
 * starts the MIDlet and generates cameraSave, displayImage, database
 *
 **/

public void startApp() {
    Displayable current = Display.getDisplay(this).getCurrent();
    if (current == null) {
        //first call
        cameraSave = new CameraForm(this);
        displayImage = new DisplayImage(this);
        Display.getDisplay(this).setCurrent(cameraSave);
        cameraSave.start();

    } else {
        //returning from pauseApp
        if (current == cameraSave) {
            cameraSave.start();
        }
        Display.getDisplay(this).setCurrent(current);
    }
}
public void pauseApp() {
    if (Display.getDisplay(this).getCurrent() == cameraSave) {
        cameraSave.stop();
    }
}
public void destroyApp(boolean unconditional) {
    if (Display.getDisplay(this).getCurrent() == cameraSave) {
        cameraSave.stop();
    }
}
private void exitRequested() {
    destroyApp(false);
    notifyDestroyed();
}
void cameraFormExit() {
    exitRequested();
}
/**
 * restart the camera again
 *
 */
void displayCanvasBack() {
    Display.getDisplay(this).setCurrent(cameraSave);
    cameraSave.start();
}


/**
 *  the byte[] of the image should be transmitted to a server
 *
 **/
void buildHTTPConnection(byte[] byteImage) {
    displayImage.setImage(byteImage);
    Display.getDisplay(this).setCurrent(displayImage);
    HttpConnection hc = null;
    OutputStream out = null;
    try {
        //enode the image data by the Base64 algorithm
        String stringImage = Base64.encode(byteImage);
        // URL of the Sevlet
        String url = new String(
                "http://ip-adress:8080/C:/Users/HASENDE/Documents/NetBeansProjects/Mobile/pics");
        // Obtain an HTTPConnection
        hc = (HttpConnection) Connector.open(url);
        // Modifying the headers of the request
        hc.setRequestMethod(HttpConnection.POST);
        // Obtain the output stream for the HttpConnection
        out = hc.openOutputStream();

        out.write(stringImage.getBytes());          
    } catch (IOException ioe) {
        StringItem stringItem = new StringItem(null, ioe.toString());
    } finally {
        try {
            if (out != null)
                out.close();
            if (hc != null)
                hc.close();
        } catch (IOException ioe) {
        }
    }
    // ** end network
}
/**
 *  stop the camera, show the captured image and transmit the image to a server
 **/
void transmitImage(byte[] image) {
    cameraSave.stop();
    Display.getDisplay(this).setCurrent(displayImage);
    buildHTTPConnection(image);
}

     public void snap(){
               try {
         byte[] image = videoControl.getSnapshot("encoding = jpeg");
         transmitImage(image);  
         messageItem.setText("Ok");
    } catch (MediaException me) {
          messageItem.setText("Media Exception: " + me.getMessage());
      } 

        }
}
4

2 回答 2

2

通过识别引发 NPE 的语句,您可以 99% 接近找到错误:

    byte[] image = videoControl.getSnapshot("encoding = jpeg");

上述语句中的 NPE 表示videoControl为空。现在,如果您仔细观察,您可能会注意到在 CameraMIDlet 中,videoControl 被初始化为 null 并且永远不会更改为其他任何内容 - 这就是您获得 NPE 的原因。顺便说一句,从 CameraForm 代码看来,您打算使用那里定义的 videoControl 对象,不是吗。

边注。CameraForm 似乎被设计为在多个线程中使用(有synchronized修饰符) - 如果是这种情况,您最好确保 videoControl 也以同步方式从中获取。同样在这种情况下,在标志volatile的定义中添加修饰符:active

    private volatile boolean active = false; // in CameraForm
于 2012-04-07T06:21:46.307 回答
0

对于捕获照片使用画布而不是表单,请检查以下代码以获取照片捕获

public class ImageCaptureCanvas extends Canvas {

    UrMidlet midlet;
    VideoControl videoControl;
    Player player;
    SnapShotCanvas snap;
    private Display display;



    public ImageCaptureCanvas(UrMidlet midlet) throws MediaException {
        this.midlet = midlet;

        this.display = Display.getDisplay(midlet);
        this.setFullScreenMode(true);

        try {
            player = Manager.createPlayer("capture://image");
            player.realize();
            videoControl = (VideoControl) player.getControl("VideoControl");

        } catch (Exception e) {
            dm(e.getClass().getName());
        }

        videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
        try {
            videoControl.setDisplayLocation(0,0);
            videoControl.setDisplaySize(getWidth(), getHeight());

        } catch (MediaException me) {
            try {
                videoControl.setDisplayFullScreen(true);
            } catch (MediaException me2) {
            }
        }
        dm("icc10");
        videoControl.setVisible(true);
        dm("icc11");
        player.start();
        this.display.setCurrent(this);
    }

     public void dm(String message) {
        Form form = new Form("Error");
        form.append(message);
        display.setCurrent(form);
    }

    public void paint(Graphics g) {
    }

    protected void keyPressed(int keyCode) {
        boolean prv=false;
        int actn=getGameAction(keyCode);
        switch (keyCode) {
            case KEY_NUM5:
                prv=true;
                Thread t = new Thread() {

                    public void run() {
                        try {
                            byte[] raw = videoControl.getSnapshot(null);
                            Image image = Image.createImage(raw, 0, raw.length);

                            snap = new SnapShotCanvas(image);
                            display.setCurrent(snap);
                        } catch (Exception e) {
                            dm(e.getClass().getName() + " " + e.getMessage());
                        }
                    }
                };
                t.start();
                break;
        }
        if(!prv){
            switch (actn) {
            case Canvas.FIRE:
                Thread t1 = new Thread() {

                    public void run() {
                        try {
                            byte[] raw = videoControl.getSnapshot(null);
                            Image image = Image.createImage(raw, 0, raw.length);

                           snap = new SnapShotCanvas(image);
                           display.setCurrent(snap);

                        } catch (Exception e) {
                            dm(e.getClass().getName() + " " + e.getMessage());
                        }
                    }
                };
                t1.start();
                break;

        }
        }

    }
}

SnapShotCanvas 代码在这里

class SnapShotCanvas extends Canvas {

    private Image image;

    public SnapShotCanvas(Image image) {
        this.image = image;
        setFullScreenMode(true);
    }

    public void paint(Graphics g) {
        g.drawImage(image, getWidth() / 2, getHeight() / 2, Graphics.HCENTER | Graphics.VCENTER);
    }
}
于 2012-04-07T09:25:43.100 回答