Android小白进阶之路--项目需求3

 吧项目需求3:UVC协议摄像头扫描二维码,将扫码结果发送给后台。

今天经大神指点对于打印机打印小票这一块提供了一些方向,首先有几个问题要想1、是连接被扫的还是连接扫码的;2、然后怎么连接,蓝牙还是Wifi?;3、连接打印机的是什么系统,安卓还是Win?;这些都弄明白了你就知道怎样调用了,然后去找相关的api就完了,还有一点是打印这个东西应该找系统的api,例如Win怎样调用打印机?

APK是AndroidPackage的缩写,即Android安装包(apk)。APK是类似Symbian Sis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。

root权限,系统权限的一种,与SYSTEM权限可以理解成一个概念,但高于Administrator权限,root是Linux和unix系统中的超级管理员用户帐户,该帐户拥有整个系统至高无上的权力,所有对象他都可以操作,所以很多黑客在入侵系统的时候,都要把权限提升到root权限,用windows的方法理解也就是将自己的非法帐户添加到Administrators用户组。

UVC协议称为:USB video class 或USB video device class。是Microsoft与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标准,目前已成为USB org标准之一。

Android工具---Git,Git是免费的开源的分布式的版本控制系统,Git是一款分布式的源代码管理工具。


根据打印流程可以得出的是:本打印小票的打印机是可以主动扫描、也可以调出二维码被扫描两种方式并存的;连接方式是Wifi连接;连接打印机系统是Windows系统;小票打印就是向打印设备发送控制打印格式的指令集,而这些打印格式需要去查询对应打印机的API文档。有大神把常用的api进行了封装:1、文字对齐方式 2、打印字体大小 3、字体是否加粗4、打印二维码 5、打印条形码 6、切纸  7、打开钱箱   8、字符串转字节数组  9、字符拼接

/**

* 打印格式

* Created by john on 17-3-23.

*/

public class PrintFormatUtils {

// 对齐方式

public static final int ALIGN_LEFT = 0;     // 靠左

public static final int ALIGN_CENTER = 1;   // 居中

public static final int ALIGN_RIGHT = 2;    // 靠右

//字体大小

public static final int FONT_NORMAL = 0;    // 正常

public static final int FONT_MIDDLE = 1;    // 中等

public static final int FONT_BIG = 2;       // 大

//加粗模式

public static final int FONT_BOLD = 0;              // 字体加粗

public static final int FONT_BOLD_CANCEL = 1;       // 取消加粗

/**

* 打印二维码

* @param qrCode

* @return

*/

public static String getQrCodeCmd(String qrCode) {

byte[] data;

int store_len = qrCode.length() + 3;

byte store_pL = (byte) (store_len % 256);

byte store_pH = (byte) (store_len / 256);

// QR Code: Select the model

//              Hex     1D      28      6B      04      00      31      41      n1(x32)     n2(x00) - size of model

// set n1 [49 x31, model 1] [50 x32, model 2] [51 x33, micro qr code]

// https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=140

byte[] modelQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x04, (byte)0x00, (byte)0x31, (byte)0x41, (byte)0x32, (byte)0x00};

// QR Code: Set the size of module

// Hex      1D      28      6B      03      00      31      43      n

// n depends on the printer

// https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=141

byte[] sizeQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x43, (byte)0x08};

//          Hex     1D      28      6B      03      00      31      45      n

// Set n for error correction [48 x30 -> 7%] [49 x31-> 15%] [50 x32 -> 25%] [51 x33 -> 30%]

// https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=142

byte[] errorQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x45, (byte)0x31};

// QR Code: Store the data in the symbol storage area

// Hex      1D      28      6B      pL      pH      31      50      30      d1...dk

// https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=143

//                        1D          28          6B         pL          pH  cn(49->x31) fn(80->x50) m(48->x30) d1…dk

byte[] storeQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, store_pL, store_pH, (byte)0x31, (byte)0x50, (byte)0x30};

// QR Code: Print the symbol data in the symbol storage area

// Hex      1D      28      6B      03      00      31      51      m

// https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=144

byte[] printQR = {(byte)0x1d, (byte)0x28, (byte)0x6b, (byte)0x03, (byte)0x00, (byte)0x31, (byte)0x51, (byte)0x30};

data = byteMerger(modelQR, sizeQR);

data = byteMerger(data, errorQR);

data = byteMerger(data, storeQR);

data = byteMerger(data, qrCode.getBytes());

data = byteMerger(data, printQR);

return new String(data);

}

/**

* 打印条码

* @param barcode

* @return

*/

public static String getBarcodeCmd(String barcode) {

// 打印 Code-128 条码时需要使用字符集前缀

// "{A" 表示大写字母

// "{B" 表示所有字母,数字,符号

// "{C" 表示数字,可以表示 00 - 99 的范围

byte[] data;

String btEncode;

if (barcode.length() < 18) {

// 字符长度小于15的时候直接输出字符串

btEncode = "{B" + barcode;

} else {

// 否则做一点优化

int startPos = 0;

btEncode = "{B";

for (int i = 0; i < barcode.length(); i++) {

char curChar = barcode.charAt(i);

if (curChar < 48 || curChar > 57 || i == (barcode.length() - 1)) {

// 如果是非数字或者是最后一个字符

if (i - startPos >= 10) {

if (startPos == 0) {

btEncode = "";

}

btEncode += "{C";

boolean isFirst = true;

int numCode = 0;

for (int j = startPos; j < i; j++) {

if (isFirst) { // 处理第一位

numCode = (barcode.charAt(j) - 48) * 10;

isFirst = false;

} else { // 处理第二位

numCode += (barcode.charAt(j) - 48);

btEncode += (char) numCode;

isFirst = true;

}

}

btEncode += "{B";

if (!isFirst) {

startPos = i - 1;

} else {

startPos = i;

}

}

for (int k = startPos; k <= i; k++) {

btEncode += barcode.charAt(k);

}

startPos = i + 1;

}

}

}

// 设置 HRI 的位置,02 表示下方

byte[] hriPosition = {(byte) 0x1d, (byte) 0x48, (byte) 0x02};

// 最后一个参数表示宽度 取值范围 1-6 如果条码超长则无法打印

byte[] width = {(byte) 0x1d, (byte) 0x77, (byte) 0x02};

byte[] height = {(byte) 0x1d, (byte) 0x68, (byte) 0xfe};

// 最后两个参数 73 : CODE 128 || 编码的长度

byte[] barcodeType = {(byte) 0x1d, (byte) 0x6b, (byte) 73, (byte) btEncode.length()};

byte[] print = {(byte) 10, (byte) 0};

data = PrintFormatUtils.byteMerger(hriPosition, width);

data = PrintFormatUtils.byteMerger(data, height);

data = PrintFormatUtils.byteMerger(data, barcodeType);

data = PrintFormatUtils.byteMerger(data, btEncode.getBytes());

data = PrintFormatUtils.byteMerger(data, print);

return new String(data);

}

/**

* 切纸

* @return

*/

public static String getCutPaperCmd() {

// 走纸并切纸,最后一个参数控制走纸的长度

byte[] data = {(byte) 0x1d, (byte) 0x56, (byte) 0x42, (byte) 0x15};

return new String(data);

}

/**

* 对齐方式

* @param alignMode

* @return

*/

public static String getAlignCmd(int alignMode) {

byte[] data = {(byte) 0x1b, (byte) 0x61, (byte) 0x0};

if (alignMode == ALIGN_LEFT) {

data[2] = (byte) 0x00;

} else if (alignMode == ALIGN_CENTER) {

data[2] = (byte) 0x01;

} else if (alignMode == ALIGN_RIGHT) {

data[2] = (byte) 0x02;

}

return new String(data);

}

/**

* 字体大小

* @param fontSize

* @return

*/

public static String getFontSizeCmd(int fontSize) {

byte[] data = {(byte) 0x1d, (byte) 0x21, (byte) 0x0};

if (fontSize == FONT_NORMAL) {

data[2] = (byte) 0x00;

} else if (fontSize == FONT_MIDDLE) {

data[2] = (byte) 0x01;

} else if (fontSize == FONT_BIG) {

data[2] = (byte) 0x11;

}

return new String(data);

}

/**

* 加粗模式

* @param fontBold

* @return

*/

public static String getFontBoldCmd(int fontBold) {

byte[] data = {(byte) 0x1b, (byte) 0x45, (byte) 0x0};

if (fontBold == FONT_BOLD) {

data[2] = (byte) 0x01;

} else if (fontBold == FONT_BOLD_CANCEL) {

data[2] = (byte) 0x00;

}

return new String(data);

}

/**

* 打开钱箱

* @return

*/

public static String getOpenDrawerCmd() {

byte[] data = new byte[4];

data[0] = 0x10;

data[1] = 0x14;

data[2] = 0x00;

data[3] = 0x00;

return new String(data);

}

/**

* 字符串转字节数组

* @param str

* @return

*/

public static byte[] stringToBytes(String str) {

byte[] data = null;

try {

byte[] strBytes = str.getBytes("utf-8");

data = (new String(strBytes, "utf-8")).getBytes("gbk");

} catch (UnsupportedEncodingException exception) {

exception.printStackTrace();

}

return data;

}

/**

* 字节数组合并

* @param bytesA

* @param bytesB

* @return

*/

public static byte[] byteMerger(byte[] bytesA, byte[] bytesB) {

byte[] bytes = new byte[bytesA.length + bytesB.length];

System.arraycopy(bytesA, 0, bytes, 0, bytesA.length);

System.arraycopy(bytesB, 0, bytes, bytesA.length, bytesB.length);

return bytes;

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,295评论 18 399
  • 一、 1、请用Java写一个冒泡排序方法 【参考答案】 public static void Bubble(int...
    独云阅读 1,231评论 0 6
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,204评论 0 17
  • 岁月静好,现世安稳。 起初听到这句话的时候,内心是欢喜的。因为句子中的含义正是我很喜欢的生活方式。于是就想查一查是...
    清风浅微凉阅读 1,112评论 0 1