La librería zXing es un proyecto open-source (libre de derechos de autor para uso y modificación) que ofrece soporte para la lectura y decodificación para la gran mayoría de códigos de barras, códigos BIDI o QR en múltiples plataformas. En este documento nos centraremos en su versión para Android.
El código se puede descargar desde el siguiente repositorio SVN de Google Code: Libreria zXing
Instalación de la librería:
Nota: Para los ejemplos de este documento, se está usando la versión API 10 del SDK de Android y Eclipse versión Indigo para Windows. En caso de estar utilizando una versión diferente como Helios o Juno, tan solo hay que sustituir las apariciones de un nombre por el de la otra versión
- Pasos previos: Para descargar un proyecto SVN en Eclipse, es necesario tener instalado el plug-in Subversive. Si ya dispone de él, puede omitir este paso y el siguiente.
- En la ventana principal de Eclipse, pulsar en: Help>Install New Software
- En el cuadro que pone Work with elegir:
- Expandir el nodo de Collaboration.
- Buscar y marcar la casilla de Subversive Team Provider (incubation) y pulsar siguiente
- Pulsar Next de nuevo, aceptar la licencia y click Finish. Subversive se descargará y se instalará.
- Reiniciar Eclipse para que los cambios surtan efecto.
Instalación subversive SVN Connectors
Además del plug-in son necesarios los SVN Connectors para conectar con el servidor.
-
En la ventana principal de Eclipse, pulsar en: Help>Install New Software
-
En el cuadro que pone Work with escribir: http://community.polarion.com/projects/subversive/download/eclipse/2.0/indigo-site/
-
Expandir los Subversive SVN Connectors, elige la casilla de Subversive SVN Connectors y de los opcionales, la última versión disponible del SVNKit y pulsar Next
-
Pulsar Next de nuevo, aceptar la licencia y click Finish. Subversive se descargará y se instalará.
-
Reiniciar Eclipse para que los cambios surtan efecto.
Con esto ya tenemos todo lo necesario para descargar cualquier proyecto desde un repositorio SVN como el de la librería zXing
Adquirir y compilar la librería zXing
1.- Descarga la librería desde el repositorio
En este paso obtendremos el código fuente para la creación de la librería desde el repositorio SVN de Google Code en Eclipse
-
Si no está activa la vista de repositorios (en la parte inferior de la pantalla, en la misma zona que aparece la consola) pulsa en:
- Window > Show View > Other > SVN > SVN Repositories.
-
Crear un nuevo repositorio a través de la vista de repositorios: Pulsar en el cilindro con el + verde y añadir a siguiente URL: http://zxing.googlecode.com/svn/
-
Cuando aparezca el repositorio en la vista de repositorios, pulsar con el botón derecho en él y pulsar en Check out. Con esto descargaremos todo el código en un nuevo proyecto que se llamará svn.
2.- Obtener Proguard y Ant
Para compilar el código en Android, son necesarias 2 utilidades: Proguard y Ant. Ambas se usan desde la línea de comandos. Proguard sirve para hacer más eficiente el código y la Ant para compilar proyectos java. La ventaja de usar Ant como herramienta para scripts de compilación es que es multiplataforma, con lo que no tenemos que tener distintos archivos de compilación según el SO estemos usando.
-
Descargamos ambas utilidades desde los enlaces: Proguard y Ant y descomprimimos su contenido.
-
Vamos a Eclipse y en la carpeta svn que se ha creado con el proyecto descargado, nos dirigimos al subdirectorio trunk.
-
Buscar el archivo build.properties y modificarlo de la siguiente manera:
-
Añadir la línea: proguard-jar=X. Donde X es la ruta donde descomprimimos el proguard: e.g.: C:\\proguard4.6\\bin\\proguard.jar)
-
Añadir la línea: android-home=X. Donde X es la ruta donde se encuentra el SDK de Android: e.g.: C:\\Android\\android-sdk-windows)
-
Necesitamos añadir y modificar algunas variables de entorno del sistema. Para ello: Botón derecho sobre Equipo > Propiedades > Configuración Avanzada del Sistema > Variables de entorno…
-
Añadir la variable JAVA_HOME y como valor añadimos la ruta donde se encuentre instalado el JDK (e.g: C:\Program Files\Java\jdk1.6.0_21)
-
Añadir la variable ANT_HOME y como valor añadimos la ruta donde se encuentre descomprimido el Ant (e.g.:C:\apache-ant-1.8.2)
-
Añadir la variable CLASSPATH y como valor escribimos “;” sin las comillas
-
Modificamos la variable Path añadiendo las 2 rutas de la carpeta bin del JDK y del Ant, separadas por “;”.
(e.g: C:\Program Files\Java\jdk1.6.0_21\bin;C:\apache-ant-1.8.2\bin)
3.- Compilar el código de la librería
Para obtener la librería, primero es necesario compilar el core:
-
Abrimos una consola (Símbolo del Sistema de Windows)
-
Navegamos (con el comando cd) hasta la ruta del proyecto svn en Eclipse
-
Accedemos a la carpeta core, donde aparezca el archivo build.xml (Si no aparece, usar el comando dir para verlo). Este archivo lo usa Ant para compilar, por lo que asegurarse de que estamos en la ruta correcta ya que de lo contrario no se compilará correctamente. Cada carpeta posee su propio build.xml.
-
Ejecutar el comando: ant build export
Así compilamos sin información de debug para que no existan problemas de incompatibilidad con Android
Con estos pasos hechos, si vamos a la carpeta core encontraremos el archivo core.jar que es la librería compilada que después incluiremos en nuestro proyecto.
Incrustar la librería sobre nuestro proyecto
1.- Configuración de la librería
Anteriormente, hemos descargado un repositorio SVN. Este contiene el soporte para varios lenguajes, pero como a nosotros solo nos interesa la parte de Android, vamos a seleccionar que archivos queremos mantener y cuales no interesan
- En una ventana del Explorador de Windows, navegar hasta la carpeta que contenga el workspace donde descargamos el repositorio. Accedemos a él (carpeta svn) y después a la carpeta trunk.
-
Copiamos la carpeta android a nuestro workspace.
-
Copiar el core.jar compilado en el apartado anterior en:
-
En la carpeta libs del proyecto BiljetApp y
-
En la carpeta libs del proyecto copiado en el paso anterior (CaptureActivity)
- Con este paso, Eclipse debería reconocer el .jar como una librería del proyecto automáticamente. En caso de que no, habría que importarlo manualmente:
- 1: Botón derecho sobre el proyecto > Build Path > Configure Build Path
- 2: En la pestaña Libraries, pulsar en Add External JARs… y seleccionar el core.jar
-
Una vez ubicada la carpeta, volvemos a Eclipse y sobre la vista de proyectos, pulsamos File > Import… > General > Existing projects into a Workspace
-
En root directory seleccionar la ruta que contiene el workspace actual
-
Cuando haya cargado la lista de proyectos disponibles que contiene el workspace, pulsa en Deselect All, buscar el proyecto CaptureActivity, y marcarlo (solo se necesita ese)
-
Una vez se tenga el proyecto importado, se puede desconectar del SVN: Sobre el proyecto svn y CaptureActivity, pulsar en Team > Disconnect y después en Yes. Si no aparece, es que ya estaba desconectado.
-
Ahora que tenemos la parte que nos interesa, ya se puede eliminar el proyecto svn del workspace e incluso del disco duro.
-
Sobre el proyecto CaptureActivity, pulsar Botón derecho > Properties > Android y marcar la casilla IsLibrary. Este proyecto (CaptureActivity) es el que vamos a usar como librería para el nuestro (BiljetApp)
Con estos pasos la librería ya se encuentra configurada para usarla. A continuación se enumeran algunos problemas que pueden surgir
Solucion:
Sitúa el ratón en cada switch que esté marcado con error y pulsar CTRL+1 y a
continuación elige la opción de Convert switch to if-then-else
Solución:
Prueba a bajar la versión del JDK usado para compilar a la 1.6
Si se siguen encontrando errores, pulsar en Project > Clean… para volver a generar el R.java
2.- Enlazar el proyecto zXing con el nuestro
Ya tenemos la librería configurada para ser usada. Vamos a enlazarla en el proyecto concreto en el que la vamos a usar (BiljetApp)
-
Sobre el proyecto BiljetApp pulsar Botón derecho > Properties > Android y en el apartado Libraries pulsar sobre Add…. Seleccionamos la librería creada en el paso anterior.
-
Añadir el siguiente código al botón u objeto que lanzará el escáner de códigos:
- Intent intent = new Intent(“com.google.zxing.client.android.SCAN”);
- intent.putExtra(“SCAN_MODE”, “QR_CODE_MODE”);
- startActivityForResult(intent, 0);
-
En la misma actividad que incluimos el botón con el intent para lanzar el escáner, situar este método para recoger los resultados:
- public void onActivityResult(int requestCode, int resultCode, Intent intent) {
- if (requestCode == 0) {
- if (resultCode == RESULT_OK) {
- String contents = intent.getStringExtra(“SCAN_RESULT”);
- String format = intent.getStringExtra(“SCAN_RESULT_FORMAT”);
- // Handle successful scan
- } else if (resultCode == RESULT_CANCELED) {
- // Handle cancel
- }
- }
- }
-
Registrar el intent en el android.manifest del proyecto. Añadir:
- <activity
- android:clearTaskOnLaunch=”true”
- android:stateNotNeeded=”true”
- android:configChanges=”orientation|keyboardHidden”
- android:name=”com.google.zxing.client.android.CaptureActivity”
- android:screenOrientation=”landscape”
- android:theme=”@android:style/Theme.NoTitleBar.Fullscreen”
- android:windowSoftInputMode=”stateAlwaysHidden” >
- <intent-filter >
- <action android:name=”android.intent.action.MAIN” />
- <category android:name=”android.intent.category.DEFAULT” />
- </intent-filter>
- <intent-filter >
- <action android:name=”com.google.zxing.client.android.SCAN” />
- <category android:name=”android.intent.category.DEFAULT” />
- </intent-filter>
- </activity>
-
Añadir también en el manifest permisos para poder utilizar la cámara del terminal.
- <uses-permission android:name=”android.permission.CAMERA”></uses-permission>
Con estos pasos la librería ya se encuentra incrustada completamente en el proyecto. A continuación se enumeran algunos problemas que puedan surgir y mejoras que son aplicables:
Problemas:
Al usar la cámara se obtienen errores, problemas o la aplicación se cierra inesperadamente
Solución:
Añadir las siguientes líneas de código al manifest:
- <uses-feature android:name=”android.hardware.camera” />
- <uses-feature
- android:name=”android.hardware.camera.autofocus”
- android:required=”false” />
- <uses-feature
- android:name=”android.hardware.touchscreen”
- android:required=”false” />
- <uses-sdk
- android:minSdkVersion=”10″
- android:targetSdkVersion=”10″ />
Al pulsar la tecla de menú o ··· del terminal y una de sus opciones, la aplicación se cierra inesperadamente
Solución:
En el paquete com.google.zxing.cient.android, ir a CaptureActivity.java y comentar los siguientes métodos:
-
onCreateOptionsMenu(Menu menu)
-
onOptionsItemSelected(MenuItem item)
-
onPrepareOptionsMenu(Menu menu) (Solo si aparece)
El nombre de tu aplicación se ve sobrescrito por Barcode Scanner
Solución:
Dentro del proyecto, navegamos a res > values > strings.xml. Cambiamos el string app_name por el de nuestra aplicación. Este paso se debería repetir para cada carpeta values-xx que exista. Si no queremos dar soporte multilenguaje, eliminar todas esas carpetas y dejar únicamente la carpeta values
Mejoras:
Al pulsar el botón que lanza el escáner, aparece un menú preguntando qué aplicación se desea usar para llevar a cabo el escaneo.
Solución:
Hay que modificar 3 archivos para evitar que aparezca el menú:
-
En el android.manifest (tanto del CaptureActivity, como del BiljetApp), en el intent-filter > action realizar el mismo cambio de nombre. NO modificar el nombre de la actividad asociada en el android:name en el apartado <activity>. Ej:
Hacer que la máscara del escáner tenga forma cuadrada (para códigos QR) en lugar de rectangular (para todo tipo de códigos como los de barras)
Solución:
En el paquete com.google.zxing.client.camera, en el archivo CameraManager.java, en el método getFramingRect(), cambiar la línea:
- int width = screenResolution.x * 3 / 4;
Si cambiamos el 3 / 4 por 1 / 2, conseguiremos que la máscara se vuelva un cuadrado
Eliminar el texto en vertical (debido a que está en modo landscape por defecto)
Solución:
En el paquete com.google.zxing.client.android, en el archivo CaptureActivity.java, en el metodo resetStatusView() , cambiar la línea:
- statusView.setVisibility(View.VISIBLE);
Por la siguiente:
- statusView.setVisibility(View.INVISIBLE);
Eliminar que muestre la ayuda:
Solución:
En el paquete com.google.zxing.client.android, en el archivo CaptureActivity.java, en el método onCreate(Bundle icicle), comentar la línea:
Errores Comunes:
E/AndroidRuntime(848): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.google.zxing.client.android.SCAN
Solución:
Verificar que cuando se cambió los nombres de los intents, se realizó en TODOS los archivos que se citó arriba
E/AndroidRuntime(946): java.lang.VerifyError: com.google.zxing.client.android.CaptureActivity
Solución:
La versión del proyecto y de la librería core.jar no se corresponden. Verificar que hay concordancia
E/AndroidRuntime(1214): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.android.prueba/LINEAMODIFICADA.CaptureActivity}: java.lang.ClassNotFoundException: LINEAMODIFACADA.CaptureActivity in loader dalvik.system.PathClassLoader[/data/app/com.android.prueba-1.apk]
Solución:
La línea del manifest de proyecto propio (BiljetApp) que indica que clase está asociada al intent action que lanzas no esta bien configurada, debe ser esta: android:name=”com.google.zxing.client.android.CaptureActivity”. En el ejemplo de arriba el error sería LINEAMODIFICADA.