Android 热敏打印机打印二维码

      最近项目需要研究下Android通过usbhost和蓝牙连接热敏打印机打印小票,收集了一下资料参考,感觉这块技术比较乱的,每家打印机都有自己的SDK,但其实底层的原理差不多,做个稳定兼容多个品牌热敏打印机的APP还是有难度的。


  昨天晚上说抽时间来写一篇关于Android 热敏打印机打印二维码和图片的文章,所幸在下班之前把它给写了,和大家分享吧。我的是Android机器有内置热敏打印机的,我是把apk跑在我的Android机器上的,操作程序打印的。

  一、打印机的型号

  RP-POS80S或RP-POS80P或RP-POS80CS或RP-POS80CP打印机 高速热敏打印机
  打印方式:直接热敏打印
  打印密度:640点/行
  打印纸宽:80mm
  有效打印宽度:72mm
  最小走纸距离:0.125mm
  打印字符
  ACSII码字符集:12×24点
  国标一、二级汉字字库:24×24点
  采用命令集:ESC/POS打印命令集

  二、打印位图命令

     ESC *m nL nH d1...dk
     [名称]   选择位图模式
     [格式]   ASCII码   ESC  *       m nL nH d1...dk
     十六进制码    1B   2A   m nL nH d1...dk
     十进制码   27  42   m nL nH d1...dk
     [范围]   m= 0, 1, 32, 33
     0 £ nL£ 255
     0 £ nH£ 3
     0 £ d£ 255



[描述]用 m选择位图的模式,位图的点数由 nL和 nH指定,如下所示:
  
m
  
模式
垂直方向
水平方向
点数
点密度
点密度
数据个数 (K)
0
8-点 单密度
8
67.7 dpi
101.6 dpi
nL+ nH´ 256
1
8-点 双密度
8
67.7 dpi
203.2 dpi
nL+ nH´ 256
32
24-点 单密度
24
203.2 dpi
101.6 dpi
(nL+ nH ´ 256) ´3
33
24-点 双密度
24
203.2 dpi
203.2 dpi
(nL+ nH ´ 256) ´3

Dpi:每25.4毫米{1英寸}打印点数

[注意]
·如果 m的值超出了指定的范围,那么nL和之后的数据被当作常规数据处理。
· nL和 nH表示水平方向上位图中的点数。通过nL+ nH´ 256计算出点数。
· 如果位图数据输入超出了一行上能被打印的点数,那么超出的数据被忽略。
· d表示位图数据。设置相应的位为 1去打印某点,或设置为 0以不打印某点。
· 如果用 GS L 和  GSW 设置的打印范围的宽度比用ESC *命令 发送的数据所要求的宽度小时,则对有问题的行执行下列操作(但是打印不能超出最大可打印范围):

① 打印区域的宽度向右扩展以去适应数据量。
② 如果步骤①不能为数据提供足够的宽度,那么左边缘就被减少以去适应数据。对于在单密度模式(m= 0, 32)中的数据的每一位,打印机打印两个点:对于在双密度模式(m= 1, 33)中的数据的每一位,打印机打印一个点。在计算一行中能打印的数据量时,这些必须要考虑。

· 在打印一个位图之后,打印机返回常规数据处理模式。
· 这个命令不被打印模式(粗体、重叠、下划线、字符大小、或反白打印)影响, 除非是颠倒打印模式。
· 下图描述了图象数据与被打印的点之间的关系。

8-点位图被选定时


三、思路

因为所做的是打印图片(或者是二维码) ,先发送一个请求,从网络下载图片或者是二维码,得到这张图片过后,进行压缩到你想要的大小,在对压缩后的图片进行二值化,即黑白化,但是图片本身会有个α的值(即透明度)的问题,如果不进行处理的话,即使是黑白化的图片,得到图片的像素点也不是很精确。对于去透明度处理过后,在对这张图的每个最标点去像素值,即xxx  X  xxx大的图片,会有xxx X xxx个像素点。求出每个像素点的r、g、b的值,通过换算公式进行换算,得到一个像素值(0-255之间)。
如果是0-128是黑色,129-255是白色(非黑即白化),这样每个点的像素值就可以确定了。

因为我的热敏打印机是24*24的,所以会是24个像素点为一组,假设我把图片压缩为360*360像素的大小,就会有15组(纵向的15行,横坐标还是360)。一组的有24*360的像素点,因为8位是一个字节,这样24个像素点可以分为3组,每8位组成一个字节,每个像素点不是0就是1(之前已经非黑即白过),这样会得到一个byte数组,如:byte[] b1 = {1, 0, 0, 1, 0, 0, 0, 1}; 在将这样的数组换成十进制的数值int v1;这样就会得到3*15*360个的int 值,在将这些int的值和打印机的打印头命令拼接起来,组成一个byte[] 数组,就可以打印了。

四、注意

1.热敏打印机是一行一行的打印,所以每一行又得加上打印的头命令,我的打印机头命令是5个,所以byte[]数组的长度会是3*15*360+5*15

2.大家看好自己打印机的打印密度,比如我的是24*24的,所以我剪裁图片的大小会是24的倍数,360*360.大家最好也剪裁成相应的倍数,这样计算会方便点,不然的话,要对空白区域进行白色补缺。

贴代码
  1. package com.woyou.util;

  2. import android.graphics.Bitmap;
  3. import android.graphics.Canvas;
  4. import android.graphics.Matrix;
  5. import android.graphics.Rect;
  6. import android.util.Log;

  7. /**
  8. * 将图片转化为二进制
  9. * @author nsz
  10. * 2015年1月30日
  11. */
  12. public class PicFromPrintUtils {
  13.         
  14.         
  15.         public void init(){
  16. //                Gray = 0.29900 * R + 0.58700 * G + 0.11400 * B
  17.         }
  18.         
  19.         /*************************************************************************
  20.          * 我们的热敏打印机是RP-POS80S或RP-POS80P或RP-POS80CS或RP-POS80CP打印机
  21.          * 360*360的图片,8个字节(8个像素点)是一个二进制,将二进制转化为十进制数值
  22.          * y轴:24个像素点为一组,即360就是15组(0-14)
  23.          * x轴:360个像素点(0-359)
  24.          * 里面的每一组(24*360),每8个像素点为一个二进制,(每组有3个,3*8=24)
  25.          **************************************************************************/
  26.         /**
  27.          * 把一张Bitmap图片转化为打印机可以打印的bit(将图片压缩为360*360)
  28.          * 效率很高(相对于下面)
  29.          * @param bit
  30.          * @return
  31.          */
  32.         public static byte[] draw2PxPoint(Bitmap bit) {    
  33.                 byte[] data = new byte[16290];
  34.                 int k = 0;
  35.                 for (int j = 0; j < 15; j++) {
  36.                         data[k++] = 0x1B;
  37.                         data[k++] = 0x2A;
  38.                         data[k++] = 33; // m=33时,选择24点双密度打印,分辨率达到200DPI。
  39.                         data[k++] = 0x68;
  40.                         data[k++] = 0x01;
  41.                         for (int i = 0; i < 360; i++) {
  42.                                 for (int m = 0; m < 3; m++) {
  43.                                         for (int n = 0; n < 8; n++) {
  44.                                                 byte b = px2Byte(i, j * 24 + m * 8 + n, bit);
  45.                                                 data[k] += data[k] + b;
  46.                                         }
  47.                                         k++;
  48.                                 }
  49.                         }
  50.                         data[k++] = 10;
  51.                 }
  52.                 return data;
  53.         }
  54.         
  55.         /**
  56.          * 把一张Bitmap图片转化为打印机可以打印的bit
  57.          * @param bit
  58.          * @return
  59.          */
  60.         public static byte[] pic2PxPoint(Bitmap bit){
  61.                 long start = System.currentTimeMillis();
  62.                 byte[] data = new byte[16290];
  63.                 int k = 0;
  64.                 for (int i = 0; i < 15; i++) {
  65.                         data[k++] = 0x1B;
  66.                         data[k++] = 0x2A;
  67.                         data[k++] = 33; // m=33时,选择24点双密度打印,分辨率达到200DPI。
  68.                         data[k++] = 0x68;
  69.                         data[k++] = 0x01;
  70.                         for (int x = 0; x < 360; x++) {
  71.                                 for (int m = 0; m < 3; m++) {
  72.                                         byte[]  by = new byte[8];
  73.                                         for (int n = 0; n < 8; n++) {
  74.                                                 byte b = px2Byte(x, i * 24 + m * 8 +7-n, bit);
  75.                                                 by[n] = b;
  76.                                         }
  77.                                         data[k] = (byte) changePointPx1(by);
  78.                                         k++;
  79.                                 }
  80.                         }
  81.                         data[k++] = 10;
  82.                 }
  83.                 long end = System.currentTimeMillis();
  84.                 long str = end - start;
  85.                 Log.i("TAG", "str:" + str);
  86.                 return data;
  87.         }
  88.         
  89.         /**
  90.          * 图片二值化,黑色是1,白色是0
  91.          * @param x  横坐标
  92.          * @param y         纵坐标                        
  93.          * @param bit 位图
  94.          * @return
  95.          */
  96.         public static byte px2Byte(int x, int y, Bitmap bit) {
  97.                 byte b;
  98.                 int pixel = bit.getPixel(x, y);
  99.                 int red = (pixel & 0x00ff0000) >> 16; // 取高两位
  100.                 int green = (pixel & 0x0000ff00) >> 8; // 取中两位
  101.                 int blue = pixel & 0x000000ff; // 取低两位
  102.                 int gray = RGB2Gray(red, green, blue);
  103.                 if ( gray < 128 ){
  104.                         b = 1;
  105.                 } else {
  106.                         b = 0;
  107.                 }
  108.                 return b;
  109.         }
  110.         
  111.         /**
  112.          * 图片灰度的转化
  113.          * @param r  
  114.          * @param g
  115.          * @param b
  116.          * @return
  117.          */
  118.         private static int RGB2Gray(int r, int g, int b){
  119.                 int gray = (int) (0.29900 * r + 0.58700 * g + 0.11400 * b);  //灰度转化公式
  120.                 return  gray;
  121.         }
  122.         
  123.         /**
  124.          * 对图片进行压缩(去除透明度)
  125.          * @param bitmapOrg
  126.          */
  127.         public static Bitmap compressPic(Bitmap bitmapOrg) {
  128.                 // 获取这个图片的宽和高
  129.                 int width = bitmapOrg.getWidth();
  130.                 int height = bitmapOrg.getHeight();
  131.                 // 定义预转换成的图片的宽度和高度
  132.                 int newWidth = 360;
  133.                 int newHeight = 360;
  134.                 Bitmap targetBmp = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);  
  135.                 Canvas targetCanvas = new Canvas(targetBmp);
  136.                 targetCanvas.drawColor(0xffffffff);
  137.                 targetCanvas.drawBitmap(bitmapOrg, new Rect(0, 0, width, height), new Rect(0, 0, newWidth, newHeight), null);
  138.                 return targetBmp;
  139.         }
  140.         
  141.         
  142.         /**
  143.          * 对图片进行压缩(不去除透明度)
  144.          * @param bitmapOrg
  145.          */
  146.         public static Bitmap compressBitmap(Bitmap bitmapOrg) {
  147.                 // 加载需要操作的图片,这里是一张图片
  148. //                Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.alipay);
  149.                 // 获取这个图片的宽和高
  150.                 int width = bitmapOrg.getWidth();
  151.                 int height = bitmapOrg.getHeight();
  152.                 // 定义预转换成的图片的宽度和高度
  153.                 int newWidth = 360;
  154.                 int newHeight = 360;
  155.                 // 计算缩放率,新尺寸除原始尺寸
  156.                 float scaleWidth = ((float) newWidth) / width;
  157.                 float scaleHeight = ((float) newHeight) / height;
  158.                 // 创建操作图片用的matrix对象
  159.                 Matrix matrix = new Matrix();
  160.                 // 缩放图片动作
  161.                 matrix.postScale(scaleWidth, scaleHeight);
  162.                 // 创建新的图片
  163.                 Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, width,height, matrix, true);
  164.                 // 将上面创建的Bitmap转换成Drawable对象,使得其可以使用在ImageView, ImageButton中
  165. //                BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
  166.                 return resizedBitmap;
  167.         }
  168.         
  169.         /**
  170.          * 将[1,0,0,1,0,0,0,1]这样的二进制转为化十进制的数值(效率更高)
  171.          * @param arry
  172.          * @return
  173.          */
  174.         public static int changePointPx1(byte[] arry){
  175.                 int v = 0;
  176.                 for (int j = 0; j <arry.length; j++) {
  177.                         if( arry[j] == 1) {
  178.                                 v = v | 1 << j;
  179.                         }
  180.                 }
  181.                 return v;
  182.         }
  183.         
  184.         /**
  185.          * 将[1,0,0,1,0,0,0,1]这样的二进制转为化十进制的数值
  186.          * @param arry
  187.          * @return
  188.          */
  189.         public byte changePointPx(byte[] arry){
  190.                 byte v = 0;
  191.                 for (int i = 0; i < 8; i++) {
  192.                         v += v + arry[i];
  193.                 }
  194.                 return v;
  195.         }
  196.         
  197.         /**
  198.          * 得到位图的某个点的像素值
  199.          * @param bitmap
  200.          * @return
  201.          */
  202.         public byte[] getPicPx(Bitmap bitmap){
  203.                 int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];// 保存所有的像素的数组,图片宽×高
  204.                 bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
  205.                 for (int i = 0; i < pixels.length; i++) {
  206.                         int clr = pixels[i];
  207.                         int red = (clr & 0x00ff0000) >> 16; // 取高两位
  208.                 int green = (clr & 0x0000ff00) >> 8; // 取中两位
  209.                                 int blue = clr & 0x000000ff; // 取低两位
  210.                                 System.out.println("r=" + red + ",g=" + green + ",b=" + blue);
  211.                 }
  212.                 return null;
  213.         }
  214.         
  215. }
复制代码

下面楼层继续...


   

  1. package com.woyou.util;

  2. import java.io.ByteArrayOutputStream;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. import java.security.InvalidParameterException;
  8. import java.text.DecimalFormat;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Date;
  11. import java.util.Locale;

  12. import android.content.Context;
  13. import android_serialport_api.SerialPort;

  14. /**
  15. * 打印机辅助

  16. * @author nsz        2015年1月30日
  17. */
  18. public class PrintUtil {
  19.         final static int BUFFER_SIZE = 4096;

  20.         /**
  21.          * 对一个byte[] 进行打印
  22.          * @param printText
  23.          * @return
  24.          * add by yidie
  25.          */
  26.         public static boolean printBytes(byte[] printText) {
  27.                 boolean returnValue = true;
  28.                 try {
  29.                         OutputStream mOutputStream = getSerialPort().getOutputStream();
  30.                         mOutputStream.write(printText);
  31.                 } catch (Exception ex) {
  32.                         returnValue = false;
  33.                 }
  34.                 return returnValue;
  35.         }

  36.         /**
  37.          * "\n" 就是换行
  38.          * @param paramString
  39.          * @return
  40.          * add by yidie
  41.          */
  42.         public static boolean printString(String paramString) {
  43.                 return printBytes(getGbk(paramString));
  44.         }

  45.         /***************************************************************************
  46.          * add by yidie 2012-01-10 功能:设置打印绝对位置 参数: int 在当前行,定位光标位置,取值范围0至576点 说明:
  47.          * 在字体常规大小下,每汉字24点,英文字符12点 如位于第n个汉字后,则position=24*n
  48.          * 如位于第n个半角字符后,则position=12*n
  49.          ****************************************************************************/

  50.         public static byte[] setCusorPosition(int position) {
  51.                 byte[] returnText = new byte[4]; // 当前行,设置绝对打印位置 ESC $ bL bH
  52.                 returnText[0] = 0x1B;
  53.                 returnText[1] = 0x24;
  54.                 returnText[2] = (byte) (position % 256);
  55.                 returnText[3] = (byte) (position / 256);
  56.                 return returnText;
  57.         }

  58.         /**
  59.          * 设置打印机的行高
  60.          * @param h
  61.          * @return
  62.          */
  63.         public static byte[] setLineHeight(byte h) {
  64.                 byte[] returnText = new byte[] { 0x1B, 0x33, h }; // 切纸; 1B 33 n
  65.                 return returnText;
  66.         }

  67.         public static byte[] setDefaultLineHeight() {
  68.                 byte[] returnText = new byte[] { 0x1B, 0x32 }; // 切纸; 1B 32
  69.                 return returnText;
  70.         }

  71.         public static byte[] InputStreamTOByte(InputStream in) throws IOException {

  72.                 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
  73.                 byte[] data = new byte[BUFFER_SIZE];
  74.                 int count = -1;
  75.                 while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
  76.                         outStream.write(data, 0, count);

  77.                 data = null;
  78.                 return outStream.toByteArray();
  79.         }
  80.         
  81.         /**
  82.          * 打印我有外卖的logo
  83.          * @param c
  84.          */
  85.         public static void printLogo(Context c) {
  86.                 PrintUtil.printBytes(PrintUtil.setLineHeight((byte) 0));
  87.                 InputStream is = c.getClass().getResourceAsStream("/assets/bill.bin");
  88.                 byte[] b;
  89.                 try {
  90.                         b = InputStreamTOByte(is);
  91.                         PrintUtil.printBytes(b);
  92.                         PrintUtil.printBytes(PrintUtil.setDefaultLineHeight());
  93.                 } catch (Exception e) {
  94.                         e.printStackTrace();
  95.                 }
  96.         }

  97.          public static byte[] getLogo(Context c) {
  98.                 InputStream is = c.getClass().getResourceAsStream("/assets/bill.bin");
  99.                 byte[] b;
  100.                 try {
  101.                         b = InputStreamTOByte(is);
  102.                         return b;
  103.                 } catch (Exception e) {
  104.                         e.printStackTrace();
  105.                 }
  106.                 return null;
  107.          }
  108.          
  109.          /**
  110.           * 得到店铺logo
  111.           * @param c
  112.           * @param bit
  113.           * @return
  114.           */
  115.         public static byte[] getLogo(Context c, byte[] bit) {
  116.                 InputStream is = c.getClass().getResourceAsStream("/assets/bill.bin");
  117.                 byte[] b = bit;
  118.                 try {
  119.                         b = InputStreamTOByte(is);
  120.                         return b;
  121.                 } catch (Exception e) {
  122.                         e.printStackTrace();
  123.                 }
  124.                 return null;
  125.         }
  126.         
  127.         public static byte[] getLogo(byte[] bs) {
  128.                 byte[] b;
  129.                 try {
  130.                         b = bs;
  131.                         return b;
  132.                 } catch (Exception e) {
  133.                         e.printStackTrace();
  134.                 }
  135.                 return null;
  136.         }        
  137.         
  138.         /**
  139.          * 支付打印(二维码)
  140.          * @param b
  141.          * @param money
  142.          * @return
  143.          * [url=home.php?mod=space&uid=2643633]@throws[/url] InvalidParameterException
  144.          * @throws SecurityException
  145.          * @throws IOException
  146.          */
  147.         public static boolean printAlipayTitle(byte[] b, String money) 
  148.                         throws InvalidParameterException, SecurityException, IOException {
  149.                 
  150.                 int iNum = 0;
  151.                 byte[] tempBuffer = new byte[1000];
  152.                 
  153.                 byte[]  oldText = setAlignCenter('2');
  154.                 System.arraycopy(oldText, 0,  tempBuffer,  iNum,  oldText.length);
  155.                 iNum += oldText.length;
  156.                 oldText = setWH('4'); 
  157.                 System.arraycopy(oldText, 0, tempBuffer,  iNum,  oldText.length);
  158.                 iNum += oldText.length;
  159.                 oldText = setBold(true);
  160.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  161.                 iNum += oldText.length;
  162.                 oldText = getGbk("支付凭证\n");
  163.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  164.                 iNum += oldText.length;
  165.                 
  166.                 oldText = getGbk("\n");
  167.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  168.                 iNum += oldText.length;
  169.                 
  170.                 oldText = setAlignCenter('2');
  171.                 System.arraycopy(oldText, 0,  tempBuffer,  iNum,  oldText.length);
  172.                 iNum += oldText.length;
  173.                 oldText = setWH('3'); 
  174.                 System.arraycopy(oldText, 0, tempBuffer,  iNum,  oldText.length);
  175.                 iNum += oldText.length;
  176.                 oldText = setBold(true);
  177.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  178.                 iNum += oldText.length;
  179.                 oldText = getGbk("您共消费了" + money + "元\n");
  180.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  181.                 iNum += oldText.length;
  182.                 
  183.                 oldText = getGbk("\n");
  184.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  185.                 iNum += oldText.length;
  186.                 
  187.                 oldText = setAlignCenter('2');
  188.                 System.arraycopy(oldText, 0,  tempBuffer,  iNum,  oldText.length);
  189.                 iNum += oldText.length;
  190.                 oldText = setWH('3'); 
  191.                 System.arraycopy(oldText, 0, tempBuffer,  iNum,  oldText.length);
  192.                 iNum += oldText.length;
  193.                 oldText = setBold(true);
  194.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  195.                 iNum += oldText.length;
  196.                 oldText = getGbk("请扫码支付\n\n");
  197.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  198.                 iNum += oldText.length;
  199.                 
  200.                 SerialPort mSerialPort = getSerialPort();
  201.                 OutputStream mOutputStream = mSerialPort.getOutputStream();
  202.                 try {
  203.                         mOutputStream.write(tempBuffer);
  204.                         printBytes(b);
  205.                         printString("\n\n\n");
  206.                         printBytes(CutPaper());
  207.                 } catch (IOException e) {
  208.                         e.printStackTrace();
  209.                         return false;
  210.                 }
  211.                 return true;
  212.         }

  213.         /***************************************************************************
  214.          * add by yidie 2012-01-10 功能:订单打印 参数: String 订单短号 OrderDetail 打印内容,包含
  215.          * GoodsInfo[] String 打印标题
  216.          ****************************************************************************/

  217.         public static boolean printOrder(Context c, byte[] b)
  218.                         throws InvalidParameterException, SecurityException, IOException {

  219.                 DecimalFormat dcmFmt = new DecimalFormat("0.00");
  220.                 int iNum = 0, i;

  221.                 byte[] tempBuffer = new byte[8000];
  222.                 String stTmp = "";

  223.                 byte[] oldText = setAlignCenter('2');
  224.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  225.                 iNum += oldText.length;

  226.                 oldText = getLogo(c, b);
  227.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  228.                 iNum += oldText.length;

  229.                 oldText = setWH('1');
  230.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  231.                 iNum += oldText.length;

  232.                 oldText = getGbk("\n");
  233.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  234.                 iNum += oldText.length;

  235.                 oldText = setAlignCenter('2');
  236.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  237.                 iNum += oldText.length;

  238.                 oldText = setWH('4');
  239.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  240.                 iNum += oldText.length;

  241.                 oldText = setBold(true);
  242.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  243.                 iNum += oldText.length;

  244.                 oldText = setWH('1');
  245.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  246.                 iNum += oldText.length;

  247.                 oldText = getGbk("\n");
  248.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  249.                 iNum += oldText.length;

  250.                 oldText = setAlignCenter('1');
  251.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  252.                 iNum += oldText.length;

  253.                 oldText = setCusorPosition(324);
  254.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  255.                 iNum += oldText.length;

  256.                 String strTime = new SimpleDateFormat("yyyy-MM-dd HH:mm",
  257.                                 Locale.SIMPLIFIED_CHINESE).format(new Date());
  258.                 oldText = getGbk(strTime + "打印\n");
  259.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  260.                 iNum += oldText.length;

  261.                 oldText = setBold(false);
  262.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  263.                 iNum += oldText.length;

  264.                 oldText = getGbk("----------------------------------------------\n");
  265.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  266.                 iNum += oldText.length;

  267.                 oldText = setWH('3');
  268.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  269.                 iNum += oldText.length;

  270.                 oldText = getGbk("   商品名称              单价    数量    金额\n");
  271.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  272.                 iNum += oldText.length;

  273.                 oldText = getGbk("----------------------------------------------\n");
  274.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  275.                 iNum += oldText.length;

  276.                 oldText = setWH('3');
  277.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  278.                 iNum += oldText.length;

  279.                 oldText = setAlignCenter('2');
  280.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  281.                 iNum += oldText.length;

  282.                 oldText = setWH('1');
  283.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  284.                 iNum += oldText.length;

  285.                 oldText = getGbk("\n感谢使用[我有外卖]订餐,24小时服务热线 4008519517\n\n\n");
  286.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  287.                 iNum += oldText.length;

  288.                 oldText = CutPaper();
  289.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  290.                 iNum += oldText.length;
  291.                 
  292.                 SerialPort mSerialPort = getSerialPort();
  293.                 OutputStream mOutputStream = mSerialPort.getOutputStream();
  294.                 try {
  295.                         mOutputStream.write(tempBuffer);
  296.                 } catch (IOException e) {
  297.                         e.printStackTrace();
  298.                         return false;
  299.                 }
  300.                 return true;
  301.         }

  302.         /***************************************************************************
  303.          * add by yidie 2012-01-12 功能:报表打印 参数: String 打印标题,如“月报表:2013-01”
  304.          * ReportUserSale 打印内容,包含 UserSaleInfo[]
  305.          ****************************************************************************/

  306.         public static boolean printReportUser() throws InvalidParameterException,
  307.                         SecurityException, IOException {

  308.                 int iNum = 0;
  309.                 String stTmp = "";

  310.                 byte[] tempBuffer = new byte[8000];
  311.                 SerialPort mSerialPort = getSerialPort();
  312.                 OutputStream mOutputStream = mSerialPort.getOutputStream();

  313.                 byte[] oldText = setAlignCenter('1');
  314.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  315.                 iNum += oldText.length;

  316.                 oldText = setWH('3');
  317.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  318.                 iNum += oldText.length;

  319.                 oldText = setCusorPosition(324);
  320.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  321.                 iNum += oldText.length;

  322.                 String strTime = new SimpleDateFormat("yyyy-MM-dd HH:mm",
  323.                                 Locale.SIMPLIFIED_CHINESE).format(new Date());
  324.                 oldText = getGbk(strTime + "打印\n");
  325.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  326.                 iNum += oldText.length;

  327.                 oldText = setWH('1');
  328.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  329.                 iNum += oldText.length;

  330.                 oldText = setAlignCenter('2');
  331.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  332.                 iNum += oldText.length;

  333.                 oldText = setWH('4');
  334.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  335.                 iNum += oldText.length;

  336.                 oldText = setBold(true);
  337.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  338.                 iNum += oldText.length;

  339.                 oldText = setWH('1');
  340.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  341.                 iNum += oldText.length;

  342.                 oldText = getGbk("\n\n");
  343.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  344.                 iNum += oldText.length;

  345.                 oldText = setAlignCenter('1');
  346.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  347.                 iNum += oldText.length;

  348.                 oldText = setBold(false);
  349.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  350.                 iNum += oldText.length;

  351.                 oldText = setWH('1');
  352.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  353.                 iNum += oldText.length;

  354.                 oldText = getGbk("     用户           售出数量 售出金额\n");
  355.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  356.                 iNum += oldText.length;

  357.                 oldText = getGbk("----------------------------------------------\n");
  358.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  359.                 iNum += oldText.length;

  360.                 oldText = CutPaper();
  361.                 System.arraycopy(oldText, 0, tempBuffer, iNum, oldText.length);
  362.                 iNum += oldText.length;
  363.                 try {
  364.                         mOutputStream.write(tempBuffer);
  365.                 } catch (IOException e) {
  366.                         e.printStackTrace();
  367.                         return false;
  368.                 }

  369.                 return true;
  370.         }

  371.         /***************************************************************************
  372.          * add by yidie 2012-01-12 功能:报表打印 参数: String 打印标题,如“月报表:2013-01” ReportSale
  373.          * 打印内容,包含 SaleInfo[]
  374.          ****************************************************************************/

  375.         private static SerialPort mSerialPort = null;

  376.         public static SerialPort getSerialPort() throws SecurityException,
  377.                         IOException, InvalidParameterException {
  378.                 if (mSerialPort == null) {
  379.                         String spFile = null;
  380.                         String model = MainBoardUtil.getModel(); // android.os.Build.MODEL.toLowerCase();
  381.                         if (model.contains(Constants.MAIN_BOARD_SMDKV210)) {
  382.                                 spFile = "/dev/s3c2410_serial0";
  383.                         } else if (model.contains(Constants.MAIN_BOARD_RK30)) {
  384.                                 spFile = "/dev/ttyS1";
  385.                         } else if (model.contains(Constants.MAIN_BOARD_C500)) {
  386.                                 spFile = "/dev/ttyS1";
  387.                         } else {
  388.                                 throw new IOException("unknow hardware!");
  389.                         }

  390.                         int baudrate = 115200;
  391.                         boolean flagCon = true;

  392.                         File myFile = new File(spFile);

  393.                         /* Open the serial port */
  394.                         mSerialPort = new SerialPort(myFile, baudrate, 0, flagCon);
  395.                 }
  396.                 return mSerialPort;
  397.         }

  398.         public static void closeSerialPort() {
  399.                 if (mSerialPort != null) {
  400.                         mSerialPort.close();
  401.                         mSerialPort = null;
  402.                 }
  403.         }

  404.         public static byte[] getGbk(String stText) {
  405.                 byte[] returnText = null;
  406.                 try {
  407.                         returnText = stText.getBytes("GBK"); // 必须放在try内才可以
  408.                 } catch (Exception ex) {
  409.                         ;
  410.                 }
  411.                 return returnText;
  412.         }

  413.         public static byte[] setWH(char dist) {
  414.                 byte[] returnText = new byte[3]; // GS ! 11H 倍宽倍高
  415.                 returnText[0] = 0x1D;
  416.                 returnText[1] = 0x21;

  417.                 switch (dist) // 1-无;2-倍宽;3-倍高; 4-倍宽倍高
  418.                 {
  419.                 case '2':
  420.                         returnText[2] = 0x10;
  421.                         break;
  422.                 case '3':
  423.                         returnText[2] = 0x01;
  424.                         break;
  425.                 case '4':
  426.                         returnText[2] = 0x11;
  427.                         break;
  428.                 default:
  429.                         returnText[2] = 0x00;
  430.                         break;
  431.                 }

  432.                 return returnText;
  433.         }

  434.         /**
  435.          * 打印的对齐方式
  436.          * @param dist
  437.          * @return
  438.          */
  439.         public static byte[] setAlignCenter(char dist) {
  440.                 byte[] returnText = new byte[3]; // 对齐 ESC a
  441.                 returnText[0] = 0x1B;
  442.                 returnText[1] = 0x61;

  443.                 switch (dist) // 1-左对齐;2-居中对齐;3-右对齐
  444.                 {
  445.                 case '2':
  446.                         returnText[2] = 0x01;
  447.                         break;
  448.                 case '3':
  449.                         returnText[2] = 0x02;
  450.                         break;
  451.                 default:
  452.                         returnText[2] = 0x00;
  453.                         break;
  454.                 }
  455.                 return returnText;
  456.         }

  457.         public static byte[] setBold(boolean dist) {
  458.                 byte[] returnText = new byte[3]; // 加粗 ESC E
  459.                 returnText[0] = 0x1B;
  460.                 returnText[1] = 0x45;

  461.                 if (dist) {
  462.                         returnText[2] = 0x01; // 表示加粗
  463.                 } else {
  464.                         returnText[2] = 0x00;
  465.                 }
  466.                 return returnText;
  467.         }

  468.         public static byte[] PrintBarcode(String stBarcode) {
  469.                 int iLength = stBarcode.length() + 4;
  470.                 byte[] returnText = new byte[iLength];

  471.                 returnText[0] = 0x1D;
  472.                 returnText[1] = 'k';
  473.                 returnText[2] = 0x45;
  474.                 returnText[3] = (byte) stBarcode.length(); // 条码长度;

  475.                 System.arraycopy(stBarcode.getBytes(), 0, returnText, 4,
  476.                                 stBarcode.getBytes().length);

  477.                 return returnText;
  478.         }

  479.         /**
  480.          * 切纸
  481.          * @return
  482.          */
  483.         public static byte[] CutPaper() {
  484.                 byte[] returnText = new byte[] { 0x1D, 0x56, 0x42, 0x00 }; // 切纸; GS V
  485.                                                                                                                                         // 66D 0D
  486.                 return returnText;
  487.         }
  488. }
复制代码
  1. package com.woyou.woyoupay;

  2. import java.io.IOException;
  3. import java.net.URL;
  4. import java.util.ArrayList;
  5. import java.util.List;

  6. import org.json.JSONException;
  7. import org.json.JSONObject;

  8. import android.app.Activity;
  9. import android.app.ProgressDialog;
  10. import android.content.Intent;
  11. import android.graphics.Bitmap;
  12. import android.graphics.BitmapFactory;
  13. import android.graphics.drawable.Drawable;
  14. import android.os.Bundle;
  15. import android.text.Html;
  16. import android.util.Log;
  17. import android.view.View;
  18. import android.view.View.OnClickListener;
  19. import android.view.Window;
  20. import android.widget.ImageView;
  21. import android.widget.TextView;

  22. import com.anjoyo.net.AsyncHttpClient;
  23. import com.anjoyo.net.JsonHttpResponseHandler;
  24. import com.anjoyo.net.RequestParams;
  25. import com.woyou.R;
  26. import com.woyou.bean.ScanCodeRes;
  27. import com.woyou.util.Constants;
  28. import com.woyou.util.PicFromPrintUtils;
  29. import com.woyou.util.PrintUtil;
  30. import com.woyou.util.ThreadPoolManager;

  31. public class Print2DCodeAct extends Activity implements OnClickListener {
  32.         private static final String TAG = "Print2DCodeAct";
  33.         TextView back, print, motifiscan;
  34.         TextView oId, money, price;
  35.         ImageView printImg;
  36.         ProgressDialog dialog;

  37.         @Override
  38.         protected void onCreate(Bundle savedInstanceState) {
  39.                 super.onCreate(savedInstanceState);
  40.                 requestWindowFeature(Window.FEATURE_NO_TITLE);
  41.                 setContentView(R.layout.activity_print2dcode);
  42.                 initView();
  43.         }

  44.         String extra;
  45.         private void initView() {
  46.                 Intent intent = getIntent();
  47.                 extra = intent.getStringExtra("money");
  48.                 back = (TextView) this.findViewById(R.id.back);
  49.                 oId = (TextView) this.findViewById(R.id.order_id);
  50.                 back.setOnClickListener(this);
  51.                 motifiscan = (TextView) this.findViewById(R.id.motifiscan);
  52.                 print = (TextView) this.findViewById(R.id.print_image);
  53.                 printImg = (ImageView) this.findViewById(R.id.print_two_image);
  54.                 money = (TextView) this.findViewById(R.id.money);
  55.                 print.setOnClickListener(this);
  56.                 motifiscan.setOnClickListener(this);
  57.                 money.setText(Html.fromHtml("¥<big>" + extra + "</big>"));
  58.                 
  59.                 //显示图片
  60. //                Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(), R.drawable.alipay);
  61. //                Bitmap bitmap = compressPic(bitmapOrg);
  62. //                image_alipy.setImageBitmap(bitmap);
  63.                 
  64.                 //请求数据
  65.                 getData();
  66.         }

  67.         private void showDialog() {
  68.                 if (dialog == null) {
  69.                         dialog = new ProgressDialog(this);
  70.                         dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
  71.                         dialog.setCancelable(true);
  72.                         dialog.setMessage("正在加载中,请稍候...");
  73.                 }
  74.                 dialog.show();
  75.         }
  76.         private void hideDialog() {
  77.                 runOnUiThread(new Runnable() {
  78.                         
  79.                         @Override
  80.                         public void run() {
  81.                                 if (dialog != null) {
  82.                                         dialog.dismiss();
  83.                                 }
  84.                         }
  85.                 });
  86.         }
  87.         
  88.         
  89.         
  90.         @Override
  91.         protected void onResume() {
  92.                 super.onResume();
  93.                 Constants.ACTIVITY_INSTANCE = Print2DCodeAct.this;
  94.         }

  95.         List<ScanCodeRes> list = new ArrayList<ScanCodeRes>();
  96.         Bitmap compressPic = null;
  97.         String big_pic_url;
  98.         String pic_url;
  99.         String small_pic_url;
  100.         private void getData() {
  101.                 float f = Float.parseFloat(extra) * 100;
  102.                 int inte = (int) f;
  103.                 long parseLong = Long.parseLong(String.valueOf(inte));
  104.                 
  105.                 String sign = Constants.md5("100512354" + "150039203" + Constants.KEY);
  106.                 String url = "http://api.coupon.dev.wosai.cn/Upay/alipayQrCodeOffline";
  107.                 AsyncHttpClient client = new AsyncHttpClient();
  108.                 RequestParams params = new RequestParams();
  109.                 params.put("store_own_order_id", "1234");
  110.                 params.put("subject", "喔噻体验商品");
  111.                 params.put("total_fee", parseLong+"");
  112.                 params.put("wosai_store_id", "100512354");
  113.                 params.put("wosai_app_id", "150039203");
  114.                 params.put("sign", sign);
  115.                 params.put("notify_url", "http://www.woyouwaimai.com/get");   //推送支付成功的通知
  116.                 Log.i(TAG, url + params);
  117.                 
  118.                 client.get(url, params, new JsonHttpResponseHandler() {
  119.                         @Override
  120.                         public void onStart() {
  121.                                 super.onStart();
  122.                                 showDialog();
  123.                         }
  124.                         @Override
  125.                         public void onSuccess(JSONObject response) {
  126.                                 super.onSuccess(response);
  127.                                 try {
  128.                                         String code = response.getString("code");
  129.                                         String msg = response.getString("msg");
  130.                                         Log.i(TAG, "code:" + code);
  131.                                         Log.i(TAG, "msg:" + msg);
  132.                                         if ("10000".equals(code)) {
  133.                                                 JSONObject data = response.getJSONObject("data");
  134.                                                 String order_sn = data.getString("order_sn");
  135.                                                 String wosai_store_id = data.getString("wosai_store_id");
  136.                                                 int status = data.getInt("status");
  137.                                                 String ctime = data.getString("ctime");
  138.                                                 JSONObject order_pay_detail = data.getJSONObject("order_pay_detail");
  139.                                                 String order_detail = data.getString("order_detail");
  140.                                                 String pay_way = data.getString("pay_way");
  141.                                                 long total_fee = data.getLong("total_fee");

  142.                                                 String is_success = order_pay_detail.getString("is_success");
  143.                                                 JSONObject responses = order_pay_detail.getJSONObject("response");
  144.                                                 String sign = order_pay_detail.getString("sign");
  145.                                                 String sign_type = order_pay_detail.getString("sign_type");

  146.                                                 JSONObject alipay = responses.getJSONObject("alipay");
  147.                                                 big_pic_url = alipay.getString("big_pic_url");
  148.                                                 String out_trade_no = alipay.getString("out_trade_no");
  149.                                                 pic_url = alipay.getString("pic_url");
  150.                                                 String qr_code = alipay.getString("qr_code");
  151.                                                 String result_code = alipay.getString("result_code");
  152.                                                 small_pic_url = alipay.getString("small_pic_url");
  153.                                                 String voucher_type = alipay.getString("voucher_type");
  154.                                                 Log.i(TAG, "big_pic_url:" + big_pic_url);
  155.                                                 Log.i(TAG, "pic_url:" + pic_url);
  156.                                                 Log.i(TAG, "small_pic_url:" + small_pic_url);
  157.                                                 
  158.                                                 ScanCodeRes res = new ScanCodeRes();
  159.                                                 res.setOrder_sn(order_sn);
  160.                                                 res.setWosai_store_id(wosai_store_id);
  161.                                                 res.setStatus(status);
  162.                                                 res.setCtime(ctime);
  163.                                                 res.setIs_success(is_success);
  164.                                                 res.setOrder_detail(order_detail);
  165.                                                 res.setTotal_fee(total_fee);
  166.                                                 res.setPay_way(pay_way);
  167.                                                 list.add(res);
  168.                                                 
  169.                                                 Constants.memoryCache.put(Constants.SCAN_CODE_RESULT, list);
  170.                                                 
  171.                                         }
  172.                                 } catch (JSONException e) {
  173.                                         e.printStackTrace();
  174.                                         hideDialog();
  175.                                 }
  176.                         }

  177.                         @Override
  178.                         public void onFinish() {
  179.                                 super.onFinish();
  180.                                 ThreadPoolManager.getInstance().executeTask(new Runnable() {
  181.                                         @Override
  182.                                         public void run() {
  183.                                                 try {
  184.                                                         Bitmap bitmap = BitmapFactory.decodeStream(new URL(pic_url).openStream());
  185.                                                         compressPic = PicFromPrintUtils.compressPic(bitmap);
  186.                                                 }catch (IOException e) {
  187.                                                         e.printStackTrace();
  188.                                                 }
  189.                                                 runOnUiThread(new Runnable() {
  190.                                                         
  191.                                                         @Override
  192.                                                         public void run() {
  193.                                                                 printImg.setImageBitmap(compressPic);
  194.                                                                 print2Code(compressPic);
  195.                                                                 hideDialog();
  196.                                                         }
  197.                                                 });
  198.                                                 
  199.                                         }
  200.                                 });
  201.                         }

  202.                 });
  203.         }
  204.         
  205.         //打印二维码
  206.         private void print2Code(Bitmap bitmap){
  207.                 final byte[] bs = PicFromPrintUtils.draw2PxPoint(bitmap);
  208.                 ThreadPoolManager.getInstance().executeTask(new Runnable() {
  209.                         @Override
  210.                         public void run() {
  211.                                 try {
  212.                                         PrintUtil.printAlipayTitle(bs, extra);
  213.                                 } catch (Exception e) {
  214.                                         e.printStackTrace();
  215.                                 }
  216.                         }
  217.                 });
  218.         }
  219.         
  220.         @Override
  221.         public void onClick(View v) {
  222.                 switch (v.getId()) {
  223.                 case R.id.print_image:
  224.                         if ( compressPic != null ){
  225.                                 print2Code(compressPic);
  226.                         }
  227.                         break;

  228.                 case R.id.back:
  229.                         finish();
  230.                         break;

  231.                 case R.id.motifiscan:
  232.                         Intent intent = new Intent(this, HomeAct.class);
  233.                         intent.putExtra("money", extra);
  234.                         startActivity(intent);
  235.                         break;
  236.                 }
  237.         }
  238.         
  239.         public Drawable loadImageFromNetwork(String urladdr) {
  240.                 Drawable drawable = null;
  241.                 try {
  242.                         drawable = Drawable.createFromStream(new URL(urladdr).openStream(),"image.jpg");
  243.                 } catch (IOException e) {
  244.                         Log.d("test", e.getMessage());
  245.                 }
  246.                 if (drawable == null) {
  247.                         Log.d("test", "null drawable");
  248.                 } else {
  249.                         Log.d("test", "not null drawable");
  250.                 }
  251.                 return drawable;
  252.         }
  253.         
  254.         // 计算图片的缩放值
  255.         public static int calculateInSampleSize(BitmapFactory.Options options,
  256.                         int reqWidth, int reqHeight) {
  257.                 final int height = options.outHeight;
  258.                 final int width = options.outWidth;
  259.                 int inSampleSize = 1;
  260.                 if (height > reqHeight || width > reqWidth) {
  261.                         final int heightRatio = Math.round((float) height
  262.                                         / (float) reqHeight);
  263.                         final int widthRatio = Math.round((float) width / (float) reqWidth);
  264.                         inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
  265.                 }
  266.                 return inSampleSize;
  267.         }

  268. }
复制代码


代码不是很全,只上了一些核心的代码,因为这是公司的项目,不适合把工程贴上来,忘大家见谅。中间会有一些简单的算法,是为提高效率用的,代码的整合力度也不是很好,大家将就点吧。



原文

http://www.eoeandroid.com/thread-564903-1-1.html?_dsign=50a25db8

相关文章
相关标签/搜索