Commit 836ee784 authored by pengguangpu's avatar pengguangpu

添加创捷打印驱动代码

parent 3506d520
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.miya.hardware"> package="com.miya.hardware">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application <application
android:name=".app.HardwareApplication" android:name=".app.HardwareApplication"
android:allowBackup="true" android:allowBackup="true"
......
...@@ -3,12 +3,106 @@ package com.miya.hardware; ...@@ -3,12 +3,106 @@ package com.miya.hardware;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class PrintActivity extends Activity { import com.miya.print.PrinterManager;
import com.miya.print.utils.CheckStatusUtils;
public class PrintActivity extends Activity implements View.OnClickListener {
Button btnInit;
Button btnRelease;
Button btnPrintText;
Button btnSetTextSize;
Button btnCut;
EditText etText;
TextView tvResult;
/**
* 文字大小或放大倍数
*/
int textSize;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_print); setContentView(R.layout.activity_print);
//findView
btnInit = findViewById(R.id.btnInit);
btnRelease = findViewById(R.id.btnRelease);
btnPrintText = findViewById(R.id.btnPrintText);
btnSetTextSize = findViewById(R.id.btnSetTextSize);
etText = findViewById(R.id.etText);
tvResult = findViewById(R.id.tvResult);
btnCut = findViewById(R.id.btnCut);
//set click listener
btnInit.setOnClickListener(this);
btnRelease.setOnClickListener(this);
btnPrintText.setOnClickListener(this);
btnSetTextSize.setOnClickListener(this);
btnCut.setOnClickListener(this);
findViewById(R.id.ivBack).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnInit:
//初始化打印硬件
boolean result = PrinterManager.getInstance().init(this);
if (result) {
tvResult.setText("找到了打印机,机器名称:" + PrinterManager.getInstance().getPrinter().getPrinterName());
} else {
tvResult.setText("没找到打印机");
}
break;
case R.id.btnRelease:
if (PrinterManager.getInstance().isConnected()) {
if (PrinterManager.getInstance().getPrinter().release() == true) {
tvResult.setText("销毁成功");
} else {
tvResult.setText("没初始化过");
}
}
break;
case R.id.btnPrintText:
String content = etText.getText().toString();
if (PrinterManager.getInstance().isConnected()) {
try {
int ret = PrinterManager.getInstance().getPrinter().printText(0, 0, content, true);
} catch (Exception ex) {
ex.printStackTrace();
tvResult.setText(ex.getMessage());
}
}
break;
case R.id.btnSetTextSize:
break;
case R.id.btnCut:
if (PrinterManager.getInstance().isConnected()) {
try {
PrinterManager.getInstance().getPrinter().cutPaper();
} catch (Exception ex) {
ex.printStackTrace();
tvResult.setText(ex.getMessage());
}
}
break;
case R.id.ivBack:
finish();
break;
}
} }
} }
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:orientation="vertical">
</android.support.constraint.ConstraintLayout> <android.support.v7.widget.ActionMenuView
\ No newline at end of file android:layout_width="match_parent"
android:layout_height="88dp"
android:background="@color/colorPrimary">
<ImageView
android:id="@+id/ivBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_media_previous" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:gravity="right"
android:text="打印开放组件"
android:textColor="#ffffff"
android:textSize="36sp" />
</android.support.v7.widget.ActionMenuView>
<TextView
android:id="@+id/tvResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="显示操作结果"
android:textSize="36sp" />
<TableLayout
android:id="@+id/layoutOp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:padding="16dp">
<TableRow>
<Button
android:id="@+id/btnInit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="初始化" />
<Button
android:id="@+id/btnRelease"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="销毁资源" />
</TableRow>
<TableRow>
<EditText
android:id="@+id/etText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/btnPrintText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打印默认字符" />
</TableRow>
<TableRow>
<Button
android:id="@+id/btnSetTextSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="设置文字大小" />
</TableRow>
<TableRow>
<Button
android:id="@+id/btnCut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="切纸" />
</TableRow>
</TableLayout>
</LinearLayout>
\ No newline at end of file
<resources> <resources>
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. --> <!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
......
...@@ -32,6 +32,9 @@ dependencies { ...@@ -32,6 +32,9 @@ dependencies {
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//一些工具类集合,从主工程拷贝过来的
implementation 'com.blankj:utilcode:1.16.0'
/** /**
* 创捷机器打印jar包 * 创捷机器打印jar包
*/ */
......
package com.miya.print; package com.miya.print;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
/** /**
* 打印基类 * 打印基类
...@@ -17,8 +18,14 @@ public class BasePrinter implements IPrinter { ...@@ -17,8 +18,14 @@ public class BasePrinter implements IPrinter {
*/ */
int status; int status;
/**
* 打印机器名称
*/
String name;
@Override @Override
public boolean init(Context context) { public boolean init(Context context) {
this.context = context;
return false; return false;
} }
...@@ -27,8 +34,69 @@ public class BasePrinter implements IPrinter { ...@@ -27,8 +34,69 @@ public class BasePrinter implements IPrinter {
return false; return false;
} }
@Override
public int printText(int align, int size, String content, boolean isFeed) {
return PrinterStatusEnum.CODE_SUCCESS.status;
}
@Override
public int printBarcode(int align, String content, boolean isFeed) {
return 0;
}
@Override
public int printQrcode(int align, String content, boolean isFeed) {
return 0;
}
@Override
public int printImage(int align, Bitmap bm, boolean isFeed) {
return 0;
}
@Override
public int cutPaper() {
return 0;
}
@Override
public int setAlign(int align) {
return 0;
}
@Override
public int feedPaper() {
return 0;
}
@Override
public int getPrinterStatus() {
return 0;
}
@Override
public int excuteCmd(String cmd) {
return 0;
}
@Override @Override
public int beginPrint() { public int beginPrint() {
return 0; return 0;
} }
@Override
public int endPrint() {
return 0;
}
@Override
public void setPrinterName(String name) {
this.name = name;
}
@Override
public String getPrinterName() {
return this.name;
}
} }
package com.miya.print; package com.miya.print;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import android.text.TextUtils;
import android.util.Log;
import com.miya.print.utils.CheckStatusUtils;
import com.miya.print.utils.D; import com.miya.print.utils.D;
import com.miya.print.utils.ImageUtils;
import com.printsdk.cmd.PrintCmd; import com.printsdk.cmd.PrintCmd;
import com.printsdk.usbsdk.UsbDriver; import com.printsdk.usbsdk.UsbDriver;
...@@ -26,6 +36,61 @@ public class ChuangjiePrinter extends BasePrinter { ...@@ -26,6 +36,61 @@ public class ChuangjiePrinter extends BasePrinter {
public UsbDevice mUsbDev; // 公共打印机 public UsbDevice mUsbDev; // 公共打印机
private static final String ACTION_USB_PERMISSION = "com.usb.sample.USB_PERMISSION"; private static final String ACTION_USB_PERMISSION = "com.usb.sample.USB_PERMISSION";
/**
* 字体大小,用于防止重复设置
*/
int textSize = -1;
@Override
public boolean init(Context context) {
this.context = context;
if (mUsbDriver == null) {
getUsbDriverService(context);
}
// USB线已经连接
getUsbDriverService();
return connet() == 0;
}
@Override
public int beginPrint() {
return super.beginPrint();
}
@Override
public int printText(int align, int size, String content, boolean isFeed) {
int ret;
if (textSize != size) {
ret = setSizeText(size, size);
}
ret = setAlignMode(align);
ret = printString(content);
if (isFeed) {
ret = LF();
}
return ret;
}
@Override
public int cutPaper() {
if (null != mUsbDriver && null != mUsbDev) {
int ret = mUsbDriver.write(PrintCmd.printFeedline(5));
ret = mUsbDriver.write(PrintCmd.cutPage(0), mUsbDev);
return ret;
}
return -1;
}
@Override
public boolean release() {
super.release();
if (null == mUsbDev) {
if (mUsbDriver.isConnected()) {
mUsbDriver.disconnet();
}
}
return true;
}
/** /**
* 0 打印机正常 * 0 打印机正常
...@@ -56,6 +121,285 @@ public class ChuangjiePrinter extends BasePrinter { ...@@ -56,6 +121,285 @@ public class ChuangjiePrinter extends BasePrinter {
return conState; return conState;
} }
public boolean isConnect() {
if (null != mUsbDev) {
return mUsbDriver.isConnected();
}
return false;
}
public String getErrMsgByConnectState(int connectState) {
switch (connectState) {
case 0:
return "打印机正常";
case 1:
return "打印机未连接或未上电";
case 2:
return "打印机和调用库不匹配";
case 3:
return "打印头打开";
case 4:
return "切刀未复位";
case 5:
return "打印头过热";
case 6:
return "黑标错误";
case 7:
return "纸尽";
case 8:
return "纸将尽";
}
return "";
}
public synchronized int disconnet() {
int conState = -1;
if (mUsbDriver.isConnected()) {
if (null != mUsbDev) {
mUsbDriver.disconnet(mUsbDev);
conState = getPrinterStatus(mUsbDev);
}
}
return conState;
}
public int getStatus() {
int conState = -1;
if (null != mUsbDev) {
conState = getPrinterStatus(mUsbDev);
}
return conState;
}
public void setCharset(int country, int CPnumber) {
if (null != mUsbDriver && null != mUsbDev) {
mUsbDriver.write(PrintCmd.setCharset(country, CPnumber), mUsbDev);
}
}
/**
* 0是居左边
*
* @param iAlignment
*/
public int setAlignMode(int iAlignment) {
if (null != mUsbDriver && null != mUsbDev) {
return mUsbDriver.write(PrintCmd.setAlignMode(iAlignment), mUsbDev);
}
return -1;
}
public int LF() {
if (null != mUsbDriver && null != mUsbDev) {
return mUsbDriver.write(PrintCmd.LF(), mUsbDev);
}
return -1;
}
public void setEnableUnderLine(int underline) {
if (null != mUsbDriver && null != mUsbDev) {
mUsbDriver.write(PrintCmd.setEnableUnderLine(underline), mUsbDev);
}
}
public void setLeftAndRightMargin(int iMargin) {
if (null != mUsbDriver && null != mUsbDev) {
mUsbDriver.write(PrintCmd.setLeftAndRightMargin(iMargin), mUsbDev);
}
}
public void setLeftMargin(int iMargin) {
if (null != mUsbDriver && null != mUsbDev) {
mUsbDriver.write(PrintCmd.setLeftMargin(iMargin), mUsbDev);
}
}
public void setLineSpace(int iLinespace) {
if (null != mUsbDriver && null != mUsbDev) {
mUsbDriver.write(PrintCmd.setLineSpace(iLinespace), mUsbDev);
}
}
/**
* 切纸
*
* @param iMode 0==>全切;1==>半切
*/
public void cutPage(int iMode) {
if (null != mUsbDriver && null != mUsbDev) {
mUsbDriver.write(PrintCmd.printFeedline(5));
mUsbDriver.write(PrintCmd.cutPage(iMode), mUsbDev);
}
}
public int printBarCode(String barcode) {
int printState = -1;
if (null != mUsbDriver && null != mUsbDev) {
printState = mUsbDriver.write(PrintCmd.printBarCode(2, 120, 0, 2, 10, barcode), mUsbDev);// 一维条码打印
}
return printState;
}
public int printBarCode(String barcode, int codeType) {
int printState = -1;
if (null != mUsbDriver && null != mUsbDev) {
printState = mUsbDriver.write(PrintCmd.printBarCode(2, 120, 0, 2, codeType, barcode), mUsbDev);// 一维条码打印
}
return printState;
}
public int printQrcode(String StrData, int iLmargin, int iMside, int iRound) {
int printState = -1;
if (null != mUsbDriver && null != mUsbDev) {
printState = mUsbDriver.write(PrintCmd.printQrcode(StrData, iLmargin, iMside, iRound), mUsbDev);
}
return printState;
}
public int printQrcodeBitmap(Bitmap data) {
int printState = -1;
if (null != mUsbDriver && null != mUsbDev) {
Bitmap bm = ImageUtils.getSinglePic(data);
int[] pixData = ImageUtils.getPixelsByBitmap(bm);
printState = mUsbDriver.write(PrintCmd.printQrcodeBitmap(pixData, data.getWidth(), data.getHeight()));
}
return printState;
}
/**
* 设置放大倍数
*
* @param width 取值0~8,取为0时代表默认大小
* @param height 取值0~8,取为0时代表默认大小
* @return
*/
public int setSizeText(int width, int height) {
int printState = -1;
if (null != mUsbDriver && null != mUsbDev) {
printState = mUsbDriver.write(PrintCmd.setSizeText(width, height), mUsbDev);
}
return printState;
}
public int printString(String data) {
int printState = -1;
if (null != mUsbDriver && null != mUsbDev) {
if (TextUtils.isEmpty(data)) {
data = "";
}
printState = mUsbDriver.write(PrintCmd.printString(data, 0), mUsbDev);// 一维条码打印
}
return printState;
}
public int printStringByBytes(byte[] data) {
int printState = -1;
if (null != mUsbDriver && null != mUsbDev) {
printState = mUsbDriver.write(data, mUsbDev);// 一维条码打印
}
return printState;
}
public void setEnableBold(int iBold) {
if (null != mUsbDriver && null != mUsbDev) {
mUsbDriver.write(PrintCmd.setEnableBold(iBold), mUsbDev);
}
}
/**
* 获取UsbDriverService服务
*
* @return
*/
private boolean getUsbDriverService() {
boolean blnRtn = false;
try {
if (!mUsbDriver.isConnected()) {
// USB线已经连接
for (UsbDevice device : mUsbManager.getDeviceList().values()) {
if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID)
|| (device.getProductId() == PID13 && device.getVendorId() == VENDORID)
|| (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) {
blnRtn = mUsbDriver.usbAttached(device);
if (blnRtn == false) {
break;
}
blnRtn = mUsbDriver.connect(device);
// 打开设备
if (blnRtn) {
//内置打印机
if (device.getProductId() == PID11) {
mUsbDev1 = device;
mUsbDev = mUsbDev1;
} else {//USB打印机
mUsbDev2 = device;
mUsbDev = mUsbDev2;
D.i(TAG, "USB连接成功");
break;
}
} else {
D.i(TAG, "USB连接失败");
break;
}
}
}
} else {
blnRtn = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return blnRtn;
}
public void initPrint(Context context) {
this.context = context;
if (mUsbDriver == null) {
getUsbDriverService(context);
}
// USB线已经连接
getUsbDriverService();
}
/**
* 初始化设备
*
* @param context
*/
private void getUsbDriverService(Context context) {
mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
mUsbDriver = new UsbDriver(mUsbManager, context);
PendingIntent permissionIntent1 = PendingIntent.getBroadcast(context, 0,
new Intent(ACTION_USB_PERMISSION), 0);
mUsbDriver.setPermissionIntent(permissionIntent1);
// Broadcast listen for new devices
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(mUsbReceiver, filter);
}
/** /**
* 0 打印机正常 * 0 打印机正常
* 1 打印机未连接或未上电 * 1 打印机未连接或未上电
...@@ -108,49 +452,104 @@ public class ChuangjiePrinter extends BasePrinter { ...@@ -108,49 +452,104 @@ public class ChuangjiePrinter extends BasePrinter {
} }
/** /**
* 获取UsbDriverService服务 * 0 打印机正常
* 1 打印机未连接或未上电
* 2 打印机和调用库不匹配
* 3 打印头打开
* 4 切刀未复位
* 5 打印头过热
* 6 黑标错误
* 7 纸尽
* 8 纸将尽
* *
* @param status
* @return * @return
*/ */
private boolean getUsbDriverService() { public String getPrinterStatus(int status) {
boolean blnRtn = false;
try { if (status == 0) {
if (!mUsbDriver.isConnected()) { return "正常";
// USB线已经连接 }
for (UsbDevice device : mUsbManager.getDeviceList().values()) { if (status == 1) {
if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID) return "打印机未连接或未上电";
|| (device.getProductId() == PID13 && device.getVendorId() == VENDORID) }
|| (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) { if (status == 2) {
blnRtn = mUsbDriver.usbAttached(device); return "打印机和调用库不匹配";
if (blnRtn == false) { }
break; if (status == 3) {
return "打印头打开";
}
if (status == 4) {
return "切刀未复位";
}
if (status == 5) {
return "打印头过热";
}
if (status == 6) {
return "黑标错误";
}
if (status == 7) {
return "纸尽";
}
if (status == 8) {
return "正常";
}
return "打印机未连接或未上电";
}
/*
* BroadcastReceiver when insert/remove the device USB plug into/from a USB port
* 创建一个广播接收器接收USB插拔信息:当插入USB插头插到一个USB端口,或从一个USB端口,移除装置的USB插头
*/
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID)
|| (device.getProductId() == PID13 && device.getVendorId() == VENDORID)
|| (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) {
if (mUsbDriver.usbAttached(intent)) {
if (device.getProductId() == PID11) {
mUsbDev1 = device;
} else {
mUsbDev2 = device;
} }
blnRtn = mUsbDriver.connect(device); }
// 打开设备 }
if (blnRtn) {
//内置打印机 } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
if (device.getProductId() == PID11) { UsbDevice device = (UsbDevice) intent
mUsbDev1 = device; .getParcelableExtra(UsbManager.EXTRA_DEVICE);
mUsbDev = mUsbDev1; if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID)
} else {//USB打印机 || (device.getProductId() == PID13 && device.getVendorId() == VENDORID)
mUsbDev2 = device; || (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) {
mUsbDev = mUsbDev2; mUsbDriver.disconnet(device);
D.i(TAG, "USB连接成功"); if (device.getProductId() == PID11)
break; mUsbDev1 = null;
else
mUsbDev2 = null;
}
} else if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID)
|| (device.getProductId() == PID13 && device.getVendorId() == VENDORID)
|| (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) {
if (mUsbDriver.connect(device)) {
if (device.getProductId() == PID11)
mUsbDev1 = device;
else
mUsbDev2 = device;
} }
} else {
D.e(TAG, "USB连接失败");
break;
} }
} else {
Log.d(TAG, "permission denied for device " + device);
} }
} }
} else {
blnRtn = true;
} }
} catch (Exception e) {
e.printStackTrace();
} }
return blnRtn; };
}
} }
package com.miya.print; package com.miya.print;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
/** /**
* 标准打印接口 * 标准打印接口
...@@ -10,78 +11,124 @@ import android.content.Context; ...@@ -10,78 +11,124 @@ import android.content.Context;
*/ */
public interface IPrinter { public interface IPrinter {
//================全局状态码定义start===============//
/** /**
* 操作成功 * 初始化驱动
*
* @param context 调用者上下文索引
* @return true==>初始化成功;false==>初始化失败
*/ */
int CODE_SUCCESS = 0; boolean init(Context context);
/** /**
* 操作失败 * 销毁资源
*
* @return true==>销毁成功;false==>销毁失败
*/ */
int CODE_FAILED = -1; boolean release();
/** /**
* 打印机未连接或未上电 * 打印文字
*
* @param align 对齐方式
* @param size 文字大小
* @param content 待打印内容
* @param isFeed 是否走纸,true==>走纸
* @return 状态码(参考状态码枚举)
*/ */
int CODE_NOT_CONNECTED = 1; int printText(int align, int size, String content, boolean isFeed);
/** /**
* 打印机和调用库不匹配 * 打印条码
*
* @param align 对齐方式
* @param content 条码内容
* @param isFeed 是否走纸,true==>走纸
* @return 状态码(参考状态码枚举)
*/ */
int CODE_NOT_MATCHED = 2; int printBarcode(int align, String content, boolean isFeed);
/** /**
* 打印头打开 * 打印二维码
*
* @param align 对齐方式
* @param content 条码内容
* @param isFeed 是否走纸,true==>走纸
* @return 状态码(参考状态码枚举)
*/ */
int CODE_PRINT_HEAD_OPENED = 3; int printQrcode(int align, String content, boolean isFeed);
/** /**
* 切刀未复位 * 打印图片
*
* @param align 对齐方式
* @param bm 图片
* @param isFeed 是否走纸,true==>走纸
* @return 状态码(参考状态码枚举)
*/ */
int CODE_KNIFE_ERROR = 4; int printImage(int align, Bitmap bm, boolean isFeed);
/** /**
* 打印头过热 * 切纸
*
* @return 状态码(参考状态码枚举)
*/ */
int CODE_PRINT_HEAD_HOT = 5; int cutPaper();
/** /**
* 黑标错误 * 设置对齐方式
*
* @param align 对齐方式,0:巨左;1:居中;2:居右
* @return 状态码(参考状态码枚举)
*/ */
int CODE_BLACK_ERROR = 6; int setAlign(int align);
/** /**
* 纸尽 * 走纸
*
* @return 状态码(参考状态码枚举)
*/ */
int CODE_NO_PAPER = 7; int feedPaper();
/** /**
* 纸将尽 * 获取打印机状态
*
* @return 状态码(参考状态码枚举)
*/ */
int CODE_FEW_PAPER = 8; int getPrinterStatus();
//================全局状态码定义end===============//
/** /**
* 初始化驱动 * 执行指令
* *
* @param context 调用者上下文索引 * @param cmd 指令内容
* @return true==>初始化成功;false==>初始化失败 * @return 状态码(参考状态码枚举)
*/ */
boolean init(Context context); int excuteCmd(String cmd);
/** /**
* 销毁资源 * 开始新一轮打印
* *
* @return * @return 状态码(参考状态码枚举)
*/ */
boolean release(); int beginPrint();
/** /**
* 开始新一轮打印 * 结束本轮打印
* *
* @return 状态码 * @return 状态码(参考状态码枚举)
*/ */
int beginPrint(); int endPrint();
/**
* 设置打印机器名称
*
* @param name 打印机器名称
*/
void setPrinterName(String name);
/**
* 获取打印机器名称
*
* @return 打印机器名称
*/
String getPrinterName();
} }
\ No newline at end of file
package com.miya.print;
import android.content.Context;
import com.miya.print.utils.D;
/**
* 打印机管理者
*/
public class PrinterManager {
final static String TAG = PrinterManager.class.getSimpleName();
/**
* 设备类型枚举,用于轮询过程中的反射
*/
enum Type {
//这里添加扩展的驱动
// TYPE_HISENSE("hisense", ChuangjiePrinter.class.getName()),
// TYPE_YINGTAI("yingtai", ChuangjiePrinter.class.getName()),
// TYPE_SUNMI("shangmi", ChuangjiePrinter.class.getName()),
TYPE_CHUANGJIE("chuangjie", ChuangjiePrinter.class.getName());
/**
* 设备类型名称
*/
String typeName;
/**
* 设备驱动类全类名
*/
String clsName;
Type(String typeName, String clsName) {
this.typeName = typeName;
this.clsName = clsName;
}
@Override
public String toString() {
return "Type{" +
"typeName='" + typeName + '\'' +
", clsName='" + clsName + '\'' +
'}';
}
}
public static PrinterManager instance;
private PrinterManager() {
}
public static PrinterManager getInstance() {
synchronized (PrinterManager.class) {
if (instance == null) {
instance = new PrinterManager();
}
return instance;
}
}
/**
* 打印机器
*/
IPrinter printer;
/**
* 轮询初始化
*
* @return 状态码
*/
public boolean init(Context context) {
for (Type type : Type.values()) {
if (printer != null) {
printer.release();
}
try {
Class printerCls = Class.forName(type.clsName);
printer = (IPrinter) printerCls.newInstance();
boolean result = printer.init(context);
if (result == true) {
printer.setPrinterName(type.typeName);
D.i(TAG, "初始化打印机成功,打印机器为:" + type.typeName);
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
//没有找到对应的打印机
if (printer != null) {
printer.release();
}
D.i(TAG, "没找到对应的打印机器,请检查");
return false;
}
/**
* 获取当前打印接口
*
* @return
*/
public IPrinter getPrinter() {
return printer;
}
/**
* 判断当前打印机是否已连接
*
* @return
*/
public boolean isConnected() {
return printer != null;
}
}
package com.miya.print;
/**
* 打印枚举类
*
* @author pupu
*/
public enum PrinterStatusEnum {
/**
* 操作成功
*/
CODE_SUCCESS(0, "操作成功"),
/**
* 操作失败
*/
CODE_FAILED(-1, "操作失败"),
/**
* 打印机未连接或未上电
*/
CODE_NOT_CONNECTED(1, "打印机未连接或未上电"),
/**
* 打印机和调用库不匹配
*/
CODE_NOT_MATCHED(2, "打印机和调用库不匹配"),
/**
* 打印头打开
*/
CODE_PRINT_HEAD_OPENED(3, "打印头打开"),
/**
* 切刀未复位
*/
CODE_KNIFE_ERROR(4, "切刀未复位"),
/**
* 打印头过热
*/
CODE_PRINT_HEAD_HOT(5, "打印头过热"),
/**
* 黑标错误
*/
CODE_BLACK_ERROR(6, "黑标错误"),
/**
* 纸尽
*/
CODE_NO_PAPER(7, "纸尽"),
/**
* 纸将尽
*/
CODE_FEW_PAPER(8, "纸将尽");
/**
* 状态码
*/
int status;
/**
* 描述
*/
String desc;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
PrinterStatusEnum(int status, String desc) {
this.status = status;
this.desc = desc;
}
/**
* 根据状态码查找对应的枚举
*
* @param status 状态码
* @return 找到了就返回对应的枚举,没找到就返回null
*/
public static PrinterStatusEnum find(int status) {
for (PrinterStatusEnum statusEnum : PrinterStatusEnum.values()) {
if (statusEnum.status == status) {
return statusEnum;
}
}
return null;
}
}
package com.miya.print.utils;
import com.miya.print.PrinterStatusEnum;
/**
* 检查操作结果工具类
*/
public class CheckStatusUtils {
public static void checkState(int ret) {
if (ret != 0) {
for (PrinterStatusEnum statusEnum : PrinterStatusEnum.values()) {
if (ret == statusEnum.getStatus()) {
throw new RuntimeException(statusEnum.getStatus() + ":" + statusEnum.getDesc());
}
}
}
}
}
package com.miya.print.utils;
import android.content.Context;
import android.os.Environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import static android.content.Context.MODE_PRIVATE;
/**
* Created by chen on 2016/8/23.
*/
public class FileUtils {
//文件存储根目录
public String getFileRoot(Context context) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File external = context.getExternalFilesDir(null);
if (external != null) {
return external.getAbsolutePath();
}
}
return context.getFilesDir().getAbsolutePath();
}
//向指定的文件中写入指定的数据
public void writeFileData(Context context, String filename, String content){
try {
FileOutputStream fos = context.openFileOutput(filename, MODE_PRIVATE);//获得FileOutputStream
//将要写入的字符串转换为byte数组
byte[] bytes = content.getBytes();
fos.write(bytes);//将byte数组写入文件
fos.close();//关闭文件输出流
} catch (Exception e) {
e.printStackTrace();
}
}
//打开指定文件,读取其数据,返回字符串对象
public String readFileData(Context context, String fileName){
String result="";
try{
FileInputStream fis = context.openFileInput(fileName);
//获取文件长度
int lenght = fis.available();
byte[] buffer = new byte[lenght];
fis.read(buffer);
//将byte数组转换成指定格式的字符串
result = new String(buffer, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
package com.miya.print.utils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
/**
* ImageUtils
* 图片处理功能,主要功能是进行黑白化
*
* @author cq
* @create by chen in 2016年8月19日11:43:59
* @modify,
* @modifytime
*/
public class ImageUtils {
/**
* 对图片进行压缩(去除透明度)
*
* @param
*/
private static int errorcode;
public static Bitmap compressPic(Bitmap bitmap, int newWidth, int newHeight) {
// 获取这个图片的宽和高
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// 指定调整后的宽度和高度
// int newWidth = 240;
// int newHeight = 240;
if (newWidth <= 0) {
newWidth = 240;
//setStatus(PrintErrorCode.IMAGE_WIDTH_ERROR);
}
if (newHeight <= 0) {
newHeight = 240;
//setStatus(PrintErrorCode.IMAGE_HEIGHT_ERROR);
}
Bitmap targetBmp = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
Canvas targetCanvas = new Canvas(targetBmp);
targetCanvas.drawColor(0xffffffff);
targetCanvas.drawBitmap(bitmap, new Rect(0, 0, width, height), new Rect(0, 0, newWidth, newHeight), null);
return targetBmp;
}
/**
* 灰度图片黑白化,黑色是1,白色是0
*
* @param x 横坐标
* @param y 纵坐标
* @param bit 位图
* @return
*/
public static byte px2Byte(int x, int y, Bitmap bit) {
if (x < bit.getWidth() && y < bit.getHeight()) {
byte b;
int pixel = bit.getPixel(x, y);
int red = (pixel & 0x00ff0000) >> 16; // 取高两位
int green = (pixel & 0x0000ff00) >> 8; // 取中两位
int blue = pixel & 0x000000ff; // 取低两位
int gray = RGB2Gray(red, green, blue);
if (gray < 128) {
b = 1;
} else {
b = 0;
}
return b;
}
return 0;
}
/**
* 图片灰度的转化
*/
private static int RGB2Gray(int r, int g, int b) {
int gray = (int) (0.29900 * r + 0.58700 * g + 0.11400 * b); //灰度转化公式
return gray;
}
/* *************************************************************************
* 假设一个240*240的图片,分辨率设为24, 共分10行打印
* 每一行,是一个 240*24 的点阵, 每一列有24个点,存储在3个byte里面。
* 每个byte存储8个像素点信息。因为只有黑白两色,所以对应为1的位是黑色,对应为0的位是白色
**************************************************************************/
/**
* 把一张Bitmap图片转化为打印机可以打印的字节流
*
* @param bmp
* @return
*/
public static byte[] draw2PxPoint(Bitmap bmp) {
//用来存储转换后的 bitmap 数据。为什么要再加1000,这是为了应对当图片高度无法
//整除24时的情况。比如bitmap 分辨率为 240 * 250,占用 7500 byte,5:5455,3,5447,4,5427
//但是实际上要存储11行数据,每一行需要 24 * 240 / 8 =720byte 的空间。再加上一些指令存储的开销,
//所以多申请 1000byte 的空间是稳妥的,不然运行时会抛出数组访问越界的异常。
int size = bmp.getWidth() * bmp.getHeight() / 8 + 1000;
byte[] data = new byte[size];
int k = 0;
//设置行距为0的指令
data[k++] = 0x1B;
data[k++] = 0x33;
data[k++] = 0x00;
// 逐行打印
for (int j = 0; j < bmp.getHeight() / 24f; j++) {
//打印图片的指令
data[k++] = 0x1B;
data[k++] = 0x2A;
data[k++] = 33;
data[k++] = (byte) (bmp.getWidth() % 256); //nL
data[k++] = (byte) (bmp.getWidth() / 256); //nH
//对于每一行,逐列打印
for (int i = 0; i < bmp.getWidth(); i++) {
//每一列24个像素点,分为3个字节存储
for (int m = 0; m < 3; m++) {
//每个字节表示8个像素点,0表示白色,1表示黑色
for (int n = 0; n < 8; n++) {
byte b = px2Byte(i, j * 24 + m * 8 + n, bmp);
data[k] += data[k] + b;
}
k++;
}
}
data[k++] = 10;//换行
}
// long a=System.currentTimeMillis();
byte[] data1 = new byte[k];
System.arraycopy(data, 0, data1, 0, k);
// long b=System.currentTimeMillis();
// System.out.println("结束字节:"+k+"---"+data.length+"耗时:"+(b-a));
return data1;
}
/**
* jpg png bmp 彩色图片转换Bitmap数据为int[]数组
* @param bm
* @return int[]
*/
public static int[] getPixelsByBitmap(Bitmap bm) {
int width, heigh;
width = bm.getWidth();
heigh = bm.getHeight();
int iDataLen = width * heigh;
int[] pixels = new int[iDataLen];
bm.getPixels(pixels, 0, width, 0, 0, width, heigh);
return pixels;
}
/**
* 获取单色位图
* @param inputBMP
* @return Bitmap
*/
public static Bitmap getSinglePic(Bitmap inputBMP) {
int[] pix = new int[inputBMP.getWidth() * inputBMP.getHeight()];
int[] colorTemp = new int[inputBMP.getWidth() * inputBMP.getHeight()];
inputBMP.getPixels(pix, 0, inputBMP.getWidth(), 0, 0,
inputBMP.getWidth(), inputBMP.getHeight());
Bitmap returnBMP = Bitmap.createBitmap(inputBMP.getWidth(),
inputBMP.getHeight(), Bitmap.Config.RGB_565);
int lightNumber = 127;// 曝光度,這個顔色是中間值,如果大於中間值,那就是黑色,否則白色,数值越小,曝光度越高
// for (int j = 0; j < colorTemp.length; j++) {
// // 将颜色数组中的RGB值取反,255减去当前颜色值就获得当前颜色的反色
// // 網上的,但是我要進行曝光處理,使他變成單色圖
// colorTemp[j] = Color.rgb(Color.red(pix[j]) > lightNumber ? 255 : 0,
// Color.green(pix[j]) > lightNumber ? 255 : 0,
// Color.blue(pix[j]) > lightNumber ? 255 : 0);
// }
for (int j = 0; j < colorTemp.length; j++) {
colorTemp[j] = Color.rgb(Color.red(pix[j]), Color.green(pix[j]),
Color.blue(pix[j]));
}
for (int i = 0; i < colorTemp.length; i++) {
// 這裏需要思考一下,上一步有可能得到:純紅,純黃,純藍,黑色,白色這樣5種顔色,前三種是應該變成白色還是黑色呢?
// 發現這是一個很複雜的問題,涉及到不同區域閒顔色的對比,如果是黑色包圍紅色,那紅色就應該是白色,反之變成黑色。。。
// 似乎衹能具體問題具體分析,這裏就先把黃色設成白色,藍色=白色,紅色=黑色
int r = Color.red(pix[i]);
int g = Color.green(pix[i]);
int b = Color.blue(pix[i]);
// 有兩種顔色以上的混合,那就是變成黑色但目前这种方法,对于黑白的曝光效果更出色,
// 原理是设置一个曝光值,然后三种颜色相加大于3倍的曝光值,才是黑色,否则白色
if (r + g + b > 3 * lightNumber) {
colorTemp[i] = Color.rgb(255, 255, 255);
} else {
colorTemp[i] = Color.rgb(0, 0, 0);
}
}
returnBMP.setPixels(colorTemp, 0, inputBMP.getWidth(), 0, 0,
inputBMP.getWidth(), inputBMP.getHeight());
return returnBMP;
}
public int getStatus() {
return errorcode;
}
private void setStatus(int errorcode) {
this.errorcode = errorcode;
}
}
package com.miya.print.utils;
import android.annotation.SuppressLint;
import android.text.TextUtils;
import com.blankj.utilcode.util.RegexUtils;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
/**
* Created by fengyu on 2018/1/26.
*/
public class Page58MmPrintUtils {
/**
* 打印纸一行最大的字节
*/
private static final int LINE_BYTE_SIZE = 32;
private static final int LEFT_LENGTH = 20;
private static final int RIGHT_LENGTH = 12;
/**
* 左侧汉字最多显示几个文字
*/
private static final int LEFT_TEXT_MAX_LENGTH = 8;
/**要是数字和字母最多显示18个*/
private static final int LEFT_TEXT_MAX_LENGTH_18 = 18;
/**
* 小票打印菜品的名称,上限调到8个字
*/
public static final int MEAL_NAME_MAX_LENGTH = 8;
private static StringBuilder outputStringBuilder = null;
public static StringBuilder getOutputStringBuilder() {
return outputStringBuilder;
}
public static void setOutputStream(StringBuilder stringBuilder) {
Page58MmPrintUtils.outputStringBuilder = stringBuilder;
}
/**
* 打印文字
*
* @param text 要打印的文字
*/
public static void printText(String text) {
outputStringBuilder.append(text);
}
public static byte[] getPrintByte() throws UnsupportedEncodingException {
return outputStringBuilder.toString().getBytes("gbk");
}
/**
* 设置打印格式
*
* @param command 格式指令
*/
public static void selectCommand(byte[] command) {
outputStringBuilder.append(command);
// try {
// outputStringBuilder.append(command);
// } catch (IOException e) {
// //Toast.makeText(this.context, "发送失败!", Toast.LENGTH_SHORT).show();
// e.printStackTrace();
// }
}
/**
* 复位打印机
*/
public static final byte[] RESET = {0x1b, 0x40};
/**
* 左对齐
*/
public static final byte[] ALIGN_LEFT = {0x1b, 0x61, 0x00};
/**
* 中间对齐
*/
public static final byte[] ALIGN_CENTER = {0x1b, 0x61, 0x01};
/**
* 右对齐
*/
public static final byte[] ALIGN_RIGHT = {0x1b, 0x61, 0x02};
/**
* 选择加粗模式
*/
public static final byte[] BOLD = {0x1b, 0x45, 0x01};
/**
* 取消加粗模式
*/
public static final byte[] BOLD_CANCEL = {0x1b, 0x45, 0x00};
/**
* 宽高加倍
*/
public static final byte[] DOUBLE_HEIGHT_WIDTH = {0x1d, 0x21, 0x11};
/**
* 宽加倍
*/
public static final byte[] DOUBLE_WIDTH = {0x1d, 0x21, 0x10};
/**
* 高加倍
*/
public static final byte[] DOUBLE_HEIGHT = {0x1d, 0x21, 0x01};
/**
* 字体不放大
*/
public static final byte[] NORMAL = {0x1d, 0x21, 0x00};
/**
* 设置默认行间距
*/
public static final byte[] LINE_SPACING_DEFAULT = {0x1b, 0x32};
/**
* 设置行间距
*/
// public static final byte[] LINE_SPACING = {0x1b, 0x32};//{0x1b, 0x33, 0x14}; // 20的行间距(0,255)
// final byte[][] byteCommands = {
// { 0x1b, 0x61, 0x00 }, // 左对齐
// { 0x1b, 0x61, 0x01 }, // 中间对齐
// { 0x1b, 0x61, 0x02 }, // 右对齐
// { 0x1b, 0x40 },// 复位打印机
// { 0x1b, 0x4d, 0x00 },// 标准ASCII字体
// { 0x1b, 0x4d, 0x01 },// 压缩ASCII字体
// { 0x1d, 0x21, 0x00 },// 字体不放大
// { 0x1d, 0x21, 0x11 },// 宽高加倍
// { 0x1b, 0x45, 0x00 },// 取消加粗模式
// { 0x1b, 0x45, 0x01 },// 选择加粗模式
// { 0x1b, 0x7b, 0x00 },// 取消倒置打印
// { 0x1b, 0x7b, 0x01 },// 选择倒置打印
// { 0x1d, 0x42, 0x00 },// 取消黑白反显
// { 0x1d, 0x42, 0x01 },// 选择黑白反显
// { 0x1b, 0x56, 0x00 },// 取消顺时针旋转90°
// { 0x1b, 0x56, 0x01 },// 选择顺时针旋转90°
// };
/**
* 打印两列
*
* @param leftText 左侧文字
* @param rightText 右侧文字
* @return
*/
@SuppressLint("NewApi")
public static String printTwoData(String leftText, String rightText) {
StringBuilder sb = new StringBuilder();
int leftTextLength = getBytesLength(leftText);
int rightTextLength = getBytesLength(rightText);
sb.append(leftText);
sb.append(" ");
// 计算两侧文字中间的空格
int marginBetweenMiddleAndRight = LINE_BYTE_SIZE - leftTextLength - rightTextLength;
for (int i = 0; i < marginBetweenMiddleAndRight; i++) {
sb.append(" ");
}
sb.append(rightText);
return sb.toString();
}
public static byte[] printDivideLine() {
StringBuilder sb = new StringBuilder();
String divide = "-";
int length = getBytesLength(divide);
for (int i = 0, j = LINE_BYTE_SIZE / length; i < j; i++) {
sb.append(divide);
}
return sb.toString().getBytes();
}
public static String printDivideLineString() {
StringBuilder sb = new StringBuilder();
String divide = "-";
int length = getBytesLength(divide);
for (int i = 0, j = LINE_BYTE_SIZE / length; i < j; i++) {
sb.append(divide);
}
return sb.toString();
}
/**
* 打印四列
*
* @param leftText 左侧文字
* @param secondText 第二个文字
* @param thirdText 第三个文字
* @param rightText 右侧文字
* @return
*/
@SuppressLint("NewApi")
public static String printFourData(String leftText, String secondText, String thirdText, String rightText) {
StringBuilder sb = new StringBuilder();
// 左边最多显示 LEFT_TEXT_MAX_LENGTH 个汉字 + 两个点
if (leftText.length() > LEFT_TEXT_MAX_LENGTH) {
leftText = leftText.substring(0, LEFT_TEXT_MAX_LENGTH) + "..";
}
int leftTextLength = getBytesLength(leftText);
int secondTextLength = getBytesLength(secondText);
int thirdTextLength = getBytesLength(thirdText);
int rightTextLength = getBytesLength(rightText);
sb.append(leftText);
// 计算文字间的空格长度
int marginBetweenLetters = LINE_BYTE_SIZE - leftTextLength - secondTextLength
- thirdTextLength - rightTextLength;
sb.append(" ");//8
sb.append(secondText);
for (int i = 0; i <= marginBetweenLetters - 11; i++) {
sb.append(" ");
}
sb.append(thirdText);
sb.append(" ");//3
sb.append(rightText);
return sb.toString();
}
/**
* 打印三列
*
* @param leftText 左侧文字
* @param middleText 中间文字
* @param rightText 右侧文字
* @return
*/
@SuppressLint("NewApi")
public static String printThreeData(String leftText, String middleText, String rightText) {
StringBuilder sb = new StringBuilder();
if(RegexUtils.isMatch("^[a-zA-Z_0-9]+$", leftText)){
if (leftText.length() > LEFT_TEXT_MAX_LENGTH_18) {
leftText = leftText.substring(0, LEFT_TEXT_MAX_LENGTH_18);
}
}else{
// 左边最多显示 LEFT_TEXT_MAX_LENGTH 个汉字 + 两个点
if (leftText.length() > LEFT_TEXT_MAX_LENGTH) {
leftText = leftText.substring(0, LEFT_TEXT_MAX_LENGTH) + "..";
}
}
int leftTextLength = getBytesLength(leftText);
int middleTextLength = getBytesLength(middleText);
int rightTextLength = getBytesLength(rightText);
sb.append(leftText);
// 计算左侧文字和中间文字的空格长度
int marginBetweenLeftAndMiddle = LEFT_LENGTH - leftTextLength - middleTextLength / 2;
for (int i = 0; i < marginBetweenLeftAndMiddle; i++) {
sb.append(" ");
}
sb.append(middleText);
// 计算右侧文字和中间文字的空格长度
int marginBetweenMiddleAndRight = RIGHT_LENGTH - middleTextLength / 2 - rightTextLength;
for (int i = 0; i < marginBetweenMiddleAndRight; i++) {
sb.append(" ");
}
// 打印的时候发现,最右边的文字总是偏右一个字符,所以需要删除一个空格
sb.delete(sb.length() - 1, sb.length()).append(rightText);
return sb.toString();
}
/**
* 获取数据长度
*
* @param msg
* @return
*/
@SuppressLint("NewApi")
private static int getBytesLength(String msg) {
return msg.getBytes(Charset.forName("GB2312")).length;
}
public static String printDivideSymbolString(String symbol) {
StringBuilder sb = new StringBuilder();
String divide = symbol;
int length = getBytesLength(divide);
for (int i = 0, j = LINE_BYTE_SIZE / length; i < j; i++) {
sb.append(divide);
}
return sb.toString();
}
/**
* 格式化菜品名称,最多显示MEAL_NAME_MAX_LENGTH个数
*
* @param name
* @return
*/
public static String formatMealName(String name) {
if (TextUtils.isEmpty(name)) {
return name;
}
if (name.length() > MEAL_NAME_MAX_LENGTH) {
return name.substring(0, 8) + "..";
}
return name;
}
/**
* 中间是文字 两边是======
* @param centerText
* @return
*/
@SuppressLint("NewApi")
public static String printCenterData(String centerText) {
StringBuilder sb = new StringBuilder();
int centerLength = getBytesLength(centerText);
int leftLength = (LINE_BYTE_SIZE - centerLength)/2;
int rightLength = LINE_BYTE_SIZE - leftLength-centerLength;
for (int i = 0; i < leftLength; i++) {
sb.append("=");
}
sb.append(centerText);
StringBuilder sa = new StringBuilder();
for (int i = 0; i < rightLength; i++) {
sa.append("=");
}
sb.append(sa.toString());
return sb.toString();
}
}
package com.miya.print.utils;
import android.annotation.SuppressLint;
import android.text.TextUtils;
import com.blankj.utilcode.util.RegexUtils;
import java.nio.charset.Charset;
/**
* Created by fengyu on 2018/2/23.
*/
public class Page88MmPrintUtils {
/**
* 打印纸一行最大的字节
*/
private static final int LINE_BYTE_SIZE = 46;
private static final int LINE_BIG_BYTE_SIZE = 35;
private static final int LEFT_LENGTH = 28;
private static final int RIGHT_LENGTH = 18;
/**
* 左侧汉字最多显示几个文字
*/
private static final int LEFT_TEXT_MAX_LENGTH = 10;
/**
* 要是数字和字母最多显示15个
*/
private static final int LEFT_TEXT_MAX_LENGTH_15 = 15;
/**
* 小票打印菜品的名称,上限调到8个字
*/
public static final int MEAL_NAME_MAX_LENGTH = 10;
/**
* 复位打印机
*/
public static final byte[] RESET = {0x1b, 0x40};
/**
* 左对齐
*/
public static final byte[] ALIGN_LEFT = {0x1b, 0x61, 0x00};
/**
* 中间对齐
*/
public static final byte[] ALIGN_CENTER = {0x1b, 0x61, 0x01};
/**
* 右对齐
*/
public static final byte[] ALIGN_RIGHT = {0x1b, 0x61, 0x02};
/**
* 选择加粗模式
*/
public static final byte[] BOLD = {0x1b, 0x45, 0x01};
/**
* 取消加粗模式
*/
public static final byte[] BOLD_CANCEL = {0x1b, 0x45, 0x00};
/**
* 宽高加倍
*/
public static final byte[] DOUBLE_HEIGHT_WIDTH = {0x1d, 0x21, 0x11};
/**
* 宽加倍
*/
public static final byte[] DOUBLE_WIDTH = {0x1d, 0x21, 0x10};
/**
* 高加倍
*/
public static final byte[] DOUBLE_HEIGHT = {0x1d, 0x21, 0x01};
/**
* 字体不放大
*/
public static final byte[] NORMAL = {0x1d, 0x21, 0x00};
/**
* 设置默认行间距
*/
public static final byte[] LINE_SPACING_DEFAULT = {0x1b, 0x32};
/**
* 设置行间距
*/
// public static final byte[] LINE_SPACING = {0x1b, 0x32};//{0x1b, 0x33, 0x14}; // 20的行间距(0,255)
// final byte[][] byteCommands = {
// { 0x1b, 0x61, 0x00 }, // 左对齐
// { 0x1b, 0x61, 0x01 }, // 中间对齐
// { 0x1b, 0x61, 0x02 }, // 右对齐
// { 0x1b, 0x40 },// 复位打印机
// { 0x1b, 0x4d, 0x00 },// 标准ASCII字体
// { 0x1b, 0x4d, 0x01 },// 压缩ASCII字体
// { 0x1d, 0x21, 0x00 },// 字体不放大
// { 0x1d, 0x21, 0x11 },// 宽高加倍
// { 0x1b, 0x45, 0x00 },// 取消加粗模式
// { 0x1b, 0x45, 0x01 },// 选择加粗模式
// { 0x1b, 0x7b, 0x00 },// 取消倒置打印
// { 0x1b, 0x7b, 0x01 },// 选择倒置打印
// { 0x1d, 0x42, 0x00 },// 取消黑白反显
// { 0x1d, 0x42, 0x01 },// 选择黑白反显
// { 0x1b, 0x56, 0x00 },// 取消顺时针旋转90°
// { 0x1b, 0x56, 0x01 },// 选择顺时针旋转90°
// };
/**
* 打印两列
*
* @param leftText 左侧文字
* @param rightText 右侧文字
* @return
*/
@SuppressLint("NewApi")
public static String printTwoData(String leftText, String rightText) {
StringBuilder sb = new StringBuilder();
int leftTextLength = getBytesLength(leftText);
int rightTextLength = getBytesLength(rightText);
sb.append(leftText);
// 计算两侧文字中间的空格
int marginBetweenMiddleAndRight = LINE_BYTE_SIZE - leftTextLength - rightTextLength;
for (int i = 0; i < marginBetweenMiddleAndRight; i++) {
sb.append(" ");
}
sb.append(rightText);
return sb.toString();
}
/**
* 打印居中带分隔符的文字
*
* @return
*/
@SuppressLint("NewApi")
public static String printOneCenterData(String text) {
StringBuilder sb = new StringBuilder();
int leftTextLength = getBytesLength(text);
// 计算两侧文字中间的空格
int marginBetweenMiddleAndRight = (LINE_BYTE_SIZE - leftTextLength) / 2;
for (int i = 0; i < marginBetweenMiddleAndRight; i++) {
sb.append(" ");
}
sb.append(text);
for (int i = 0; i < marginBetweenMiddleAndRight; i++) {
sb.append(" ");
}
return sb.toString();
}
/**
* 中间是文字 两边是======
*
* @param centerText
* @return
*/
@SuppressLint("NewApi")
public static String printCenterData(String centerText) {
StringBuilder sb = new StringBuilder();
int centerLength = getBytesLength(centerText);
int leftLength = (LINE_BYTE_SIZE - centerLength) / 2;
int rightLength = LINE_BYTE_SIZE - leftLength - centerLength;
for (int i = 0; i < leftLength; i++) {
sb.append("=");
}
sb.append(centerText);
StringBuilder sa = new StringBuilder();
for (int i = 0; i < rightLength; i++) {
sa.append("=");
}
sb.append(sa.toString());
return sb.toString();
}
/**
* 中间是文字
*
* @param centerText
* @return
*/
@SuppressLint("NewApi")
public static String printCenterData(String centerText, String divideStr) {
StringBuilder sb = new StringBuilder();
int centerLength = getBytesLength(centerText);
int leftLength = (LINE_BYTE_SIZE - centerLength) / 2;
int rightLength = LINE_BYTE_SIZE - leftLength - centerLength;
for (int i = 0; i < leftLength; i++) {
sb.append(divideStr);
}
sb.append(centerText);
StringBuilder sa = new StringBuilder();
for (int i = 0; i < rightLength; i++) {
sa.append(divideStr);
}
sb.append(sa.toString());
return sb.toString();
}
/**
* 打印两列
*
* @param leftText 左侧文字
* @param rightText 右侧文字
* @return
*/
@SuppressLint("NewApi")
public static String printTwoDataBigSize(String leftText, String rightText) {
StringBuilder sb = new StringBuilder();
int leftTextLength = getBytesLength(leftText);
int rightTextLength = getBytesLength(rightText);
sb.append(leftText);
// 计算两侧文字中间的空格
int marginBetweenMiddleAndRight = LINE_BIG_BYTE_SIZE - leftTextLength - rightTextLength;
for (int i = 0; i < marginBetweenMiddleAndRight; i++) {
sb.append(" ");
}
sb.append(rightText);
return sb.toString();
}
public static byte[] printDivideLine() {
StringBuilder sb = new StringBuilder();
String divide = "-";
int length = getBytesLength(divide);
for (int i = 0, j = LINE_BYTE_SIZE / length; i < j; i++) {
sb.append(divide);
}
return sb.toString().getBytes();
}
public static String printDivideLineString() {
StringBuilder sb = new StringBuilder();
String divide = "-";
int length = getBytesLength(divide);
for (int i = 0, j = LINE_BYTE_SIZE / length; i < j; i++) {
sb.append(divide);
}
return sb.toString();
}
public static String printDivideSymbolString(String symbol) {
StringBuilder sb = new StringBuilder();
String divide = symbol;
int length = getBytesLength(divide);
for (int i = 0, j = LINE_BYTE_SIZE / length; i < j; i++) {
sb.append(divide);
}
return sb.toString();
}
/**
* 打印三列
*
* @param leftText 左侧文字
* @param middleText 中间文字
* @param rightText 右侧文字
* @return
*/
@SuppressLint("NewApi")
public static String printThreeData(String leftText, String middleText, String rightText) {
StringBuilder sb = new StringBuilder();
// 左边最多显示 LEFT_TEXT_MAX_LENGTH 个汉字 + 两个点
if (RegexUtils.isMatch("^[a-zA-Z_0-9]+$", leftText)) {
if (leftText.length() > LEFT_TEXT_MAX_LENGTH_15) {
leftText = leftText.substring(0, LEFT_TEXT_MAX_LENGTH_15) + "..";
}
} else {
if (leftText.length() > LEFT_TEXT_MAX_LENGTH) {
leftText = leftText.substring(0, LEFT_TEXT_MAX_LENGTH) + "..";
}
}
int leftTextLength = getBytesLength(leftText);
int middleTextLength = getBytesLength(middleText);
int rightTextLength = getBytesLength(rightText);
sb.append(leftText);
// 计算左侧文字和中间文字的空格长度
int marginBetweenLeftAndMiddle = LEFT_LENGTH - leftTextLength - middleTextLength / 2;
for (int i = 0; i < marginBetweenLeftAndMiddle; i++) {
sb.append(" ");
}
sb.append(middleText);
// 计算右侧文字和中间文字的空格长度
int marginBetweenMiddleAndRight = RIGHT_LENGTH - middleTextLength / 2 - rightTextLength;
for (int i = 0; i < marginBetweenMiddleAndRight; i++) {
sb.append(" ");
}
// 打印的时候发现,最右边的文字总是偏右一个字符,所以需要删除一个空格
sb.delete(sb.length() - 1, sb.length()).append(rightText);
return sb.toString();
}
/**
* 打印四列
*
* @param leftText 左侧文字
* @param secondText 第二个文字
* @param thirdText 第三个文字
* @param rightText 右侧文字
* @return
*/
@SuppressLint("NewApi")
public static String printFourData(String leftText, String secondText, String thirdText, String rightText) {
StringBuilder sb = new StringBuilder();
// 左边最多显示 LEFT_TEXT_MAX_LENGTH 个汉字 + 两个点
if (RegexUtils.isMatch("^[a-zA-Z_0-9]+$", leftText)) {
if (leftText.length() > LEFT_TEXT_MAX_LENGTH_15) {
leftText = leftText.substring(0, LEFT_TEXT_MAX_LENGTH_15) + "..";
} else {
StringBuffer stringBuffer = new StringBuffer(leftText);
for (int i = 0; i < 17 - leftText.length(); i++) {
stringBuffer.append(" ");
}
leftText = stringBuffer.toString();
}
} else {
if (leftText.length() > LEFT_TEXT_MAX_LENGTH) {
leftText = leftText.substring(0, LEFT_TEXT_MAX_LENGTH) + "..";
}
}
int leftTextLength = getBytesLength(leftText);
int secondTextLength = getBytesLength(secondText);
int thirdTextLength = getBytesLength(thirdText);
int rightTextLength = getBytesLength(rightText);
sb.append(leftText);
// 计算文字间的空格长度
int marginBetweenLetters = LINE_BYTE_SIZE - leftTextLength - secondTextLength
- thirdTextLength - rightTextLength;
sb.append(" ");//8
sb.append(secondText);
for (int i = 0; i <= marginBetweenLetters - 11; i++) {
sb.append(" ");
}
sb.append(thirdText);
sb.append(" ");//3
sb.append(rightText);
return sb.toString();
}
/**
* 打印四列
*
* @param firstText 第一个文字
* @param secondText 第二个文字
* @param thirdText 第三个文字
* @param fourthText 第四个文字
* @param fifthText 第五个文字
* @return
*/
@SuppressLint("NewApi")
public static String printFiveData(String firstText, String secondText, String thirdText, String fourthText, String fifthText) {
StringBuilder sb = new StringBuilder();
// 左边最多显示 LEFT_TEXT_MAX_LENGTH 个汉字 + 两个点
if (firstText.length() > LEFT_TEXT_MAX_LENGTH) {
firstText = firstText.substring(0, LEFT_TEXT_MAX_LENGTH) + "..";
}
int firstTextLength = getBytesLength(firstText);
int secondTextLength = getBytesLength(secondText);
int thirdTextLength = getBytesLength(thirdText);
int fourthTextLength = getBytesLength(fourthText);
int fifthTextLength = getBytesLength(fifthText);
sb.append(firstText);
// 计算剩余的空格长度
int marginBetweenLetters = LINE_BYTE_SIZE - firstTextLength - secondTextLength
- thirdTextLength - fourthTextLength - fifthTextLength;
sb.append(" ");//8
sb.append(secondText);
for (int i = 0; i <= marginBetweenLetters - 14; i++) {
sb.append(" ");
}
sb.append(thirdText);
sb.append(" ");//3
sb.append(fourthText);
sb.append(" ");//3
sb.append(fifthText);
return sb.toString();
}
/**
* 获取数据长度
*
* @param msg
* @return
*/
@SuppressLint("NewApi")
private static int getBytesLength(String msg) {
return msg.getBytes(Charset.forName("GB2312")).length;
}
/**
* 格式化菜品名称,最多显示MEAL_NAME_MAX_LENGTH个数
*
* @param name
* @return
*/
public static String formatMealName(String name) {
if (TextUtils.isEmpty(name)) {
return name;
}
if (name.length() > MEAL_NAME_MAX_LENGTH) {
return name.substring(0, 8) + "..";
}
return name;
}
/**
* 打印居中文字
*
* @param str 待打印文字
* @return
*/
public static String printCenterText(String str) {
StringBuilder sb = new StringBuilder();
String divide = "-";
int length = getBytesLength(divide);
int strLen = getBytesLength(str);
for (int i = 0; i < (LINE_BYTE_SIZE / length) / 2 - strLen / 4 - 1; i++) {
sb.append(" ");
}
sb.append(str);
for (int i = 0; i < (LINE_BYTE_SIZE / length) / 2 - strLen / 4 - 1; i++) {
sb.append(" ");
}
return sb.toString();
}
/**
* 打印带分割线的居中字符
* 例:-------谢谢惠顾-------
*
* @param str 待打印
* @return
* @author pupu
*/
public static String printCenterTextWithDivideLine(String str) {
StringBuilder sb = new StringBuilder();
String divide = "-";
int length = getBytesLength(divide);
int strLen = getBytesLength(str);
for (int i = 0; i < (LINE_BYTE_SIZE / length) / 2 - strLen / 4 - 1; i++) {
sb.append("-");
}
sb.append(str);
for (int i = 0; i < (LINE_BYTE_SIZE / length) / 2 - strLen / 4 - 1; i++) {
sb.append("-");
}
return sb.toString();
}
/**
* 打印4列,4列文字都居中打印
*
* @param str1
* @param str2
* @param str3
* @param str4
* @return
* @author pupu
*/
public static String printFourDataWithCenterAlign(String str1, String str2, String str3, String str4) {
StringBuilder sb = new StringBuilder();
int MAX_WORD = LINE_BYTE_SIZE / 2 + 1;
//最左侧文字最多显示6个文字
if (str1.length() > MAX_WORD / 4) {
str1 = str1.substring(0, MAX_WORD / 4) + "..";
}
if (str2.length() > MAX_WORD / 4) {
str2 = str2.substring(0, MAX_WORD / 4) + "..";
}
if (str3.length() > MAX_WORD / 4) {
str3 = str3.substring(0, MAX_WORD / 4) + "..";
}
if (str4.length() > MAX_WORD / 4) {
str4 = str4.substring(0, MAX_WORD / 4) + "..";
}
int strLen1 = getBytesLength(str1) / 2;
int strLen2 = getBytesLength(str2) / 2;
int strLen3 = getBytesLength(str3) / 2;
int strLen4 = getBytesLength(str4) / 2;
//计算空格
//str1
for (int i = 0; i < (MAX_WORD / 4 - strLen1) / 2; i++) {
sb.append(" ");
}
sb.append(str1);
for (int i = 0; i < (MAX_WORD / 4 - strLen1) / 2; i++) {
sb.append(" ");
}
//str2
for (int i = 0; i < (MAX_WORD / 4 - strLen2) / 2; i++) {
sb.append(" ");
}
sb.append(str2);
for (int i = 0; i < (MAX_WORD / 4 - strLen2) / 2; i++) {
sb.append(" ");
}
//str3
for (int i = 0; i < (MAX_WORD / 4 - strLen3) / 2; i++) {
sb.append(" ");
}
sb.append(str3);
for (int i = 0; i < (MAX_WORD / 4 - strLen3) / 2; i++) {
sb.append(" ");
}
//str4
for (int i = 0; i < (MAX_WORD / 4 - strLen4) / 2; i++) {
sb.append(" ");
}
sb.append(str4);
for (int i = 0; i < (MAX_WORD / 4 - strLen4) / 2; i++) {
sb.append(" ");
}
return sb.toString();
}
}
package com.miya.print.utils;
import java.io.UnsupportedEncodingException;
/**
* Created by fengyu on 2018/1/28.
*/
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 print
// 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);
}
/**
* from pupu:打印条码(不带换行的打印)
*
* @param barcode
* @return
*/
public static String getBarcodeCmdWithNoLF(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());
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;
}
}
package com.miya.print.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Base64;
import android.util.Log;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Map;
/**
* @describe sharepreference 数据存储,包括对象
* @author cq
*
*/
public class SharePreferenceUtils {
private SharedPreferences mKV;
private Editor mEditor;
private static SharePreferenceUtils instance;
private Context context;
public String ERROR_INFO = null;
private static final String TAG = "SharePreferenceUtils";
/**
* 构造方法。
*
* @param context
* @param kvName
* 键值表名称。
* @param * 打开的模式。值为Context.MODE_APPEND, Context.MODE_PRIVATE,
* Context.WORLD_READABLE, Context.WORLD_WRITEABLE.
*/
public SharePreferenceUtils(Context context, String kvName) {
this.context = context;
mKV = context.getSharedPreferences(kvName, Context.MODE_PRIVATE);
mEditor = mKV.edit();
}
/**
* 获取保存着的boolean对象。
*
* @param key
* 键名
* @param defValue
* 当不存在时返回的默认值。
* @return 返回获取到的值,当不存在时返回默认值。
*/
public boolean getBoolean(String key, boolean defValue) {
return mKV.getBoolean(key, defValue);
}
/**
* 获取保存着的int对象。
*
* @param key
* 键名
* @param defValue
* 当不存在时返回的默认值。
* @return 返回获取到的值,当不存在时返回默认值。
*/
public int getInt(String key, int defValue) {
return mKV.getInt(key, defValue);
}
/**
* 获取保存着的long对象。
*
* @param key
* 键名
* @param defValue
* 当不存在时返回的默认值。
* @return 返回获取到的值,当不存在时返回默认值。
*/
public long getLong(String key, long defValue) {
return mKV.getLong(key, defValue);
}
/**
* 获取保存着的float对象。
*
* @param key
* 键名
* @param defValue
* 当不存在时返回的默认值。
* @return 返回获取到的值,当不存在时返回默认值。
*/
public float getFloat(String key, float defValue) {
return mKV.getFloat(key, defValue);
}
/**
* 获取保存着的String对象。
*
* @param key
* 键名
* @param defValue
* 当不存在时返回的默认值。
* @return 返回获取到的值,当不存在时返回默认值。
*/
public String getString(String key, String defValue) {
return mKV.getString(key, defValue);
}
/**
* 获取所有键值对。
*
* @return 获取到的所胡键值对。
*/
public Map<String, ?> getAll() {
return mKV.getAll();
}
/**
* 设置一个键值对,它将在{@linkplain #commit()}被调用时保存。<br/>
* 注意:当保存的value不是boolean, byte(会被转换成int保存),int, long, float,
* String等类型时将调用它的toString()方法进行值的保存。
*
* @param key
* 键名称。
* @param value
* 值。
* @return 引用的KV对象。
*/
public SharePreferenceUtils put(String key, Object value) {
if (value instanceof Boolean) {
mEditor.putBoolean(key, (Boolean) value);
} else if (value instanceof Integer || value instanceof Byte) {
mEditor.putInt(key, (Integer) value);
} else if (value instanceof Long) {
mEditor.putLong(key, (Long) value);
} else if (value instanceof Float) {
mEditor.putFloat(key, (Float) value);
} else if (value instanceof String) {
mEditor.putString(key, (String) value);
} else {
mEditor.putString(key, value.toString());
}
return this;
}
/**
* SharedPreferences保存对象-----
*
* @param
* @param key
* @param object
*/
@SuppressLint("NewApi")
public void setObjectValue(String key, Object object) {
String objectBase64 = "";
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
objectBase64 = Base64.encodeToString(baos.toByteArray(),
Base64.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
mEditor.putString(key, objectBase64);
mEditor.commit();
}
/**
* SharedPreferences取得对象
*
* @param
* @param key
* @return
*/
@SuppressLint("NewApi")
public Object getObjectValue(String key) {
Object object = null;
try {
String objectBase64 = mKV.getString(key, "");
byte[] base64Bytes = Base64.decode(objectBase64.getBytes(),
Base64.DEFAULT);
ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
object = ois.readObject();
} catch (Exception e) {// 发生异常情况下清空对应缓存
ERROR_INFO = e.toString();
Log.e(TAG, e.toString());
}
return object;
}
/**
* 移除键值对。
*
* @param key
* 要移除的键名称。
* @return 引用的KV对象。
*/
public SharePreferenceUtils remove(String key) {
mEditor.remove(key);
return this;
}
/**
* 清除所有键值对。
*
* @return 引用的KV对象。
*/
public SharePreferenceUtils clear() {
mEditor.clear();
return this;
}
/**
* 是否包含某个键。
*
* @param key
* 查询的键名称。
* @return 当且仅当包含该键时返回true, 否则返回false.
*/
public boolean contains(String key) {
return mKV.contains(key);
}
/**
* 返回是否提交成功。
*
* @return 当且仅当提交成功时返回true, 否则返回false.
*/
public boolean commit() {
return mEditor.commit();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment