Commit Simon's changes for Issue 134
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Sun, 1 Feb 2009 11:44:56 +0000 (11:44 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Sun, 1 Feb 2009 11:44:56 +0000 (11:44 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@838 59b500cc-1b3d-0410-9834-0bbf25fbcc57

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

diff --git a/javame/src/com/google/zxing/client/j2me/Menu.java b/javame/src/com/google/zxing/client/j2me/Menu.java
new file mode 100644 (file)
index 0000000..544ee2f
--- /dev/null
@@ -0,0 +1,96 @@
+/*\r
+ * Copyright 2009 ZXing authors\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package com.google.zxing.client.j2me;\r
+\r
+import javax.microedition.lcdui.Command;\r
+import javax.microedition.lcdui.CommandListener;\r
+import javax.microedition.lcdui.Display;\r
+import javax.microedition.lcdui.Displayable;\r
+import javax.microedition.lcdui.List;\r
+\r
+/**\r
+ * The Menu form simply adds Command Listener functionality\r
+ * to the standard List User Interface component.\r
+ *\r
+ * @author Simon Flannery (simon.flannery@gmail.com)\r
+ */\r
+final class Menu extends List implements CommandListener {\r
+\r
+  private final ZXingMIDlet zXingMIDlet;\r
+  private Command cancelCommand;\r
+  private Command barcodeCommand;\r
+\r
+  /**\r
+   * Creates a new Search List and initialises all components.\r
+   *\r
+   * @param parent The Parent ZXing MIDlet.\r
+   * @param title The title of the List.\r
+   * @param item The caption of the item action Command.\r
+   */\r
+  Menu(ZXingMIDlet parent, String title, String item) {\r
+    super(title, IMPLICIT); // Set the title of the form\r
+    zXingMIDlet = parent;\r
+    // Build the UI components\r
+    cancelCommand  = new Command("Cancel", Command.CANCEL, 0);\r
+    barcodeCommand = new Command(item, Command.ITEM, 0);\r
+    addCommand(cancelCommand);\r
+    addCommand(barcodeCommand);\r
+    setCommandListener(this);\r
+  }\r
+\r
+  /**\r
+   * A convenience method for getting the selected option item.\r
+   *\r
+   * @return The selected option represented as a String. If no option is\r
+   *         selected, then the empty string is returned.\r
+   */\r
+  public String getSelectedString() {\r
+    String result = "";\r
+    if (getSelectedIndex() != -1) {\r
+      result = getString(getSelectedIndex());\r
+    }\r
+    return result;\r
+  }\r
+\r
+  /**\r
+   * A convenience method for removing all items from the list.\r
+   * While the size of the list does not equal zero, the first item of the list is deleted.\r
+   */\r
+  public void clear() {\r
+    while (size() != 0) { // Delete the first-most element until there is no first-most element\r
+      delete(0);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * CommandListener Required Implementation for capturing soft key presses.\r
+   * This is where all call back methods (of the MIDlet) are serviced.\r
+   *\r
+   * @param command The command requiring attention.\r
+   * @param displayable The Display.\r
+   */\r
+  public void commandAction(Command command, Displayable displayable) {\r
+    if (command == cancelCommand) { /* Detecting the soft key press. */\r
+      Display.getDisplay(zXingMIDlet).setCurrent(zXingMIDlet.getCanvas());\r
+    } else if (command == barcodeCommand || command == SELECT_COMMAND) {\r
+      if (getSelectedIndex() != -1) {\r
+        zXingMIDlet.itemRequest();\r
+      }\r
+    }\r
+  }\r
+\r
+}\r
index d156b20..a24d802 100644 (file)
@@ -1,66 +1,71 @@
-/*
- * Copyright 2007 ZXing authors
- *
- * 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;
-
-/**
- * The main {@link Canvas} onto which the camera's field of view is painted.
- * This class manages decoding via {@link SnapshotThread}.
- *
- * @author Sean Owen
- */
-final class VideoCanvas extends Canvas implements CommandListener {
-
-  private static final Command exit = new Command("Exit", Command.EXIT, 1);
-
-  private final ZXingMIDlet zXingMIDlet;
-  private final SnapshotThread snapshotThread;
-
-  VideoCanvas(ZXingMIDlet zXingMIDlet) {
-    this.zXingMIDlet = zXingMIDlet;
-    addCommand(exit);
-    setCommandListener(this);
-    snapshotThread = new SnapshotThread(zXingMIDlet);
-    new Thread(snapshotThread).start();
-  }
-
-  protected void paint(Graphics graphics) {
-    // do nothing
-  }
-
-  protected void keyPressed(int keyCode) {
-    // Any valid game key will trigger a capture
-    if (getGameAction(keyCode) != 0) {
-      snapshotThread.continueRun();
-    } else {
-      super.keyPressed(keyCode);
-    }
-  }
-
-  public void commandAction(Command command, Displayable displayable) {
-    int type = command.getCommandType();
-    if (type == Command.EXIT || type == Command.STOP || type == Command.BACK || type == Command.CANCEL) {
-      snapshotThread.stop();
-      zXingMIDlet.stop();
-    }
-  }
-}
+/*\r
+ * Copyright 2007 ZXing authors\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package com.google.zxing.client.j2me;\r
+\r
+import javax.microedition.lcdui.Canvas;\r
+import javax.microedition.lcdui.Command;\r
+import javax.microedition.lcdui.CommandListener;\r
+import javax.microedition.lcdui.Displayable;\r
+import javax.microedition.lcdui.Graphics;\r
+\r
+/**\r
+ * The main {@link Canvas} onto which the camera's field of view is painted.\r
+ * This class manages decoding via {@link SnapshotThread}.\r
+ *\r
+ * @author Sean Owen\r
+ * @author Simon Flannery\r
+ */\r
+final class VideoCanvas extends Canvas implements CommandListener {\r
+\r
+  private static final Command exit = new Command("Exit", Command.EXIT, 1);\r
+  private static final Command history = new Command("History", Command.ITEM, 0);\r
+\r
+  private final ZXingMIDlet zXingMIDlet;\r
+  private final SnapshotThread snapshotThread;\r
+\r
+  VideoCanvas(ZXingMIDlet zXingMIDlet) {\r
+    this.zXingMIDlet = zXingMIDlet;\r
+    addCommand(exit);\r
+    addCommand(history);\r
+    setCommandListener(this);\r
+    snapshotThread = new SnapshotThread(zXingMIDlet);\r
+    new Thread(snapshotThread).start();\r
+  }\r
+\r
+  protected void paint(Graphics graphics) {\r
+    // do nothing\r
+  }\r
+\r
+  protected void keyPressed(int keyCode) {\r
+    // Any valid game key will trigger a capture\r
+    if (getGameAction(keyCode) != 0) {\r
+      snapshotThread.continueRun();\r
+    } else {\r
+      super.keyPressed(keyCode);\r
+    }\r
+  }\r
+\r
+  public void commandAction(Command command, Displayable displayable) {\r
+    int type = command.getCommandType();\r
+    if (command == history) {\r
+      zXingMIDlet.historyRequest();\r
+    } else if (type == Command.EXIT || type == Command.STOP || type == Command.BACK || type == Command.CANCEL) {\r
+      snapshotThread.stop();\r
+      zXingMIDlet.stop();\r
+    }\r
+  }\r
+}\r
index 8440037..9fc09a9 100644 (file)
-/*
- * Copyright 2007 ZXing authors
- *
- * 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.Result;
-import com.google.zxing.client.result.EmailAddressParsedResult;
-import com.google.zxing.client.result.ParsedResult;
-import com.google.zxing.client.result.ParsedResultType;
-import com.google.zxing.client.result.ResultParser;
-import com.google.zxing.client.result.SMSParsedResult;
-import com.google.zxing.client.result.TelParsedResult;
-import com.google.zxing.client.result.ProductParsedResult;
-import com.google.zxing.client.result.URIParsedResult;
-
-import javax.microedition.lcdui.Image;
-import javax.microedition.io.ConnectionNotFoundException;
-import javax.microedition.lcdui.Alert;
-import javax.microedition.lcdui.AlertType;
-import javax.microedition.lcdui.Canvas;
-import javax.microedition.lcdui.Command;
-import javax.microedition.lcdui.CommandListener;
-import javax.microedition.lcdui.Display;
-import javax.microedition.lcdui.Displayable;
-import javax.microedition.media.Manager;
-import javax.microedition.media.MediaException;
-import javax.microedition.media.Player;
-import javax.microedition.media.control.VideoControl;
-import javax.microedition.midlet.MIDlet;
-import javax.microedition.midlet.MIDletStateChangeException;
-import java.io.IOException;
-
-/**
- * <p>The actual reader application {@link MIDlet}.</p>
- *
- * @author Sean Owen
- */
-public final class ZXingMIDlet extends MIDlet {
-
-  private static final int ALERT_TIMEOUT_MS = 5 * 1000;
-
-  private Canvas canvas;
-  private Player player;
-  private VideoControl videoControl;
-  private Alert confirmation;
-  private Alert alert;
-
-  Displayable getCanvas() {
-    return canvas;
-  }
-
-  Player getPlayer() {
-    return player;
-  }
-
-  VideoControl getVideoControl() {
-    return videoControl;
-  }
-
-  static MultimediaManager buildMultimediaManager() {
-    return new AdvancedMultimediaManager();
-    // Comment line above / uncomment below to make the basic version
-    // return new DefaultMultimediaManager();
-  }
-
-  protected void startApp() throws MIDletStateChangeException {
-    try {
-      Image image = Image.createImage("/res/zxing-icon.png");
-      SplashThread splash = new SplashThread(this, 2000, image);
-      Display.getDisplay(this).setCurrent(splash);
-      player = createPlayer();
-      player.realize();
-      MultimediaManager multimediaManager = buildMultimediaManager();
-      multimediaManager.setZoom(player);
-      multimediaManager.setExposure(player);
-      videoControl = (VideoControl) player.getControl("VideoControl");
-      canvas = new VideoCanvas(this);
-      canvas.setFullScreenMode(true);
-      videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, canvas);
-      videoControl.setDisplayLocation(0, 0);
-      videoControl.setDisplaySize(canvas.getWidth(), canvas.getHeight());
-    } catch (IOException ioe) {
-      throw new MIDletStateChangeException(ioe.toString());
-    } catch (MediaException me) {
-      throw new MIDletStateChangeException(me.toString());
-    }
-
-    // Set up one confirmation and alert object to re-use
-    confirmation = new Alert(null);
-    confirmation.setType(AlertType.CONFIRMATION);
-    confirmation.setTimeout(ALERT_TIMEOUT_MS);
-    Command yes = new Command("Yes", Command.OK, 1);
-    confirmation.addCommand(yes);
-    Command no = new Command("No", Command.CANCEL, 1);
-    confirmation.addCommand(no);
-    alert = new Alert(null);
-    alert.setTimeout(ALERT_TIMEOUT_MS);
-  }
-
-  void splashDone() {
-    try {
-      videoControl.setVisible(true);
-      player.start();
-    } catch (MediaException me) {
-      // continue
-    }
-    Display.getDisplay(this).setCurrent(canvas);
-  }
-
-  private static Player createPlayer() throws IOException, MediaException {
-    // Try a workaround for Nokias, which want to use capture://image in some cases
-    Player player = null;
-    String platform = System.getProperty("microedition.platform");
-    if (platform != null && platform.indexOf("Nokia") >= 0) {
-      try {
-        player = Manager.createPlayer("capture://image");
-      } catch (MediaException me) {
-        // if this fails, just continue with capture://video
-      } catch (Error e) {
-        // Ugly, but, it seems the Nokia N70 throws "java.lang.Error: 136" here
-        // We should still try to continue
-      }
-    }
-    if (player == null) {
-      player = Manager.createPlayer("capture://video");
-    }
-    return player;
-  }
-
-  protected void pauseApp() {
-    if (player != null) {
-      try {
-        player.stop();
-      } catch (MediaException me) {
-        // continue?
-        showError(me);
-      }
-    }
-  }
-
-  protected void destroyApp(boolean unconditional) {
-    if (player != null) {
-      videoControl = null;
-      try {
-        player.stop();
-      } catch (MediaException me) {
-        // continue
-      }
-      player.deallocate();
-      player.close();
-      player = null;
-    }
-  }
-
-  void stop() {
-    destroyApp(false);
-    notifyDestroyed();
-  }
-
-  // Convenience methods to show dialogs
-
-  private void showOpenURL(String title, String display, final String uri) {
-    confirmation.setTitle(title);
-    confirmation.setString(display);
-    CommandListener listener = new CommandListener() {
-      public void commandAction(Command command, Displayable displayable) {
-        if (command.getCommandType() == Command.OK) {
-          try {
-            platformRequest(uri);
-          } catch (ConnectionNotFoundException cnfe) {
-            showError(cnfe);
-          } finally {
-            stop();
-          }
-        } else {
-          // cancel
-          Display.getDisplay(ZXingMIDlet.this).setCurrent(getCanvas());
-        }
-      }
-    };
-    confirmation.setCommandListener(listener);
-    showAlert(confirmation);
-  }
-
-  private void showAlert(String title, String text) {
-    alert.setTitle(title);
-    alert.setString(text);
-    alert.setType(AlertType.INFO);
-    showAlert(alert);
-  }
-
-  void showError(Throwable t) {
-    String message = t.getMessage();
-    if (message != null && message.length() > 0) {
-      showError(message);
-    } else {
-      showError(t.toString());
-    }
-  }
-
-  void showError(String message) {
-    alert.setTitle("Error");
-    alert.setString(message);
-    alert.setType(AlertType.ERROR);
-    showAlert(alert);
-  }
-
-  private void showAlert(Alert alert) {
-    Display display = Display.getDisplay(this);
-    display.setCurrent(alert, canvas);
-  }
-
-  void handleDecodedText(Result theResult) {
-    ParsedResult result = ResultParser.parseResult(theResult);
-    ParsedResultType type = result.getType();
-    if (type.equals(ParsedResultType.URI)) {
-      String uri = ((URIParsedResult) result).getURI();
-      showOpenURL("Open Web Page?", uri, uri);
-    } else if (type.equals(ParsedResultType.EMAIL_ADDRESS)) {
-      EmailAddressParsedResult emailResult = (EmailAddressParsedResult) result;
-      showOpenURL("Compose E-mail?", emailResult.getEmailAddress(), emailResult.getMailtoURI());
-    } else if (type.equals(ParsedResultType.SMS)) {
-      SMSParsedResult smsResult = (SMSParsedResult) result;
-      showOpenURL("Compose SMS?", smsResult.getNumber(), smsResult.getSMSURI());
-    } else if (type.equals(ParsedResultType.PRODUCT)) {
-      ProductParsedResult productResult = (ProductParsedResult) result;
-      String uri = "http://www.upcdatabase.com/item.asp?upc=" + productResult.getNormalizedProductID();
-      showOpenURL("Look Up Barcode Online?", productResult.getProductID(), uri);
-    } else if (type.equals(ParsedResultType.TEL)) {
-      TelParsedResult telResult = (TelParsedResult) result;
-      showOpenURL("Dial Number?", telResult.getNumber(), telResult.getTelURI());
-    } else {
-      showAlert("Barcode Detected", result.getDisplayResult());
-    }
-  }
-
-}
+/*\r
+ * Copyright 2007 ZXing authors\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package com.google.zxing.client.j2me;\r
+\r
+import com.google.zxing.Result;\r
+import com.google.zxing.client.result.EmailAddressParsedResult;\r
+import com.google.zxing.client.result.ParsedResult;\r
+import com.google.zxing.client.result.ParsedResultType;\r
+import com.google.zxing.client.result.ResultParser;\r
+import com.google.zxing.client.result.SMSParsedResult;\r
+import com.google.zxing.client.result.TelParsedResult;\r
+import com.google.zxing.client.result.ProductParsedResult;\r
+import com.google.zxing.client.result.URIParsedResult;\r
+\r
+import javax.microedition.lcdui.Image;\r
+import javax.microedition.io.ConnectionNotFoundException;\r
+import javax.microedition.lcdui.Alert;\r
+import javax.microedition.lcdui.AlertType;\r
+import javax.microedition.lcdui.Canvas;\r
+import javax.microedition.lcdui.Command;\r
+import javax.microedition.lcdui.CommandListener;\r
+import javax.microedition.lcdui.Display;\r
+import javax.microedition.lcdui.Displayable;\r
+import javax.microedition.media.Manager;\r
+import javax.microedition.media.MediaException;\r
+import javax.microedition.media.Player;\r
+import javax.microedition.media.control.VideoControl;\r
+import javax.microedition.midlet.MIDlet;\r
+import javax.microedition.midlet.MIDletStateChangeException;\r
+import java.io.IOException;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * <p>The actual reader application {@link MIDlet}.</p>\r
+ *\r
+ * @author Sean Owen\r
+ * @author Simon Flannery\r
+ */\r
+public final class ZXingMIDlet extends MIDlet {\r
+\r
+  private static final int ALERT_TIMEOUT_MS = 5 * 1000;\r
+\r
+  private Canvas canvas;\r
+  private Player player;\r
+  private VideoControl videoControl;\r
+  private Alert confirmation;\r
+  private Alert alert;\r
+  private Menu history;\r
+  private Vector resultHistory;\r
+\r
+  Displayable getCanvas() {\r
+    return canvas;\r
+  }\r
+\r
+  Player getPlayer() {\r
+    return player;\r
+  }\r
+\r
+  VideoControl getVideoControl() {\r
+    return videoControl;\r
+  }\r
+\r
+  static MultimediaManager buildMultimediaManager() {\r
+    return new AdvancedMultimediaManager();\r
+    // Comment line above / uncomment below to make the basic version\r
+    // return new DefaultMultimediaManager();\r
+  }\r
+\r
+  protected void startApp() throws MIDletStateChangeException {\r
+    try {\r
+      Image image = Image.createImage("/res/zxing-icon.png");\r
+      Displayable splash = new SplashThread(this, 2000, image);\r
+      Display.getDisplay(this).setCurrent(splash);\r
+\r
+      resultHistory = new Vector(5);\r
+      history = new Menu(this, "Scan History", "Use");\r
+\r
+      player = createPlayer();\r
+      player.realize();\r
+      MultimediaManager multimediaManager = buildMultimediaManager();\r
+      multimediaManager.setZoom(player);\r
+      multimediaManager.setExposure(player);\r
+      videoControl = (VideoControl) player.getControl("VideoControl");\r
+      canvas = new VideoCanvas(this);\r
+      canvas.setFullScreenMode(true);\r
+      videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, canvas);\r
+      videoControl.setDisplayLocation(0, 0);\r
+      videoControl.setDisplaySize(canvas.getWidth(), canvas.getHeight());\r
+    } catch (IOException ioe) {\r
+      throw new MIDletStateChangeException(ioe.toString());\r
+    } catch (MediaException me) {\r
+      throw new MIDletStateChangeException(me.toString());\r
+    }\r
+\r
+    // Set up one confirmation and alert object to re-use\r
+    confirmation = new Alert(null);\r
+    confirmation.setType(AlertType.CONFIRMATION);\r
+    confirmation.setTimeout(ALERT_TIMEOUT_MS);\r
+    Command yes = new Command("Yes", Command.OK, 1);\r
+    confirmation.addCommand(yes);\r
+    Command no = new Command("No", Command.CANCEL, 1);\r
+    confirmation.addCommand(no);\r
+    alert = new Alert(null);\r
+    alert.setTimeout(ALERT_TIMEOUT_MS);\r
+  }\r
+\r
+  void splashDone() {\r
+    try {\r
+      videoControl.setVisible(true);\r
+      player.start();\r
+    } catch (MediaException me) {\r
+      showError(me);\r
+    }\r
+    Display.getDisplay(this).setCurrent(canvas);\r
+  }\r
+\r
+  private static Player createPlayer() throws IOException, MediaException {\r
+    // Try a workaround for Nokias, which want to use capture://image in some cases\r
+    Player player = null;\r
+    String platform = System.getProperty("microedition.platform");\r
+    if (platform != null && platform.indexOf("Nokia") >= 0) {\r
+      try {\r
+        player = Manager.createPlayer("capture://image");\r
+      } catch (MediaException me) {\r
+        // if this fails, just continue with capture://video\r
+      } catch (Error e) {\r
+        // Ugly, but, it seems the Nokia N70 throws "java.lang.Error: 136" here\r
+        // We should still try to continue\r
+      }\r
+    }\r
+    if (player == null) {\r
+      player = Manager.createPlayer("capture://video");\r
+    }\r
+    return player;\r
+  }\r
+\r
+  protected void pauseApp() {\r
+    if (player != null) {\r
+      try {\r
+        player.stop();\r
+      } catch (MediaException me) {\r
+        // continue?\r
+        showError(me);\r
+      }\r
+    }\r
+  }\r
+\r
+  protected void destroyApp(boolean unconditional) {\r
+    if (player != null) {\r
+      videoControl = null;\r
+      try {\r
+        player.stop();\r
+      } catch (MediaException me) {\r
+        // continue\r
+      }\r
+      player.deallocate();\r
+      player.close();\r
+      player = null;\r
+    }\r
+  }\r
+\r
+  void stop() {\r
+    destroyApp(false);\r
+    notifyDestroyed();\r
+  }\r
+\r
+  void historyRequest() {\r
+    Display.getDisplay(this).setCurrent(history);\r
+  }\r
+\r
+  // Convenience methods to show dialogs\r
+\r
+  private void showOpenURL(String title, String display, final String uri) {\r
+    confirmation.setTitle(title);\r
+    confirmation.setString(display);\r
+    CommandListener listener = new CommandListener() {\r
+      public void commandAction(Command command, Displayable displayable) {\r
+        if (command.getCommandType() == Command.OK) {\r
+          try {\r
+            platformRequest(uri);\r
+          } catch (ConnectionNotFoundException cnfe) {\r
+            showError(cnfe);\r
+          } finally {\r
+            stop();\r
+          }\r
+        } else {\r
+          // cancel\r
+          Display.getDisplay(ZXingMIDlet.this).setCurrent(getCanvas());\r
+        }\r
+      }\r
+    };\r
+    confirmation.setCommandListener(listener);\r
+    showAlert(confirmation);\r
+  }\r
+\r
+  private void showAlert(String title, String text) {\r
+    alert.setTitle(title);\r
+    alert.setString(text);\r
+    alert.setType(AlertType.INFO);\r
+    showAlert(alert);\r
+  }\r
+\r
+  void showError(Throwable t) {\r
+    String message = t.getMessage();\r
+    if (message != null && message.length() > 0) {\r
+      showError(message);\r
+    } else {\r
+      showError(t.toString());\r
+    }\r
+  }\r
+\r
+  void showError(String message) {\r
+    alert.setTitle("Error");\r
+    alert.setString(message);\r
+    alert.setType(AlertType.ERROR);\r
+    showAlert(alert);\r
+  }\r
+\r
+  private void showAlert(Alert alert) {\r
+    Display display = Display.getDisplay(this);\r
+    display.setCurrent(alert, canvas);\r
+  }\r
+\r
+  void barcodeAction(ParsedResult result) {\r
+    ParsedResultType type = result.getType();\r
+    if (type.equals(ParsedResultType.URI)) {\r
+      String uri = ((URIParsedResult) result).getURI();\r
+      showOpenURL("Open Web Page?", uri, uri);\r
+    } else if (type.equals(ParsedResultType.EMAIL_ADDRESS)) {\r
+      EmailAddressParsedResult emailResult = (EmailAddressParsedResult) result;\r
+      showOpenURL("Compose E-mail?", emailResult.getEmailAddress(), emailResult.getMailtoURI());\r
+    } else if (type.equals(ParsedResultType.SMS)) {\r
+      SMSParsedResult smsResult = (SMSParsedResult) result;\r
+      showOpenURL("Compose SMS?", smsResult.getNumber(), smsResult.getSMSURI());\r
+    } else if (type.equals(ParsedResultType.PRODUCT)) {\r
+      ProductParsedResult productResult = (ProductParsedResult) result;\r
+      String uri = "http://www.upcdatabase.com/item.asp?upc=" + productResult.getNormalizedProductID();\r
+      showOpenURL("Look Up Barcode Online?", productResult.getProductID(), uri);\r
+    } else if (type.equals(ParsedResultType.TEL)) {\r
+      TelParsedResult telResult = (TelParsedResult) result;\r
+      showOpenURL("Dial Number?", telResult.getNumber(), telResult.getTelURI());\r
+    } else {\r
+      showAlert("Barcode Detected", result.getDisplayResult());\r
+    }\r
+  }\r
+\r
+  void itemRequest() {\r
+    ParsedResult result = (ParsedResult) resultHistory.elementAt(history.getSelectedIndex());\r
+    barcodeAction(result);\r
+  }\r
+\r
+  void handleDecodedText(Result theResult) {\r
+    ParsedResult result = ResultParser.parseResult(theResult);\r
+    String resultString = result.toString();\r
+    int i = 0;\r
+    while (i < resultHistory.size()) {\r
+      if (resultString.equals(resultHistory.elementAt(i).toString())) {\r
+        break;\r
+      }\r
+      i++;\r
+    }\r
+    if (i == resultHistory.size()) {\r
+      resultHistory.addElement(result);\r
+      history.append(result.getDisplayResult(), null);\r
+    }\r
+    barcodeAction(result);\r
+  }\r
+\r
+}\r