我有一个应该可以在蓝牙打印机Zebra ZQ320上进行打印的应用程序,但是我对某些特定字符有一些疑问,该项目中与打印机配置有关的唯一事情是一个名为“ UtileriaImpresion”的类。斑马纹的配置增加了IMZ320,而以前使用的模型也存在相同的问题。
UtileriaImpresion类
package com.hdi.ajustadormovil.utilidades;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import com.hdi.ajustadormovil.R;
import com.hdi.ajustadormovil.actividades.ImpresoraNoEncontradaException;
import com.hdi.ajustadormovil.unicos.PersistenciaUnico;
import com.zebra.sdk.comm.BluetoothConnection;
import com.zebra.sdk.comm.Connection;
import com.zebra.sdk.comm.ConnectionException;
import org.riversun.finbin.BigBinarySearcher;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class UtileriaImpresion {
/**
* Tag para el debug de Android.
*/
private static final String tag = UtileriaImpresion.class.getName();
/**
* Ejecuta un hilo secundario donde se intenta imprimir el vale indicado.
*
* @param context Contexto actual de la aplicación.
* @param parametros Mapa con los parámetros a reemplazar en el ticket.
* @param archivo Indica el nombre del archivo en los Assets.
* @param mac Dirección mac de la impresora a la que se debe conectar.
*/
public static void imprimir(final Context context, final Map<String, String> parametros, final String archivo, final String mac) {
Log.v(tag, "imprimir");
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
if (ba == null) {
Toast.makeText(context, R.string.encienda_bluetooth, Toast.LENGTH_SHORT).show();
return;
}
if (!ba.isEnabled()) {
Toast.makeText(context, R.string.encienda_bluetooth, Toast.LENGTH_SHORT).show();
return;
}
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Connection cnn = null;
try {
byte[] bytes = UtileriaImpresion.obtenerBytesTemplateImpresion(context, archivo, parametros);
cnn = new BluetoothConnection(mac);
cnn.open();
cnn.write(bytes);
Toast.makeText(context, R.string.impresion_terminada, Toast.LENGTH_LONG).show();
Log.i(tag, "Impresión terminada");
} catch (ConnectionException cex) {
Log.e(tag, "imprimir", cex);
PersistenciaUnico.obtenerInstancia().guardarLog(tag, PersistenciaUnico.nivel.error, "", cex.getMessage() != null ? cex.getMessage() : "No se generó mensaje descriptivo para la excepción");
Toast.makeText(context, R.string.impresora_no_conectada, Toast.LENGTH_LONG).show();
} catch (Exception ex) {
Log.e(tag, "imprimir", ex);
PersistenciaUnico.obtenerInstancia().guardarLog(tag, PersistenciaUnico.nivel.error, "", ex.getMessage() != null ? ex.getMessage() : "No se generó mensaje descriptivo para la excepción", "Ninguno");
Toast.makeText(context, R.string.error_impresion, Toast.LENGTH_LONG).show();
} finally {
if (cnn != null && cnn.isConnected()) {
try {
cnn.close();
} catch (ConnectionException cex) {
Log.e(tag, "imprimir", cex);
PersistenciaUnico.obtenerInstancia().guardarLog(tag, PersistenciaUnico.nivel.error, "", cex.getMessage() != null ? cex.getMessage() : "No se generó mensaje descriptivo para la excepción", "Ninguno");
}
}
Looper.loop();
Looper looper;
looper = Looper.myLooper();
if (looper != null) {
looper.quit();
}
}
}
}).start();
}
/**
* Lee el archivo especificado de los assets de la aplicación, reemplaza los
* parámetros indicados y genera el arreglo de bytes resultate listo para
* mandar a la impresora.
*
* @param context Contexto actual de la aplicación.
* @param nombreArchivo Nombre de archivo (con extención) en assets de la aplicación.
* @param parametros Mapa con los parámetros a sustituir en el archivo.
* @return Arreglo de bytes que contiene el archivo leído y los parámetros
* indicados.
* @throws IOException Si no se pudo abrir el archivo por alguna razón.
*/
public static byte[] obtenerBytesTemplateImpresion(Context context, String nombreArchivo, Map<String, String> parametros) throws IOException {
InputStream in = context.getAssets().open(nombreArchivo);
byte[] bytes = new byte[in.available()];
in.read(bytes);
in.close();
BigBinarySearcher searcher = new BigBinarySearcher();
for (Map.Entry<String, String> parametro : parametros.entrySet()) {
byte[] bytesKey = parametro.getKey().getBytes();
int indice = searcher.indexOf(bytes, bytesKey);
if (indice >= 0) {
byte[] respaldoIzquierda = Arrays.copyOfRange(bytes, 0, indice);
byte[] respaldoDerecha = Arrays.copyOfRange(bytes, indice + bytesKey.length + 1, bytes.length);
byte[] bytesValue = parametro.getValue().getBytes();
ByteBuffer buffer = ByteBuffer.allocate(respaldoIzquierda.length + bytesValue.length + respaldoDerecha.length);
// Se agregan los bytes de la izquierda.
buffer.put(respaldoIzquierda);
// Se agregan los bytes de medio.
buffer.put(bytesValue);
// Se agregan los bytes del final.
buffer.put(respaldoDerecha);
// Se reemplaza el array orignal.
bytes = buffer.array();
}
}
return bytes;
}
/**
* Obtiene la impresora que se configuró como predeterminada en las
* preferencias del sistema.
*
* @param context Contexto actual de la aplicación.
* @return Cadena de texto que contiene la dirección mac, si la cadena esta
* vacía o es nula se puede considerar que no se ha configurado la
* impresora.
* @throws ImpresoraNoEncontradaException Si no se ha encontrado la configuración de la impresora
* predeterminada.
*/
public static String obtenerDireccionMacImpresora(Context context) throws ImpresoraNoEncontradaException {
SharedPreferences sp = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
String mac = sp.getString(Constantes.SHARED_PREFERENCES_IMPRESORA, "");
if (mac.length() == 0) {
throw new ImpresoraNoEncontradaException("No se ha encontrado la impresora predeterminada, por favor configure alguna");
}
return mac;
}
/**
* Establece un centrado relativo del texto indicado de acuerdo a la letra
* que se utiliza por defecto en la impresora zebra IMZ320 (Zebra Times 5.0
* de 8.5 Pt) para imprimir los campos.
* </p>
* El centrado se hace llenando con espacios en blanco el lado izquierdo del
* texto, teniendo en cuenta que por renglón y en dicha fuente, la impresora
* puede pintar 48 caracteres.
*
* @param texto Texto a centrar.
* @return Nueva cadena de texto que contiene el centrado relativo.
*/
public static String centrarTexto(String texto) {
// Variable que indica el límite de caracteres que caben en una línea.
int limite = 48;
if (StringUtilities.isEmptyOrNull(texto)) {
return texto;
}
if (!texto.matches("[0-9]+")) {
if (StringUtilities.isAllUpper(texto) || StringUtilities.cantidadMayusculasContinuas(texto, 5)) {
limite = 35;
}
}
if (texto.length() == limite) {
return texto;
}
int espacios;
espacios = (limite - texto.length()) / 2;
espacios = Double.valueOf(espacios * 1.8).intValue();
return StringUtilities.padLeft(texto, espacios + texto.length());
}
/**
* Descompone el texto indicado en diferentes renglones teniendo en cuenta
* que cada renglón puede tener un máximo de 48 caractéres en minúscula y 30
* en mayúscula.
*
* @param texto Cadena de texto.
* @return Lista de cadenas de texto.
* @throws NullPointerException Si el parámetro texto es nulo.
*/
public static List<String> obtenerRenglones(String texto) throws NullPointerException {
// Variable que indica el límite de caracteres que caben en una línea.
int limite = 48;
if (texto == null) {
throw new NullPointerException("El parámetro texto no debe ser nulo");
}
if (StringUtilities.isAllUpper(texto) || StringUtilities.cantidadMayusculasContinuas(texto, 5)) {
limite = 35;
}
if (texto.trim().length() <= limite) {
List<String> lst = new ArrayList<>();
lst.add(texto);
return lst;
}
texto += " |";
String[] partes = texto.split(" ");
List<String> resultado = new ArrayList<>();
StringBuilder renglon = new StringBuilder();
for (int i = 0; i < partes.length - 1; i++) {
renglon.append(partes[i]);
if (renglon.length() + 1 + partes[i + 1].length() > limite) {
resultado.add(renglon.toString().trim());
renglon = new StringBuilder();
} else {
renglon.append(" ");
}
}
resultado.add(renglon.toString().trim());
return resultado;
}
}
答案 0 :(得分:1)
没有更多详细信息或看到一些代码,看起来像UTF-8印刷为ISO-8859-1。在ZPL中,您需要通过^CI28
将打印机设置为使用UTF-8。