?吧項(xiàng)目需求3:UVC協(xié)議攝像頭掃描二維碼,將掃碼結(jié)果發(fā)送給后臺。
今天經(jīng)大神指點(diǎn)對于打印機(jī)打印小票這一塊提供了一些方向,首先有幾個(gè)問題要想1、是連接被掃的還是連接掃碼的;2、然后怎么連接,藍(lán)牙還是Wifi?;3、連接打印機(jī)的是什么系統(tǒng),安卓還是Win?;這些都弄明白了你就知道怎樣調(diào)用了,然后去找相關(guān)的api就完了,還有一點(diǎn)是打印這個(gè)東西應(yīng)該找系統(tǒng)的api,例如Win怎樣調(diào)用打印機(jī)?
APK是AndroidPackage的縮寫,即Android安裝包(apk)。APK是類似Symbian Sis或Sisx的文件格式。通過將APK文件直接傳到Android模擬器或Android手機(jī)中執(zhí)行即可安裝。
root權(quán)限,系統(tǒng)權(quán)限的一種,與SYSTEM權(quán)限可以理解成一個(gè)概念,但高于Administrator權(quán)限,root是Linux和unix系統(tǒng)中的超級管理員用戶帳戶,該帳戶擁有整個(gè)系統(tǒng)至高無上的權(quán)力,所有對象他都可以操作,所以很多黑客在入侵系統(tǒng)的時(shí)候,都要把權(quán)限提升到root權(quán)限,用windows的方法理解也就是將自己的非法帳戶添加到Administrators用戶組。
UVC協(xié)議稱為:USB video class 或USB video device class。是Microsoft與另外幾家設(shè)備廠商聯(lián)合推出的為USB視頻捕獲設(shè)備定義的協(xié)議標(biāo)準(zhǔn),目前已成為USB org標(biāo)準(zhǔn)之一。
Android工具---Git,Git是免費(fèi)的開源的分布式的版本控制系統(tǒng),Git是一款分布式的源代碼管理工具。

根據(jù)打印流程可以得出的是:本打印小票的打印機(jī)是可以主動掃描、也可以調(diào)出二維碼被掃描兩種方式并存的;連接方式是Wifi連接;連接打印機(jī)系統(tǒng)是Windows系統(tǒng);小票打印就是向打印設(shè)備發(fā)送控制打印格式的指令集,而這些打印格式需要去查詢對應(yīng)打印機(jī)的API文檔。有大神把常用的api進(jìn)行了封裝:1、文字對齊方式?2、打印字體大小?3、字體是否加粗4、打印二維碼?5、打印條形碼?6、切紙 ?7、打開錢箱 ??8、字符串轉(zhuǎn)字節(jié)數(shù)組 ?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 條碼時(shí)需要使用字符集前綴
// "{A" 表示大寫字母
// "{B" 表示所有字母,數(shù)字,符號
// "{C" 表示數(shù)字,可以表示 00 - 99 的范圍
byte[] data;
String btEncode;
if (barcode.length() < 18) {
// 字符長度小于15的時(shí)候直接輸出字符串
btEncode = "{B" + barcode;
} else {
// 否則做一點(diǎn)優(yōu)化
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)) {
// 如果是非數(shù)字或者是最后一個(gè)字符
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;
}
}
}
// 設(shè)置 HRI 的位置,02 表示下方
byte[] hriPosition = {(byte) 0x1d, (byte) 0x48, (byte) 0x02};
// 最后一個(gè)參數(shù)表示寬度 取值范圍 1-6 如果條碼超長則無法打印
byte[] width = {(byte) 0x1d, (byte) 0x77, (byte) 0x02};
byte[] height = {(byte) 0x1d, (byte) 0x68, (byte) 0xfe};
// 最后兩個(gè)參數(shù) 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() {
// 走紙并切紙,最后一個(gè)參數(shù)控制走紙的長度
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);
}
/**
* 字符串轉(zhuǎn)字節(jié)數(shù)組
* @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;
}
/**
* 字節(jié)數(shù)組合并
* @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;
}
}