/* * BarcodeScanDemo.java * * Copyright � 1998-2011 Research In Motion Limited * * 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. * * Note: For the sake of simplicity, this sample application may not leverage * resource bundles and resource strings. However, it is STRONGLY recommended * that application developers make use of the localization features available * within the BlackBerry development platform to ensure a seamless application * experience across a variety of languages and geographies. For more information * on localizing your application, please refer to the BlackBerry Java Development * Environment Development Guide associated with this release. */ package com.rim.samples.device.barcodescandemo; import java.util.Hashtable; import java.util.Vector; import net.rim.device.api.amms.control.camera.ImageDecoder; import net.rim.device.api.amms.control.camera.ImageDecoderListener; import net.rim.device.api.amms.control.camera.ImageScanner; import net.rim.device.api.barcodelib.BarcodeDecoder; import net.rim.device.api.system.Display; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.FieldChangeListener; import net.rim.device.api.ui.TransitionContext; import net.rim.device.api.ui.Ui; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.UiEngineInstance; import net.rim.device.api.ui.component.ButtonField; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.container.MainScreen; import com.google.zxing.BarcodeFormat; import com.google.zxing.DecodeHintType; import com.google.zxing.Result; /* * This application demonstrates the use of the Barcode API. It * presents a simple interface for accessing and displaying a window * in which the user can center a bar code. When a code is scanned, * the application will display the code's type and embedded data. */ public final class BarcodeScanDemo extends UiApplication { /** * Entry point for the application * * @param args * Command-line argument (not used) */ public static void main(final String[] args) { new BarcodeScanDemo().enterEventDispatcher(); } /** * Creates a new BarcodeScanDemo object */ public BarcodeScanDemo() { pushScreen(new ScanScreen()); } } /** * A UI screen to display the camera display and buttons */ final class ScanScreen extends MainScreen { private ImageScanner _scanner; private MainScreen _vfScreen; private ButtonField _QRButton; private ButtonField _UPCButton; private ButtonField _dataMatrixButton; private ButtonField _code128Button; /** * Creates a new ScanScreen object */ public ScanScreen() { // Set the title of the screen setTitle("Barcode Scan Demo"); buildUi(); } /** * Builds the user interface. Adds buttons and registers MyFieldListeners * for each. */ private void buildUi() { _QRButton = new MyButtonField("Scan QR", ButtonField.CONSUME_CLICK | ButtonField.NEVER_DIRTY | Field.FIELD_HCENTER | Field.FIELD_VCENTER); _QRButton.setChangeListener(new MyFieldListener()); _dataMatrixButton = new MyButtonField("Scan DataMatrix", ButtonField.CONSUME_CLICK | ButtonField.NEVER_DIRTY | Field.FIELD_HCENTER | Field.FIELD_VCENTER); _dataMatrixButton.setChangeListener(new MyFieldListener()); _UPCButton = new MyButtonField("Scan UPC", ButtonField.CONSUME_CLICK | ButtonField.NEVER_DIRTY | Field.FIELD_HCENTER | Field.FIELD_VCENTER); _UPCButton.setChangeListener(new MyFieldListener()); _code128Button = new MyButtonField("Scan Code 128", ButtonField.CONSUME_CLICK | ButtonField.NEVER_DIRTY | Field.FIELD_HCENTER | Field.FIELD_VCENTER); _code128Button.setChangeListener(new MyFieldListener()); add(_QRButton); add(_dataMatrixButton); add(_UPCButton); add(_code128Button); } /** * Allows for larger than normal ButtonFields */ private class MyButtonField extends ButtonField { public MyButtonField(final String label, final long style) { super(label, style); } /** * Retreives the buttons perferred width (60% of Display.getWidth()) * * @return The preferred width of the button */ public int getPreferredWidth() { return (int) (Display.getWidth() * 0.60); } } /** * @see net.rim.device.api.ui.container.MainScreen#onSavePrompt() */ protected boolean onSavePrompt() { // Prevent the save dialog from being displayed return true; } /** * Displays the decoded barcode text and the type of barcode that was just * scanned. * * @param result * The results from scanning a barcode */ public void inform(final Result result) { // Close the viewfinder first UiApplication.getUiApplication().popScreen(_vfScreen); final MainScreen resultsScreen = new MainScreen(); final LabelField text = new LabelField("Barcode Text: " + result.getText()); text.setPadding(4, 4, 4, 4); final LabelField type = new LabelField("Barcode Type: " + result.getBarcodeFormat().toString()); type.setPadding(4, 4, 4, 4); final TransitionContext context = new TransitionContext(TransitionContext.TRANSITION_SLIDE); context.setIntAttribute(TransitionContext.ATTR_DIRECTION, TransitionContext.KIND_OUT); Ui.getUiEngineInstance().setTransition(null, resultsScreen, UiEngineInstance.TRIGGER_PUSH, context); resultsScreen.add(text); resultsScreen.add(type); UiApplication.getUiApplication().pushScreen(resultsScreen); } /** * Initializes the camara to begin scanning the barcode * * @param decoder * The decoder that is going to be used to decode the barcode * @param listener * The listner that is going to be used to tell when the barcode * is scanned * @return An initialized Viewfinder screen to be displayed */ private Field initializeCamera(final ImageDecoder decoder, final ImageDecoderListener listener) { try { // Check if the ImageScanner has already been initialized. If it // has, // make sure to close its player, so that a new one can be created. if (_scanner != null) { _scanner.getPlayer().close(); } _scanner = new ImageScanner(decoder, listener); _scanner.getVideoControl().setDisplayFullScreen(true); _scanner.startScan(); return _scanner.getViewfinder(); } catch (final Exception e) { } return null; } /** * Handles field change events */ private class MyFieldListener implements FieldChangeListener { final ImageDecoderListener _imageDecoderListener = new ImageDecoderListener() { /** * @see net.rim.device.api.amms.control.camera.ImageDecoderListener#imageDecoded(Object) */ public void imageDecoded(final Object decoded) { UiApplication.getUiApplication().invokeLater( new Runnable() { public void run() { inform((Result) decoded); } }); } }; /** * Listens for when a button is pressed * * @see net.rim.device.api.ui.FieldChangeListener#fieldChanged(Field, * int) */ public void fieldChanged(final Field field, final int context) { final Vector formats = new Vector(); // Find what button was pressed and add its format(s) to the vector if (field == _QRButton) { System.out.println("QR button"); formats.addElement(BarcodeFormat.QR_CODE); } else if (field == _dataMatrixButton) { formats.addElement(BarcodeFormat.DATAMATRIX); } else if (field == _UPCButton) { formats.addElement(BarcodeFormat.UPC_A); formats.addElement(BarcodeFormat.UPC_E); formats.addElement(BarcodeFormat.EAN_13); formats.addElement(BarcodeFormat.EAN_8); } else if (field == _code128Button) { formats.addElement(BarcodeFormat.CODE_128); } // Allows for the decoder to look for a specific type of barcode. // Can increase the decoders speed or accuracy. final Hashtable hints = new Hashtable(); hints.put(DecodeHintType.POSSIBLE_FORMATS, formats); // Uncomment the following line of java code if you wish to // "try harder", // but expect that as a result the decoding time for each image // processed // may take upwards of 20 times as long. It is recommended that this // setting // not be used in most cases. // hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); // Initialize the camera object and video field final Field cameraField = initializeCamera(new BarcodeDecoder(hints), _imageDecoderListener); // If the field was constructed successfully, create the UI if (cameraField != null) { _vfScreen = new MainScreen(); _vfScreen.add(cameraField); UiApplication.getUiApplication().pushScreen(_vfScreen); } } } }