Broke out classes, tried to add "open URL" support. Still some issues.
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Thu, 15 Nov 2007 21:46:36 +0000 (21:46 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Thu, 15 Nov 2007 21:46:36 +0000 (21:46 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@46 59b500cc-1b3d-0410-9834-0bbf25fbcc57

javame/src/com/google/zxing/client/j2me/SnapshotThread.java [new file with mode: 0644]
javame/src/com/google/zxing/client/j2me/VideoCanvas.java [new file with mode: 0644]
javame/src/com/google/zxing/client/j2me/ZXingMIDlet.java

diff --git a/javame/src/com/google/zxing/client/j2me/SnapshotThread.java b/javame/src/com/google/zxing/client/j2me/SnapshotThread.java
new file mode 100644 (file)
index 0000000..75c3be9
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.j2me;
+
+import com.google.zxing.MonochromeBitmapSource;
+import com.google.zxing.Reader;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.Result;
+import com.google.zxing.ReaderException;
+
+import javax.microedition.lcdui.Image;
+import javax.microedition.media.MediaException;
+
+/**
+ * @author Sean Owen (srowen@google.com)
+ */
+final class SnapshotThread extends Thread {
+
+  private static SnapshotThread currentThread;
+
+  private final ZXingMIDlet zXingMIDlet;
+
+  SnapshotThread(ZXingMIDlet zXingMIDlet) {
+    this.zXingMIDlet = zXingMIDlet;
+  }
+
+  static synchronized void startThread(ZXingMIDlet zXingMIDlet) {
+    if (currentThread == null) {
+      currentThread = new SnapshotThread(zXingMIDlet);
+      currentThread.start();
+    }
+  }
+
+  public void run() {
+    try {
+      zXingMIDlet.getPlayer().stop();
+      byte[] snapshot = zXingMIDlet.getVideoControl().getSnapshot(null);
+      Image capturedImage = Image.createImage(snapshot, 0, snapshot.length);
+      MonochromeBitmapSource source = new LCDUIImageMonochromeBitmapSource(capturedImage);
+      Reader reader = new MultiFormatReader();
+      Result result = reader.decode(source);
+      zXingMIDlet.handleDecodedText(result.getText());
+    } catch (ReaderException re) {
+      zXingMIDlet.showError(re);
+    } catch (MediaException me) {
+      zXingMIDlet.showError(me);
+    } catch (Throwable t) {
+      zXingMIDlet.showError(t);
+    } finally {
+      try {
+        zXingMIDlet.getPlayer().start();
+      } catch (MediaException me) {
+        // continue?
+        zXingMIDlet.showError(me);
+      }
+      currentThread = null;
+    }
+
+  }
+}
diff --git a/javame/src/com/google/zxing/client/j2me/VideoCanvas.java b/javame/src/com/google/zxing/client/j2me/VideoCanvas.java
new file mode 100644 (file)
index 0000000..2e361dd
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.j2me;
+
+import javax.microedition.lcdui.Canvas;
+import javax.microedition.lcdui.Command;
+import javax.microedition.lcdui.CommandListener;
+import javax.microedition.lcdui.Displayable;
+import javax.microedition.lcdui.Graphics;
+
+/**
+ * @author Sean Owen (srowen@google.com)
+ */
+final class VideoCanvas extends Canvas implements CommandListener {
+
+  private static final Command decode = new Command("Decode", Command.SCREEN, 1);
+  private static final Command exit = new Command("Exit", Command.EXIT, 1);
+
+  private final ZXingMIDlet zXingMIDlet;
+
+  VideoCanvas(ZXingMIDlet zXingMIDlet) {
+    this.zXingMIDlet = zXingMIDlet;
+    addCommand(decode);
+    addCommand(exit);
+    setCommandListener(this);
+  }
+
+  protected void paint(Graphics graphics) {
+    // do nothing
+  }
+
+  protected void keyPressed(int keyCode) {
+    // Use the "FIRE" key as a "take snapshot" key
+    if (FIRE == getGameAction(keyCode)) {
+      SnapshotThread.startThread(zXingMIDlet);
+    }
+  }
+
+  public void commandAction(Command command, Displayable displayable) {
+    if (command.equals(decode)) {
+      SnapshotThread.startThread(zXingMIDlet);
+    } else if (command.equals(exit)) {
+      zXingMIDlet.stop();
+    }
+  }
+}
index feb3dd7..4428c02 100644 (file)
 
 package com.google.zxing.client.j2me;
 
-import com.google.zxing.MonochromeBitmapSource;
-import com.google.zxing.MultiFormatReader;
-import com.google.zxing.Reader;
-import com.google.zxing.ReaderException;
-import com.google.zxing.Result;
-
+import javax.microedition.io.ConnectionNotFoundException;
 import javax.microedition.lcdui.Alert;
 import javax.microedition.lcdui.AlertType;
 import javax.microedition.lcdui.Canvas;
@@ -29,8 +24,6 @@ import javax.microedition.lcdui.Command;
 import javax.microedition.lcdui.CommandListener;
 import javax.microedition.lcdui.Display;
 import javax.microedition.lcdui.Displayable;
-import javax.microedition.lcdui.Graphics;
-import javax.microedition.lcdui.Image;
 import javax.microedition.media.Manager;
 import javax.microedition.media.MediaException;
 import javax.microedition.media.Player;
@@ -49,12 +42,21 @@ public final class ZXingMIDlet extends MIDlet {
   private Player player;
   private VideoControl videoControl;
 
+  Player getPlayer() {
+    return player;
+  }
+
+  VideoControl getVideoControl() {
+    return videoControl;
+  }
+
   protected void startApp() throws MIDletStateChangeException {
     try {
       player = Manager.createPlayer("capture://video");
       player.realize();
       videoControl = (VideoControl) player.getControl("VideoControl");
-      Displayable canvas = new VideoCanvas();
+      Canvas canvas = new VideoCanvas(this);
+      canvas.setFullScreenMode(true);
       videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, canvas);
       videoControl.setDisplayLocation(0, 0);
       videoControl.setDisplaySize(canvas.getWidth(), canvas.getHeight());
@@ -95,21 +97,57 @@ public final class ZXingMIDlet extends MIDlet {
 
   protected void destroyApp(boolean unconditional) {
     if (player != null) {
+      videoControl = null;      
+      try {
+        player.stop();
+      } catch (MediaException me) {
+        // continue
+      }
+      player.deallocate();
       player.close();
       player = null;
-      videoControl = null;
     }
   }
 
+  void stop() {
+    destroyApp(false);
+    notifyDestroyed();
+  }
+
   // Convenience methods to show dialogs
 
-  private void showAlert(String title, String text) {
+  void showYesNo(String title, final String text) {
+    Alert alert = new Alert(title, text, null, AlertType.INFO);
+    alert.setTimeout(Alert.FOREVER);
+    final Command yes = new Command("Yes", Command.OK, 0);
+    final Command no = new Command("No", Command.CANCEL, 0);
+    alert.addCommand(yes);
+    alert.addCommand(no);
+    CommandListener listener = new CommandListener() {
+      public void commandAction(Command command, Displayable displayable) {
+        if (command.equals(yes)) {
+          try {
+            if (platformRequest(text)) {
+              // Successfully opened URL; exit
+              stop();
+            }
+          } catch (ConnectionNotFoundException cnfe) {
+            showError(cnfe);
+          }
+        }
+      }
+    };
+    alert.setCommandListener(listener);
+    showAlert(alert);
+  }
+
+  void showAlert(String title, String text) {
     Alert alert = new Alert(title, text, null, AlertType.INFO);
     alert.setTimeout(Alert.FOREVER);
     showAlert(alert);
   }
 
-  private void showError(Throwable t) {
+  void showError(Throwable t) {
     showAlert(new Alert("Error", t.getMessage(), null, AlertType.ERROR));
   }
 
@@ -118,59 +156,20 @@ public final class ZXingMIDlet extends MIDlet {
     display.setCurrent(alert, display.getCurrent());
   }
 
-  private class VideoCanvas extends Canvas implements CommandListener {
-    private final Command decode = new Command("Decode", Command.SCREEN, 1);
-    private final Command exit = new Command("Exit", Command.EXIT, 1);
-    private VideoCanvas() {
-      addCommand(decode);
-      addCommand(exit);
-      setCommandListener(this);
-    }
-    protected void paint(Graphics graphics) {
-      // do nothing
-    }
-    protected void keyPressed(int keyCode) {
-      if (FIRE == getGameAction(keyCode)) {
-        new SnapshotThread().start();
-      }
-    }
-    public void commandAction(Command command, Displayable displayable) {
-      if (command.equals(decode)) {
-        new SnapshotThread().start();
-      } else if (command.equals(exit)) {
-        destroyApp(false);
-        notifyDestroyed();
-      }
+  void handleDecodedText(String text) {
+    // This is a crude imitation of the code found in module core-ext, which handles the contents
+    // in a more sophisticated way. It can't be accessed from JavaME just yet because it relies
+    // on URL parsing routines in java.net. This should be somehow worked around: TODO
+    // For now, detect URLs in a simple way, and treat everything else as text
+    if (text.startsWith("http://") || text.startsWith("https://") || maybeURLWithoutScheme(text)) {
+      showYesNo("Open URL?", text);
+    } else {
+      showAlert("Barcode detected", text);
     }
   }
 
-  // TODO make sure we do not start two threads at once
-  private class SnapshotThread extends Thread {
-    public void run() {
-      try {
-        player.stop();
-        byte[] snapshot = videoControl.getSnapshot(null);
-        Image capturedImage = Image.createImage(snapshot, 0, snapshot.length);
-        MonochromeBitmapSource source = new LCDUIImageMonochromeBitmapSource(capturedImage);
-        Reader reader = new MultiFormatReader();
-        Result result = reader.decode(source);
-        showAlert("Barcode detected", result.getText());
-      } catch (ReaderException re) {
-        showError(re);
-      } catch (MediaException me) {
-        showError(me);
-      } catch (Throwable t) {
-        showError(t);
-      } finally {
-        try {
-          player.start();
-        } catch (MediaException me) {
-          // continue?
-          showError(me);
-        }
-      }
-
-    }
+  private static boolean maybeURLWithoutScheme(String text) {
+    return text.indexOf((int) '.') >= 0 && text.indexOf((int) ' ') < 0;
   }
 
 }