2 * Copyright 2007 ZXing authors
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 package com.google.zxing.client.j2me;
\r
19 import com.google.zxing.Result;
\r
20 import com.google.zxing.client.result.EmailAddressParsedResult;
\r
21 import com.google.zxing.client.result.ParsedResult;
\r
22 import com.google.zxing.client.result.ParsedResultType;
\r
23 import com.google.zxing.client.result.ResultParser;
\r
24 import com.google.zxing.client.result.SMSParsedResult;
\r
25 import com.google.zxing.client.result.TelParsedResult;
\r
26 import com.google.zxing.client.result.ProductParsedResult;
\r
27 import com.google.zxing.client.result.URIParsedResult;
\r
29 import javax.microedition.lcdui.Image;
\r
30 import javax.microedition.io.ConnectionNotFoundException;
\r
31 import javax.microedition.lcdui.Alert;
\r
32 import javax.microedition.lcdui.AlertType;
\r
33 import javax.microedition.lcdui.Canvas;
\r
34 import javax.microedition.lcdui.Command;
\r
35 import javax.microedition.lcdui.CommandListener;
\r
36 import javax.microedition.lcdui.Display;
\r
37 import javax.microedition.lcdui.Displayable;
\r
38 import javax.microedition.media.Manager;
\r
39 import javax.microedition.media.MediaException;
\r
40 import javax.microedition.media.Player;
\r
41 import javax.microedition.media.control.VideoControl;
\r
42 import javax.microedition.midlet.MIDlet;
\r
43 import javax.microedition.midlet.MIDletStateChangeException;
\r
44 import java.io.IOException;
\r
45 import java.util.Vector;
\r
48 * <p>The actual reader application {@link MIDlet}.</p>
\r
51 * @author Simon Flannery
\r
53 public final class ZXingMIDlet extends MIDlet {
\r
55 private static final int ALERT_TIMEOUT_MS = 5 * 1000;
\r
57 private Canvas canvas;
\r
58 private Player player;
\r
59 private VideoControl videoControl;
\r
60 private Alert confirmation;
\r
61 private Alert alert;
\r
62 private Menu history;
\r
63 private Vector resultHistory;
\r
65 Displayable getCanvas() {
\r
69 Player getPlayer() {
\r
73 VideoControl getVideoControl() {
\r
74 return videoControl;
\r
77 static MultimediaManager buildMultimediaManager() {
\r
78 return new AdvancedMultimediaManager();
\r
79 // Comment line above / uncomment below to make the basic version
\r
80 // return new DefaultMultimediaManager();
\r
83 protected void startApp() throws MIDletStateChangeException {
\r
85 Image image = Image.createImage("/res/zxing-icon.png");
\r
86 Displayable splash = new SplashThread(this, 2000, image);
\r
87 Display.getDisplay(this).setCurrent(splash);
\r
89 resultHistory = new Vector(5);
\r
90 history = new Menu(this, "Scan History", "Use");
\r
92 player = createPlayer();
\r
94 MultimediaManager multimediaManager = buildMultimediaManager();
\r
95 multimediaManager.setZoom(player);
\r
96 multimediaManager.setExposure(player);
\r
97 videoControl = (VideoControl) player.getControl("VideoControl");
\r
98 canvas = new VideoCanvas(this);
\r
99 canvas.setFullScreenMode(true);
\r
100 videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, canvas);
\r
101 videoControl.setDisplayLocation(0, 0);
\r
102 videoControl.setDisplaySize(canvas.getWidth(), canvas.getHeight());
\r
103 } catch (IOException ioe) {
\r
104 throw new MIDletStateChangeException(ioe.toString());
\r
105 } catch (MediaException me) {
\r
106 throw new MIDletStateChangeException(me.toString());
\r
109 // Set up one confirmation and alert object to re-use
\r
110 confirmation = new Alert(null);
\r
111 confirmation.setType(AlertType.CONFIRMATION);
\r
112 confirmation.setTimeout(ALERT_TIMEOUT_MS);
\r
113 Command yes = new Command("Yes", Command.OK, 1);
\r
114 confirmation.addCommand(yes);
\r
115 Command no = new Command("No", Command.CANCEL, 1);
\r
116 confirmation.addCommand(no);
\r
117 alert = new Alert(null);
\r
118 alert.setTimeout(ALERT_TIMEOUT_MS);
\r
121 void splashDone() {
\r
123 videoControl.setVisible(true);
\r
125 } catch (MediaException me) {
\r
128 Display.getDisplay(this).setCurrent(canvas);
\r
131 private static Player createPlayer() throws IOException, MediaException {
\r
132 // Try a workaround for Nokias, which want to use capture://image in some cases
\r
133 Player player = null;
\r
134 String platform = System.getProperty("microedition.platform");
\r
135 if (platform != null && platform.indexOf("Nokia") >= 0) {
\r
137 player = Manager.createPlayer("capture://image");
\r
138 } catch (MediaException me) {
\r
139 // if this fails, just continue with capture://video
\r
140 } catch (Error e) {
\r
141 // Ugly, but, it seems the Nokia N70 throws "java.lang.Error: 136" here
\r
142 // We should still try to continue
\r
145 if (player == null) {
\r
146 player = Manager.createPlayer("capture://video");
\r
151 protected void pauseApp() {
\r
152 if (player != null) {
\r
155 } catch (MediaException me) {
\r
162 protected void destroyApp(boolean unconditional) {
\r
163 if (player != null) {
\r
164 videoControl = null;
\r
167 } catch (MediaException me) {
\r
170 player.deallocate();
\r
181 void historyRequest() {
\r
182 Display.getDisplay(this).setCurrent(history);
\r
185 // Convenience methods to show dialogs
\r
187 private void showOpenURL(String title, String display, final String uri) {
\r
188 confirmation.setTitle(title);
\r
189 confirmation.setString(display);
\r
190 CommandListener listener = new CommandListener() {
\r
191 public void commandAction(Command command, Displayable displayable) {
\r
192 if (command.getCommandType() == Command.OK) {
\r
194 platformRequest(uri);
\r
195 } catch (ConnectionNotFoundException cnfe) {
\r
202 Display.getDisplay(ZXingMIDlet.this).setCurrent(getCanvas());
\r
206 confirmation.setCommandListener(listener);
\r
207 showAlert(confirmation);
\r
210 private void showAlert(String title, String text) {
\r
211 alert.setTitle(title);
\r
212 alert.setString(text);
\r
213 alert.setType(AlertType.INFO);
\r
217 void showError(Throwable t) {
\r
218 String message = t.getMessage();
\r
219 if (message != null && message.length() > 0) {
\r
220 showError(message);
\r
222 showError(t.toString());
\r
226 void showError(String message) {
\r
227 alert.setTitle("Error");
\r
228 alert.setString(message);
\r
229 alert.setType(AlertType.ERROR);
\r
233 private void showAlert(Alert alert) {
\r
234 Display display = Display.getDisplay(this);
\r
235 display.setCurrent(alert, canvas);
\r
238 void barcodeAction(ParsedResult result) {
\r
239 ParsedResultType type = result.getType();
\r
240 if (type.equals(ParsedResultType.URI)) {
\r
241 String uri = ((URIParsedResult) result).getURI();
\r
242 showOpenURL("Open Web Page?", uri, uri);
\r
243 } else if (type.equals(ParsedResultType.EMAIL_ADDRESS)) {
\r
244 EmailAddressParsedResult emailResult = (EmailAddressParsedResult) result;
\r
245 showOpenURL("Compose E-mail?", emailResult.getEmailAddress(), emailResult.getMailtoURI());
\r
246 } else if (type.equals(ParsedResultType.SMS)) {
\r
247 SMSParsedResult smsResult = (SMSParsedResult) result;
\r
248 showOpenURL("Compose SMS?", smsResult.getNumber(), smsResult.getSMSURI());
\r
249 } else if (type.equals(ParsedResultType.PRODUCT)) {
\r
250 ProductParsedResult productResult = (ProductParsedResult) result;
\r
251 String uri = "http://www.upcdatabase.com/item.asp?upc=" + productResult.getNormalizedProductID();
\r
252 showOpenURL("Look Up Barcode Online?", productResult.getProductID(), uri);
\r
253 } else if (type.equals(ParsedResultType.TEL)) {
\r
254 TelParsedResult telResult = (TelParsedResult) result;
\r
255 showOpenURL("Dial Number?", telResult.getNumber(), telResult.getTelURI());
\r
257 showAlert("Barcode Detected", result.getDisplayResult());
\r
261 void itemRequest() {
\r
262 ParsedResult result = (ParsedResult) resultHistory.elementAt(history.getSelectedIndex());
\r
263 barcodeAction(result);
\r
266 void handleDecodedText(Result theResult) {
\r
267 ParsedResult result = ResultParser.parseResult(theResult);
\r
268 String resultString = result.toString();
\r
270 while (i < resultHistory.size()) {
\r
271 if (resultString.equals(resultHistory.elementAt(i).toString())) {
\r
276 if (i == resultHistory.size()) {
\r
277 resultHistory.addElement(result);
\r
278 history.append(result.getDisplayResult(), null);
\r
280 barcodeAction(result);
\r