2012-04-06 12 views
2

私はこれに長い時間を費やしましたが、まだ成功していません。イメージをキャプチャしてサーバーに送信するアプリケーションでは、以下のようなNullPointerExceptionが発生します。J2MEでのカメラスナップショットヌルポインタの例外

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) 

誤差は以下のコードで、CameraFormにmidlet.snap();でもCameraMIDletにbyte[] image = videoControl.getSnapshot("encoding = jpeg");で起こると。

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()); 
     } 

     } 
} 

答えて

2

バグを見つけるに近い99%を取得NPEをスローするステートメントを識別することによって:

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

上記のNPEは、videoControlがnullであることを意味します。ここでCameraMIDletを見ると、videoControlはnullで初期化され、他のものに変更されることはありません。そのため、NPEを取得しています。ちなみに、CameraFormコードからは、そこに定義されているvideoControlオブジェクトを使用するように見えますが、あなたはそうしませんでした。

サイドノート。 CameraFormは複数のスレッドで使用されるように設計されているようです(​​修飾子があります)。この場合、videoControlも同期された方法で取得することをお勧めします。また、その場合には、activeフラグの定義におけるvolatile修飾子を追加します。代わりに、フォームの写真を使用キャンバスを取得するための

private volatile boolean active = false; // in CameraForm 
+0

J2MEの新機能ですが、videoControlが同期された方法で取得されていることを確認する方法については、私に詳しく教えてください。 – Kirungi

+0

@キルンギは、[別の質問](http://meta.stackexchange.com/questions/43478/exit-strategies-for-chameleon-questions "カメレオンの質問"についての説明)です。興味があれば別に投稿してください – gnat

0

を、写真 チェックfollwingコードはここに

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); 
    } 
} 
+0

Thanxたくさんありますがpl'se私はあなたにMFarmersMidletの部分を含むソースコード全体を送ってください。 – Kirungi

+0

あなたのミッドレットに次のコードを書く=== public void startApp() {ImageCaptureCanvas camra =新しいImageCaptureCanvas(this ); } –

関連する問題