From a328d64900cdbba36cb022c5af2a7424ea392438 Mon Sep 17 00:00:00 2001 From: srowen Date: Thu, 15 Nov 2007 21:46:36 +0000 Subject: [PATCH] Broke out classes, tried to add "open URL" support. Still some issues. git-svn-id: http://zxing.googlecode.com/svn/trunk@46 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../zxing/client/j2me/SnapshotThread.java | 74 +++++++++++ .../google/zxing/client/j2me/VideoCanvas.java | 60 +++++++++ .../google/zxing/client/j2me/ZXingMIDlet.java | 123 +++++++++--------- 3 files changed, 195 insertions(+), 62 deletions(-) create mode 100644 javame/src/com/google/zxing/client/j2me/SnapshotThread.java create mode 100644 javame/src/com/google/zxing/client/j2me/VideoCanvas.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 index 00000000..75c3be9a --- /dev/null +++ b/javame/src/com/google/zxing/client/j2me/SnapshotThread.java @@ -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 index 00000000..2e361dd6 --- /dev/null +++ b/javame/src/com/google/zxing/client/j2me/VideoCanvas.java @@ -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(); + } + } +} diff --git a/javame/src/com/google/zxing/client/j2me/ZXingMIDlet.java b/javame/src/com/google/zxing/client/j2me/ZXingMIDlet.java index feb3dd7b..4428c02e 100644 --- a/javame/src/com/google/zxing/client/j2me/ZXingMIDlet.java +++ b/javame/src/com/google/zxing/client/j2me/ZXingMIDlet.java @@ -16,12 +16,7 @@ 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; } } -- 2.20.1