Browse Source

PDA升级

yinds 1 year ago
parent
commit
655cd63ff1
24 changed files with 2767 additions and 180 deletions
  1. 5 0
      app/build.gradle
  2. 8 0
      app/src/main/AndroidManifest.xml
  3. 4 0
      app/src/main/java/com/hw/nativeapp/MApplication.java
  4. 1 1
      app/src/main/java/com/hw/nativeapp/config/Contents.java
  5. 1 1
      app/src/main/java/com/hw/nativeapp/httpnet/ApiService.java
  6. 1 1
      app/src/main/java/com/hw/nativeapp/httpnet/entity/UpdateVerAskBean.java
  7. 1 7
      app/src/main/java/com/hw/nativeapp/httpnet/entity/UpdateVerReqBean.java
  8. 4 1
      app/src/main/java/com/hw/nativeapp/ui/activity/MainActivity.java
  9. 174 0
      app/src/main/java/com/hw/nativeapp/ui/activity/SettingActivity.java
  10. 84 61
      app/src/main/java/com/hw/nativeapp/ui/dialogs/Dialog_Update.java
  11. 89 70
      app/src/main/java/com/hw/nativeapp/ui/dialogs/Dialog_UpdateProgress.java
  12. 130 0
      app/src/main/java/com/hw/nativeapp/update/UpdateHandler.java
  13. 42 35
      app/src/main/java/com/hw/nativeapp/utils/UpgradeUtils.java
  14. 748 0
      app/src/main/java/com/hw/nativeapp/utils/sunmi/BytesUtil.java
  15. 419 0
      app/src/main/java/com/hw/nativeapp/utils/sunmi/ESCUtil.java
  16. 791 0
      app/src/main/java/com/hw/nativeapp/utils/sunmi/SunmiPrintHelper.java
  17. 22 3
      app/src/main/res/layout/activity_main.xml
  18. 241 0
      app/src/main/res/layout/activity_setting.xml
  19. BIN
      app/src/main/res/mipmap-hdpi/img_setting.png
  20. BIN
      app/src/main/res/mipmap-hdpi/print.png
  21. BIN
      app/src/main/res/mipmap-hdpi/update.png
  22. BIN
      app/src/main/res/mipmap-hdpi/xiugaimima.png
  23. BIN
      app/src/main/res/mipmap-hdpi/zhuxiao.png
  24. 2 0
      config.gradle

+ 5 - 0
app/build.gradle

@@ -34,6 +34,7 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
             buildConfigField "String", "API_HOST", rootProject.ext.release.apiHost
             buildConfigField "String", "API_PATH", rootProject.ext.release.apiName
+            buildConfigField "String", "prjectName", rootProject.ext.release.prjectName
             buildConfigField "String", "FILEAPI_HOST", rootProject.ext.release.fileApiHost
             buildConfigField "String", "FILEAPI_PATH", rootProject.ext.release.fileApiName
         }
@@ -45,6 +46,7 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
             buildConfigField "String", "API_HOST", rootProject.ext.debug.apiHost
             buildConfigField "String", "API_PATH", rootProject.ext.debug.apiName
+            buildConfigField "String", "prjectName", rootProject.ext.release.prjectName
             buildConfigField "String", "FILEAPI_HOST", rootProject.ext.debug.fileApiHost
             buildConfigField "String", "FILEAPI_PATH", rootProject.ext.debug.fileApiName
         }
@@ -124,6 +126,9 @@ dependencies {
     implementation 'androidx.recyclerview:recyclerview:1.1.0'
     implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0'
     implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0'
+
+    implementation 'com.sunmi:sunmiui:1.1.27'
+    implementation 'com.sunmi:printerlibrary:1.0.18'
 }
 
 // SH1: 84:DD:2A:D6:4A:63:12:6B:06:9F:24:38:1F:57:32:8F:4D:5F:EE:78

+ 8 - 0
app/src/main/AndroidManifest.xml

@@ -54,6 +54,10 @@
     <uses-permission android:name="action:com.sunmi.scanner.ACTION_BAR_DEVICES_SETTING"/>
     <uses-permission android:name="android.permission.NFC" />
 
+    <!-- To support printerlibrary on Android R -->
+    <queries>
+        <package android:name="woyou.aidlservice.jiuiv5"/>
+    </queries>
     <application
         android:allowBackup="true"
         android:name="com.hw.nativeapp.MApplication"
@@ -109,6 +113,10 @@
             android:configChanges="orientation|screenSize"
             android:theme="@style/ThemeNoTitleBar" />
 
+        <activity android:name="com.hw.nativeapp.ui.activity.SettingActivity"
+            android:configChanges="orientation|screenSize"
+            android:theme="@style/ThemeNoTitleBar" />
+
         <provider
             android:name="androidx.core.content.FileProvider"
             android:authorities="com.hw.airportwine.provider"

+ 4 - 0
app/src/main/java/com/hw/nativeapp/MApplication.java

@@ -21,6 +21,7 @@ import com.hw.nativeapp.utils.ActivityUtils;
 import com.hw.nativeapp.utils.LogUtils;
 import com.hw.nativeapp.utils.RxUtil;
 import com.hw.nativeapp.utils.ToastUtils;
+import com.hw.nativeapp.utils.sunmi.SunmiPrintHelper;
 import com.liulishuo.filedownloader.FileDownloader;
 
 
@@ -90,6 +91,9 @@ public class MApplication extends Application {
         StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
         StrictMode.setVmPolicy(builder.build());
         builder.detectFileUriExposure();
+
+        SunmiPrintHelper.getInstance().initSunmiPrinterService(this);
+
     }
 
 

+ 1 - 1
app/src/main/java/com/hw/nativeapp/config/Contents.java

@@ -7,7 +7,7 @@ public class Contents {
     public static final String TOKEN_HEAD = "Authorization";
 
     //APPID  - 升级使用
-    public static final String APPID = "AIR_PORT_ID";
+    public static final String APPID = "pda_key";
 
     //临时存储key
     //登录验证码uuid

+ 1 - 1
app/src/main/java/com/hw/nativeapp/httpnet/ApiService.java

@@ -41,7 +41,7 @@ public interface ApiService {
     );
 
     //版本升级
-    @POST(COMMON + "/system/appversion/upgrade-by-appid")
+    @POST(COMMON + "/system/appVersion/check")
     Observable<ResponseData<UpdateVerAskBean>> version(
             @Body UpdateVerReqBean bean,
             @Query("t") Long currtime

+ 1 - 1
app/src/main/java/com/hw/nativeapp/httpnet/entity/UpdateVerAskBean.java

@@ -6,7 +6,7 @@ public class UpdateVerAskBean {
     public String  versionCode;
     public String  versionName;
     public String  note;
-    public String  pkgUrl;
+    public String  downloadUrl;
 
 
 }

+ 1 - 7
app/src/main/java/com/hw/nativeapp/httpnet/entity/UpdateVerReqBean.java

@@ -5,13 +5,7 @@ public class UpdateVerReqBean {
     /**
      * APPID
      */
-    public String appId;
-
-    /**
-     * 应用名称
-     */
-    public String name;
-
+    public String appKeyId;
 
     /**
      * 版本名称

+ 4 - 1
app/src/main/java/com/hw/nativeapp/ui/activity/MainActivity.java

@@ -52,7 +52,7 @@ public class MainActivity extends BaseActivity  {
         super.onDestroy();
     }
 
-    @OnClick({R.id.write_off_btn, R.id.history_btn})
+    @OnClick({R.id.write_off_btn, R.id.history_btn,R.id.img_setting})
     public void onClick(View v){
         switch (v.getId()){
             case R.id.write_off_btn:
@@ -63,6 +63,9 @@ public class MainActivity extends BaseActivity  {
 //                msg.setGravity(Gravity.CENTER, 0, 0);
                 msg.show();
                 break;
+            case R.id.img_setting:
+                ActivityUtils.launchActivity(this,SettingActivity.class);
+                break;
         }
     }
 }

+ 174 - 0
app/src/main/java/com/hw/nativeapp/ui/activity/SettingActivity.java

@@ -0,0 +1,174 @@
+package com.hw.nativeapp.ui.activity;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.blankj.utilcode.util.SPUtils;
+import com.blankj.utilcode.util.ToastUtils;
+import com.hw.nativeapp.BuildConfig;
+import com.hw.nativeapp.MApplication;
+import com.hw.nativeapp.R;
+import com.hw.nativeapp.config.Contents;
+import com.hw.nativeapp.httpnet.ErrorConsumer;
+import com.hw.nativeapp.httpnet.ResponseConsumer;
+import com.hw.nativeapp.httpnet.entity.EmptyBean;
+import com.hw.nativeapp.httpnet.entity.UpdateVerAskBean;
+import com.hw.nativeapp.httpnet.entity.UpdateVerReqBean;
+import com.hw.nativeapp.ui.dialogs.Dialog_Update;
+import com.hw.nativeapp.ui.dialogs.Dialog_UpdateProgress;
+import com.hw.nativeapp.update.UpdateHandler;
+import com.hw.nativeapp.utils.RxUtil;
+
+import java.io.File;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+/**
+ * 设置页面
+ * SettingActivity
+ *
+ * @author Geh
+ * @Admonish This is the ancestral code from Geh, please check!
+ * @time 2021/6/30 22:49
+ */
+public class SettingActivity extends BaseActivity {
+private static final String TAG = "SettingActivity";
+    @BindView(R.id.imageView5)
+    ImageView imageView5;
+    @BindView(R.id.textView19)
+    TextView textView19;
+    @BindView(R.id.btn_updatepassword)
+    LinearLayout btnUpdatepassword;
+    @BindView(R.id.btn_out)
+    LinearLayout btnOut;
+    @BindView(R.id.tx_appversion)
+    TextView txAppversion;
+    @BindView(R.id.tx_serial)
+    TextView txSerial;
+    @BindView(R.id.tx_projectName)
+    TextView projectName;
+    private Dialog_Update dialogUpdate;
+    private Dialog_UpdateProgress dialogUpdateProgress;
+    private EditText editText;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_setting);
+    }
+
+    @Override
+    public void initView() {
+        try {
+            PackageManager manager = this.getPackageManager();
+            PackageInfo packageInfo = manager.getPackageInfo(this.getPackageName(), 0);
+            txAppversion.setText(packageInfo.versionName + "." + packageInfo.versionCode);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        projectName.setText("(" + BuildConfig.prjectName + ")");
+    }
+
+
+    @OnClick({R.id.btn_updatepassword, R.id.btn_out,R.id.btn_print, R.id.btn_update})
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.btn_updatepassword:
+//                Start.start(SettingActivity.this, UpdatePasswordActivity.class);
+                break;
+            case R.id.btn_out:
+//                toCancellation();
+                break;
+            case R.id.btn_print:
+                break;
+            case R.id.btn_update:
+                update();
+                break;
+
+        }
+    }
+
+
+
+
+
+    private void update(){
+        try {
+            UpdateVerReqBean bean = new UpdateVerReqBean();
+            bean.appKeyId = Contents.APPID;
+            PackageManager manager = this.getPackageManager();
+            PackageInfo packageInfo = manager.getPackageInfo(this.getPackageName(), 0);
+            bean.versionName = packageInfo.versionName;
+            bean.versionCode = packageInfo.versionCode;
+            MApplication.getApiService().version(bean,System.currentTimeMillis()/1000)
+                    .compose(RxUtil.applyObservableAsync())
+                    .subscribe(new ResponseConsumer<UpdateVerAskBean>() {
+                        @Override
+                        public void onSuccess(UpdateVerAskBean data) {
+                            if (!data.isUpload){
+                                ToastUtils.showLong("当前为最新版本");
+                            }else {
+                                showUpdate(data,packageInfo);
+                            }
+                        }
+                    },new ErrorConsumer());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    private void showUpdate(UpdateVerAskBean bean,PackageInfo packageInfo){
+        String note = "当前版本:" + packageInfo.versionName + "." + packageInfo.versionCode + "\n" +
+                "新版本:" + bean.versionName + "." + bean.versionCode + "\n" +
+                "版本描述:" + bean.note;
+        dialogUpdate = new Dialog_Update(note,this);
+        dialogUpdate.show();
+        dialogUpdate.setOnDialogListener(new Dialog_Update.OnDialogListener() {
+            @Override
+            public void update() {
+                startDownload(bean.downloadUrl);
+            }
+
+            @Override
+            public void cancel() {
+            }
+        });
+    }
+
+    private void startDownload(String downUrl){
+            dialogUpdateProgress = new Dialog_UpdateProgress(this, new Dialog_UpdateProgress.OnDialogListener() {
+            @Override
+            public void opend() {
+                UpdateHandler updateHandler = new UpdateHandler(SettingActivity.this,downUrl);
+                updateHandler.setOnListener(new UpdateHandler.OnDownloadListener() {
+                    @Override
+                    public void complate() {
+                        dialogUpdateProgress.dismiss();
+                    }
+
+                    @Override
+                    public void progress(int soFarBytes, int totalBytes) {
+                        dialogUpdateProgress.setTxProgress(soFarBytes, totalBytes);
+                        dialogUpdateProgress.setProgressBar(soFarBytes, totalBytes);
+                    }
+                });
+                updateHandler.start();
+            }
+        });
+        dialogUpdateProgress.show();
+    }
+
+}

+ 84 - 61
app/src/main/java/com/hw/nativeapp/ui/dialogs/Dialog_Update.java

@@ -1,94 +1,117 @@
 package com.hw.nativeapp.ui.dialogs;
 
+import android.annotation.SuppressLint;
 import android.app.Dialog;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.widget.EditText;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+
+
 import com.hw.nativeapp.R;
 
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
+
+public class Dialog_Update extends Dialog implements View.OnClickListener{
+
+    private EditText etContent;
+    private TextView btnupEnter;
+    private TextView btnupCancel;
+
+    private String content;
+    private Context context;
 
-public class Dialog_Update extends Dialog {
 
-    public Dialog_Update(Context mcontext) {
+    private View view;
+    /**
+     * 确认或取消点击回调类
+     */
+    private OnDialogListener onDialogListener;
+
+
+    /**
+     * 点击外部是否可以取消
+     */
+    private boolean isCancelable = false;
+
+    public Dialog_Update(String content, Context mcontext) {
         super(mcontext);
+        this.content = content;
+        this.context = mcontext;
     }
 
-    public Dialog_Update(Context context, int themeResId){
-        super(context, themeResId);
-    }
+    @SuppressLint("WrongViewCast")
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_update);
 
-    public static class Builder {
-        private Context context;
-        private String message;//提示消息
-        private String negative_text;//消极的
-        private String positive_text;//积极的
-        private DialogInterface.OnClickListener negativeListener;//消极的监听
-        private DialogInterface.OnClickListener positiveListener;//积极的监听
 
-        public Builder(Context context) {
-            this.context = context;
-        }
+        etContent = findViewById(R.id.et_content);
+        btnupEnter = findViewById(R.id.btnup_enter);
+        btnupCancel = findViewById(R.id.btnup_cancel);
 
+        setCanceledOnTouchOutside(false);
 
-        public Builder setMessage(String message) {
-            if (message == null) {
-                this.message = "您没有填写提示信息哦";
-            }
-            this.message = message;
-            return this;
-        }
+        Window window = getWindow();
+        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+        window.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
+        window.setGravity(Gravity.CENTER);
 
-        public Builder setNegativeButton(String negative_text, DialogInterface.OnClickListener negativeListener) {
-            if (negative_text == null) {
-                this.negative_text = "取消";
-            }
-            this.negative_text = negative_text;
-            this.negativeListener = negativeListener;
+        btnupEnter.setOnClickListener(this);
+        btnupCancel.setOnClickListener(this);
+        etContent.setText(this.content);
+        etContent.setEnabled(false);
+    }
 
-            return this;
+    //
+//    @Override
+//    public void onDestroyView() {
+//        super.onDestroyView();
+//        unbinder.unbind();
+//    }
+
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()){
+            case R.id.btnup_enter:
+                onDialogListener.update();
+                this.dismiss();
+                break;
+            case R.id.btnup_cancel:
+                onDialogListener.cancel();
+                this.dismiss();
+                break;
         }
+    }
 
-        public Builder setPositionButton(String positive_text, DialogInterface.OnClickListener positiveListener) {
-            if (positive_text == null) {
-                this.positive_text = "确定";
-            }
-            this.positive_text = positive_text;
-            this.positiveListener = positiveListener;
 
-            return this;
-        }
+    public void setContent(String content){
+        etContent.setText(content);
+    }
 
+    /**
+     * 按钮回调方法
+     */
+    public interface OnDialogListener {
+        void update();
+        void cancel();
+    }
 
-        private TextView etContent;
-        private TextView btnupEnter;
-        private TextView btnupCancel;
-
-
-        public Dialog_Update create() {
-            final Dialog_Update dialog = new Dialog_Update(context);
-            View view = LayoutInflater.from(context).inflate(R.layout.dialog_update, null);
-            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);//加上这一句,取消原来的标题栏,没加这句之前,发现在三星的手机上会有一条蓝色的线
-//            dialog.addContentView(view, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-            dialog.setContentView(view, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-            etContent = (TextView) view.findViewById(R.id.et_content);
-            btnupEnter = (TextView) view.findViewById(R.id.btnup_enter);
-            btnupCancel = (TextView) view.findViewById(R.id.btnup_cancel);
-
-            etContent.setText(message);
-            btnupCancel.setText(negative_text);
-            btnupEnter.setText(positive_text);
-            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
-            btnupCancel.setOnClickListener(v -> negativeListener.onClick(dialog, Dialog.BUTTON_NEGATIVE));
-            btnupEnter.setOnClickListener(v -> positiveListener.onClick(dialog, Dialog.BUTTON_POSITIVE));
-            return dialog;
-        }
+    public void setOnDialogListener(OnDialogListener onDialogListener) {
+        this.onDialogListener = onDialogListener;
     }
 }

+ 89 - 70
app/src/main/java/com/hw/nativeapp/ui/dialogs/Dialog_UpdateProgress.java

@@ -1,108 +1,127 @@
 package com.hw.nativeapp.ui.dialogs;
 
+import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
-import android.widget.LinearLayout;
+import android.widget.EditText;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+
 
 import com.hw.nativeapp.R;
 
 import java.math.BigDecimal;
 
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
 
-public class Dialog_UpdateProgress extends Dialog {
+public class Dialog_UpdateProgress extends AlertDialog {
 
-    public Dialog_UpdateProgress(Context mcontext) {
-        super(mcontext);
-    }
+//    Unbinder unbinder;
+    ProgressBar progressBar;
+    TextView txProgress;
+    TextView txProgresspercentage;
 
-    public Dialog_UpdateProgress(Context context, int themeResId){
-        super(context, themeResId);
-    }
+    private Context context;
 
-    public static class Builder {
-        private Context context;
 
-        public Builder(Context context) {
-            this.context = context;
-        }
+    private View view;
+    /**
+     * 确认或取消点击回调类
+     */
+    private OnDialogListener onDialogListener;
 
 
+    /**
+     * 点击外部是否可以取消
+     */
+    private boolean isCancelable = false;
 
-        public void setProgressBar(int soFarBytes, int totalBytes){
-            if (progressBar != null && totalBytes > 0){
-                BigDecimal proDecimal = BigDecimal.valueOf(soFarBytes);
-                BigDecimal totalDecimal = BigDecimal.valueOf(totalBytes);
-                int progress = proDecimal.divide(totalDecimal,2,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).intValue();
-                progressBar.setProgress(progress);
-                txProgresspercentage.setText(progress + "%");
-            }else {
-                progressBar.setProgress(0);
-                txProgresspercentage.setText("0%");
-            }
-        }
+    public Dialog_UpdateProgress(Context mcontext, OnDialogListener listener) {
+        super(mcontext);
+        this.context = mcontext;
+        this.onDialogListener = listener;
+    }
 
-        public void setTxProgress(int soFarBytes, int totalBytes ){
-            if (txProgress != null){
-                if (totalBytes < soFarBytes){
-                    txProgress.setText(byteToMB(soFarBytes) + "/" + byteToMB(soFarBytes));
-                }else {
-                    txProgress.setText(byteToMB(soFarBytes) + "/" + byteToMB(totalBytes));
-                }
-            }
-        }
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_updateprogress);
 
+        progressBar = findViewById(R.id.progressBar);
+        txProgress = findViewById(R.id.tx_progress);
+        txProgresspercentage = findViewById(R.id.tx_progresspercentage);
 
-        ProgressBar progressBar;
-        TextView txProgress;
-        TextView txProgresspercentage;
-
-
-        public Dialog_UpdateProgress create() {
-            final Dialog_UpdateProgress dialog = new Dialog_UpdateProgress(context);
-            View view = LayoutInflater.from(context).inflate(R.layout.dialog_updateprogress, null);
-            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);//加上这一句,取消原来的标题栏,没加这句之前,发现在三星的手机上会有一条蓝色的线
-//            dialog.addContentView(view, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-            dialog.setContentView(view, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-            progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
-            txProgress = (TextView) view.findViewById(R.id.tx_progress);
-            txProgresspercentage = (TextView) view.findViewById(R.id.tx_progresspercentage);
-
-//            etContent.setText(message);
-//            btnupCancel.setText(negative_text);
-//            btnupEnter.setText(positive_text);
-            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
-//            btnupCancel.setOnClickListener(v -> negativeListener.onClick(dialog, Dialog.BUTTON_NEGATIVE));
-//            btnupEnter.setOnClickListener(v -> positiveListener.onClick(dialog, Dialog.BUTTON_POSITIVE));
-            return dialog;
+        Window window = getWindow();
+        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+        window.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
+        window.setGravity(Gravity.CENTER);
+
+        this.onDialogListener.opend();
+    }
+
+
+
+    public void setProgressBar(int soFarBytes, int totalBytes){
+        if (progressBar != null && totalBytes > 0){
+            BigDecimal proDecimal = BigDecimal.valueOf(soFarBytes);
+            BigDecimal totalDecimal = BigDecimal.valueOf(totalBytes);
+            int progress = proDecimal.divide(totalDecimal,2,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).intValue();
+            progressBar.setProgress(progress);
+            txProgresspercentage.setText(progress + "%");
+        }else {
+            progressBar.setProgress(0);
+            txProgresspercentage.setText("0%");
         }
+    }
 
-        private String byteToMB(long size){
-            long kb = 1024;
-            long mb = kb*1024;
-            long gb = mb*1024;
-            if (size >= gb){
-                return String.format("%.1f GB",(float)size/gb);
-            }else if (size >= mb){
-                float f = (float) size/mb;
-                return String.format(f > 100 ?"%.0f MB":"%.1f MB",f);
-            }else if (size > kb){
-                float f = (float) size / kb;
-                return String.format(f>100?"%.0f KB":"%.1f KB",f);
+    public void setTxProgress(int soFarBytes, int totalBytes ){
+        if (txProgress != null){
+            if (totalBytes < soFarBytes){
+                txProgress.setText(byteToMB(soFarBytes) + "/" + byteToMB(soFarBytes));
             }else {
-                return String.format("%d B",size);
+                txProgress.setText(byteToMB(soFarBytes) + "/" + byteToMB(totalBytes));
             }
         }
     }
 
+    /**
+     * 按钮回调方法
+     */
+    public interface OnDialogListener {
+        void opend();
+    }
+
+    public void setOnDialogListener(OnDialogListener listener) {
+        this.onDialogListener = listener;
+    }
 
+    private String byteToMB(long size){
+        long kb = 1024;
+        long mb = kb*1024;
+        long gb = mb*1024;
+        if (size >= gb){
+            return String.format("%.1f GB",(float)size/gb);
+        }else if (size >= mb){
+            float f = (float) size/mb;
+            return String.format(f > 100 ?"%.0f MB":"%.1f MB",f);
+        }else if (size > kb){
+            float f = (float) size / kb;
+            return String.format(f>100?"%.0f KB":"%.1f KB",f);
+        }else {
+            return String.format("%d B",size);
+        }
+    }
 }

+ 130 - 0
app/src/main/java/com/hw/nativeapp/update/UpdateHandler.java

@@ -0,0 +1,130 @@
+package com.hw.nativeapp.update;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.core.content.FileProvider;
+
+import com.blankj.utilcode.util.ToastUtils;
+import com.hw.nativeapp.utils.FileUtils;
+import com.hw.nativeapp.utils.StringUtils;
+import com.liulishuo.filedownloader.BaseDownloadTask;
+import com.liulishuo.filedownloader.FileDownloadListener;
+import com.liulishuo.filedownloader.FileDownloader;
+import com.liulishuo.filedownloader.util.FileDownloadUtils;
+
+import java.io.File;
+
+import sunmi.sunmiui.utils.LogUtil;
+
+public class UpdateHandler {
+
+    public static final String TAG = UpdateHandler.class.getName();
+
+    private String downloadUrl;
+    private String downloadLocalPath;
+    private Context context;
+    private OnDownloadListener onDownloadListener;
+
+    public UpdateHandler(Context context , String downloadUrl){
+        this.downloadUrl = downloadUrl;
+        this.context = context;
+    }
+
+    public interface OnDownloadListener {
+        void complate();
+        void progress(int soFarBytes, int totalBytes);
+    }
+
+    public void setOnListener(OnDownloadListener listener) {
+        this.onDownloadListener = listener;
+    }
+
+
+    public void start(){
+        if (StringUtils.isEmpty(this.downloadUrl)){
+            ToastUtils.showLong("下载地址为空");
+        }
+        this.downloadLocalPath = FileDownloadUtils.getDefaultSaveRootPath() + File.separator + "tmpdir1" + File.separator +
+                "download.apk";
+        if (FileUtils.isFileExists(this.downloadLocalPath)){
+            FileUtils.deleteFile(this.downloadLocalPath);
+        }
+        LogUtil.d("download", "下载地址 ---->" + this.downloadUrl );
+        LogUtil.d("download", "存储路径 ---->" + this.downloadLocalPath );
+        FileDownloader.getImpl().create(this.downloadUrl)
+                .setPath(this.downloadLocalPath)
+                .setListener(new FileDownloadListener() {
+                    @Override
+                    protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+                        LogUtil.d("download", "pending ---->");
+                    }
+
+                    @Override
+                    protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
+                        LogUtil.d("download", "connected ---->");
+                    }
+
+                    @Override
+                    protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+                        LogUtil.d("download", "progress ---->" + soFarBytes + ":" + totalBytes);
+                        onDownloadListener.progress(soFarBytes, totalBytes);
+                    }
+
+                    @Override
+                    protected void blockComplete(BaseDownloadTask task) {
+                        LogUtil.d("download", "blockComplete ---->");
+                    }
+
+                    @Override
+                    protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
+                        LogUtil.d("download", "retry ---->");
+                    }
+
+                    @Override
+                    protected void completed(BaseDownloadTask task) {
+                        LogUtil.d("download", "completed ---->");
+                        onDownloadListener.complate();
+                        installApk();
+                    }
+
+                    @Override
+                    protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+                        LogUtil.d("download", "paused ---->");
+                    }
+
+                    @Override
+                    protected void error(BaseDownloadTask task, Throwable e) {
+                        LogUtil.d("download", "error ---->");
+                    }
+
+                    @Override
+                    protected void warn(BaseDownloadTask task) {
+                        LogUtil.d("download", "warn ---->");
+                    }
+                }).start();
+    }
+
+    private void installApk(){
+
+        File apkFile = new File(this.downloadLocalPath);
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            Log.w(TAG, "版本大于 N ,开始使用 fileProvider 进行安装");
+            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            Uri contentUri = FileProvider.getUriForFile(
+                    this.context
+                    , "com.hw.parkingpda.fileprovider"
+                    , apkFile);
+            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
+        } else {
+            Log.w(TAG, "正常进行安装");
+            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
+        }
+        this.context.startActivity(intent);
+    }
+}

+ 42 - 35
app/src/main/java/com/hw/nativeapp/utils/UpgradeUtils.java

@@ -14,8 +14,10 @@ import com.hw.nativeapp.httpnet.ResponseConsumer;
 import com.hw.nativeapp.httpnet.entity.UpdateVerAskBean;
 import com.hw.nativeapp.httpnet.entity.UpdateVerReqBean;
 import com.hw.nativeapp.httpnet.upgrade.UpgradeHandler;
+import com.hw.nativeapp.ui.activity.SettingActivity;
 import com.hw.nativeapp.ui.dialogs.Dialog_Update;
 import com.hw.nativeapp.ui.dialogs.Dialog_UpdateProgress;
+import com.hw.nativeapp.update.UpdateHandler;
 
 public class UpgradeUtils {
 
@@ -23,8 +25,7 @@ public class UpgradeUtils {
     public static  void upgrade(Context context){
         try {
             UpdateVerReqBean bean = new UpdateVerReqBean();
-            bean.appId = Contents.APPID;
-            bean.name = context.getResources().getString(R.string.app_name);
+            bean.appKeyId = Contents.APPID;
             PackageManager manager = context.getPackageManager();
             PackageInfo packageInfo = manager.getPackageInfo(context.getPackageName(), 0);
             bean.versionName = packageInfo.versionName;
@@ -47,38 +48,44 @@ public class UpgradeUtils {
     }
 
 
-    private static void showUpdate(UpdateVerAskBean bean, PackageInfo packageInfo, Context context){
-        String note = "当前版本:" + packageInfo.versionName + "." + packageInfo.versionCode + "\n" +
-                "新版本:" + bean.versionName + "." + bean.versionCode + "\n" +
-                "版本描述:" + bean.note;
-        Dialog_Update.Builder builder = new Dialog_Update.Builder(context);
-        builder.setMessage(note)
-                .setNegativeButton("取消", (dialog, which) -> dialog.dismiss())
-                .setPositionButton("确定", (dialog, which) -> {
-                    dialog.dismiss();
-                    startDownload(context, bean.pkgUrl);
-                })
-                .create()
-                .show();
-    }
-
-    private static void startDownload(Context context , String downUrl){
-        Dialog_UpdateProgress.Builder builder = new Dialog_UpdateProgress.Builder(context);
-        Dialog_UpdateProgress builderdig  = builder.create();
-        builderdig.show();
-        UpgradeHandler updateHandler = new UpgradeHandler(context,downUrl);
-        updateHandler.setOnListener(new UpgradeHandler.OnDownloadListener() {
-            @Override
-            public void complate() {
-                builderdig.dismiss();
-            }
+//    private static void showUpdate(final UpdateVerAskBean bean, PackageInfo packageInfo, Context context){
+//        String note = "当前版本:" + packageInfo.versionName + "." + packageInfo.versionCode + "\n" +
+//                "新版本:" + bean.versionName + "." + bean.versionCode + "\n" +
+//                "版本描述:" + bean.note;
+//        Dialog_Update dialogUpdate = new Dialog_Update(note,context);
+//        dialogUpdate.show();
+//        dialogUpdate.setOnDialogListener(new Dialog_Update.OnDialogListener() {
+//            @Override
+//            public void update() {
+//                startDownload(bean.downloadUrl);
+//            }
+//
+//            @Override
+//            public void cancel() {
+//            }
+//        });
+//    }
 
-            @Override
-            public void progress(int soFarBytes, int totalBytes) {
-                builder.setTxProgress(soFarBytes, totalBytes);
-                builder.setProgressBar(soFarBytes, totalBytes);
-            }
-        });
-        updateHandler.start();
-    }
+//    private static void startDownload(Context context , String downUrl){
+//        Dialog_UpdateProgress dialogUpdateProgress = new Dialog_UpdateProgress(context, new Dialog_UpdateProgress.OnDialogListener() {
+//            @Override
+//            public void opend() {
+//                UpdateHandler updateHandler = new UpdateHandler(context,downUrl);
+//                updateHandler.setOnListener(new UpdateHandler.OnDownloadListener() {
+//                    @Override
+//                    public void complate() {
+//                        dialogUpdateProgress.dismiss();
+//                    }
+//
+//                    @Override
+//                    public void progress(int soFarBytes, int totalBytes) {
+//                        dialogUpdateProgress.setTxProgress(soFarBytes, totalBytes);
+//                        dialogUpdateProgress.setProgressBar(soFarBytes, totalBytes);
+//                    }
+//                });
+//                updateHandler.start();
+//            }
+//        });
+//        dialogUpdateProgress.show();
+//    }
 }

+ 748 - 0
app/src/main/java/com/hw/nativeapp/utils/sunmi/BytesUtil.java

@@ -0,0 +1,748 @@
+package com.hw.nativeapp.utils.sunmi;
+
+import android.annotation.SuppressLint;
+import android.graphics.Bitmap;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Hashtable;
+
+public class BytesUtil {
+
+	//字节流转16进制字符串
+	public static String getHexStringFromBytes(byte[] data) {
+		if (data == null || data.length <= 0) {
+			return null;
+		}
+		String hexString = "0123456789ABCDEF";
+		int size = data.length * 2;
+		StringBuilder sb = new StringBuilder(size);
+		for (int i = 0; i < data.length; i++) {
+			sb.append(hexString.charAt((data[i] & 0xF0) >> 4));
+			sb.append(hexString.charAt((data[i] & 0x0F) >> 0));
+		}
+		return sb.toString();
+	}
+
+	//单字符转字节
+	private static byte charToByte(char c) {
+		return (byte) "0123456789ABCDEF".indexOf(c);
+	}
+
+	//16进制字符串转字节数组
+	@SuppressLint("DefaultLocale")
+	public static byte[] getBytesFromHexString(String hexstring){
+		if(hexstring == null || hexstring.equals("")){
+			return null;
+		}
+		hexstring = hexstring.replace(" ", "");
+		hexstring = hexstring.toUpperCase();
+		int size = hexstring.length()/2;
+		char[] hexarray = hexstring.toCharArray();
+		byte[] rv = new byte[size];
+		for(int i=0; i<size; i++){
+			int pos = i * 2;
+			rv[i] = (byte) (charToByte(hexarray[pos]) << 4 | charToByte(hexarray[pos + 1]));
+		}
+		return rv;
+	}
+
+	//十进制字符串转字节数组
+	@SuppressLint("DefaultLocale")
+	public static byte[] getBytesFromDecString(String decstring){
+		if(decstring == null || decstring.equals("")){
+			return null;
+		}
+		decstring = decstring.replace(" ", "");
+		int size = decstring.length()/2;
+		char[] decarray = decstring.toCharArray();
+		byte[] rv = new byte[size];
+		for(int i=0; i<size; i++){
+			int pos = i * 2;
+			rv[i] = (byte) (charToByte(decarray[pos])*10 + charToByte(decarray[pos + 1]));
+		}
+		return rv;
+	}
+
+	//字节数组组合操作1
+	public static byte[] byteMerger(byte[] byte_1, byte[] byte_2) {
+		byte[] byte_3 = new byte[byte_1.length + byte_2.length];
+		System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
+		System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
+		return byte_3;
+	}
+
+	//字节数组组合操作2
+	public static byte[] byteMerger(byte[][] byteList) {
+
+		int length = 0;
+		for (int i = 0; i < byteList.length; i++) {
+			length += byteList[i].length;
+		}
+		byte[] result = new byte[length];
+
+		int index = 0;
+		for (int i = 0; i < byteList.length; i++) {
+			byte[] nowByte = byteList[i];
+			for (int k = 0; k < byteList[i].length; k++) {
+				result[index] = nowByte[k];
+				index++;
+			}
+		}
+		for (int i = 0; i < index; i++) {
+			// CommonUtils.LogWuwei("", "result[" + i + "] is " + result[i]);
+		}
+		return result;
+	}
+
+	//生成表格字节流
+	public static byte[] initTable(int h, int w){
+		int hh = h * 32;
+		int ww = w * 4;
+
+		byte[] data = new byte[ hh * ww + 5];
+
+
+		data[0] = (byte)ww;//xL
+		data[1] = (byte)(ww >> 8);//xH
+		data[2] = (byte)hh;
+		data[3] = (byte)(hh >> 8);
+
+		int k = 4;
+		int m = 31;
+		for(int i=0; i<h; i++){
+			for(int j=0; j<w; j++){
+				data[k++] = (byte)0xFF;
+				data[k++] = (byte)0xFF;
+				data[k++] = (byte)0xFF;
+				data[k++] = (byte)0xFF;
+			}
+			if(i == h-1) m =30;
+			for(int t=0; t< m; t++){
+				for(int j=0; j<w-1; j++){
+					data[k++] = (byte)0x80;
+					data[k++] = (byte)0;
+					data[k++] = (byte)0;
+					data[k++] = (byte)0;
+				}
+				data[k++] = (byte)0x80;
+				data[k++] = (byte)0;
+				data[k++] = (byte)0;
+				data[k++] = (byte)0x01;
+			}
+		}
+		for(int j=0; j<w; j++){
+			data[k++] = (byte)0xFF;
+			data[k++] = (byte)0xFF;
+			data[k++] = (byte)0xFF;
+			data[k++] = (byte)0xFF;
+		}
+		data[k++] = 0x0A;
+		return data;
+	}
+
+	/**
+	 * 生成多个二维码字节流
+	 */
+	public static byte[] getZXingQRCode(String qr1, String qr2, int size) {
+		try {
+			Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
+			hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
+			//图像数据转换,使用了矩阵转换
+			BitMatrix bitMatrix1 = new QRCodeWriter().encode(qr1, BarcodeFormat.QR_CODE,
+					size, size, hints);
+			BitMatrix bitMatrix2 = new QRCodeWriter().encode(qr2, BarcodeFormat.QR_CODE,
+					size, size, hints);
+			return getBytesFromBitMatrix(bitMatrix1, bitMatrix2, 40);
+		} catch (WriterException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * 合并两个矩阵数据
+	 */
+	public static byte[] getBytesFromBitMatrix(BitMatrix bits1, BitMatrix bits2, int space) {
+		if (bits1 == null || bits2 == null) return null;
+
+		int h1 = bits1.getHeight();
+		int w1 = bits1.getWidth();
+		int h2 = bits2.getHeight();
+		int w2 = bits2.getWidth();
+		int h = Math.max(h1, h2);
+		int w = (w1 + w2 + space + 7)/8;
+
+		byte[] rv = new byte[h * w + 4];
+
+		rv[0] = (byte) w;//xL
+		rv[1] = (byte) (w >> 8);//xH
+		rv[2] = (byte) h;
+		rv[3] = (byte) (h >> 8);
+
+		int k = 4;
+		byte b;
+		for (int i = 0; i < h; i++) {
+			for (int j = 0; j < w; j++) {
+				for (int n = 0; n < 8; n++) {
+					int pos = j * 8 + n;
+					if(pos < w1) {
+						if(i < h1) {
+							b = getBitMatrixColor(bits1, pos, i);
+						} else {
+							b = 0;
+						}
+						rv[k] += rv[k] + b;
+					} else if(pos < (w1 + space)) {
+						rv[k] += rv[k];
+					} else {
+						if(i < h2) {
+							b = getBitMatrixColor(bits2, pos - w1 - space, i);
+						} else {
+							b = 0;
+						}
+						rv[k] += rv[k] + b;
+					}
+				}
+				k++;
+			}
+		}
+		return rv;
+	}
+
+	private static byte getBitMatrixColor(BitMatrix bits, int x, int y) {
+		int width = bits.getWidth();
+		int height = bits.getHeight();
+		if (x >= width || y >= height || x < 0 || y < 0) return 0;
+		if (bits.get(x, y)) {
+			return 1;
+		} else {
+			return 0;
+		}
+	}
+
+	/**
+	 * 将bitmap图转换为头四位有宽高的光栅位图
+	 */
+	public static byte[] getBytesFromBitMap(Bitmap bitmap) {
+		int width = bitmap.getWidth();
+		int height = bitmap.getHeight();
+		int bw = (width - 1) / 8 + 1;
+
+		byte[] rv = new byte[height * bw + 4];
+		rv[0] = (byte) bw;//xL
+		rv[1] = (byte) (bw >> 8);//xH
+		rv[2] = (byte) height;
+		rv[3] = (byte) (height >> 8);
+
+		int[] pixels = new int[width * height];
+		bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
+
+		for (int i = 0; i < height; i++) {
+			for (int j = 0; j < width; j++) {
+				int clr = pixels[width * i + j];
+				int red = (clr & 0x00ff0000) >> 16;
+				int green = (clr & 0x0000ff00) >> 8;
+				int blue = clr & 0x000000ff;
+				byte gray = (RGB2Gray(red, green, blue));
+				rv[bw*i + j/8 + 4] = (byte) (rv[bw*i + j/8 + 4] | (gray << (7 - j % 8)));
+			}
+		}
+
+		return rv;
+	}
+
+	/**
+	 * 将bitmap转成按mode指定的N点行数据
+	 */
+	public static byte[] getBytesFromBitMap(Bitmap bitmap, int mode) {
+		int width = bitmap.getWidth();
+		int height = bitmap.getHeight();
+		int[] pixels = new int[width*height];
+		if(mode == 0 || mode == 1){
+			byte[] res = new byte[width*height/8 + 5*height/8];
+			bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
+			for(int i = 0; i < height/8; i++){
+				res[0 + i*(width+5)] = 0x1b;
+				res[1 + i*(width+5)] = 0x2a;
+				res[2 + i*(width+5)] = (byte) mode;
+				res[3 + i*(width+5)] = (byte) (width%256);
+				res[4 + i*(width+5)] = (byte) (width/256);
+				for(int j = 0; j < width; j++){
+					byte gray = 0;
+					for(int m = 0; m < 8; m++){
+						int clr = pixels[j + width*(i*8+m)];
+						int red = (clr & 0x00ff0000) >> 16;
+						int green = (clr & 0x0000ff00) >> 8;
+						int blue = clr & 0x000000ff;
+						gray = (byte) ((RGB2Gray(red, green, blue)<<(7-m))|gray);
+					}
+					res[5 + j + i*(width+5)] = gray;
+				}
+			}
+			return res;
+		}else if(mode == 32 || mode == 33){
+			byte[] res = new byte[width*height/8 + 5*height/24];
+			bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
+			for(int i = 0; i < height/24; i++){
+				res[0 + i*(width*3+5)] = 0x1b;
+				res[1 + i*(width*3+5)] = 0x2a;
+				res[2 + i*(width*3+5)] = (byte) mode;
+				res[3 + i*(width*3+5)] = (byte) (width%256);
+				res[4 + i*(width*3+5)] = (byte) (width/256);
+				for(int j = 0; j < width; j++){
+					for(int n = 0; n < 3; n++){
+						byte gray = 0;
+						for(int m = 0; m < 8; m++){
+							int clr = pixels[j + width*(i*24 + m + n*8)];
+							int red = (clr & 0x00ff0000) >> 16;
+							int green = (clr & 0x0000ff00) >> 8;
+							int blue = clr & 0x000000ff;
+							gray = (byte) ((RGB2Gray(red, green, blue)<<(7-m))|gray);
+						}
+						res[5 + j*3 + i*(width*3+5) + n] = gray;
+					}
+				}
+			}
+			return res;
+		}else{
+			return new byte[]{0x0A};
+		}
+
+	}
+
+
+
+	private static byte RGB2Gray(int r, int g, int b) {
+		return (false ? ((int) (0.29900 * r + 0.58700 * g + 0.11400 * b) > 200)
+				: ((int) (0.29900 * r + 0.58700 * g + 0.11400 * b) < 200)) ? (byte) 1 : (byte) 0;
+	}
+
+	/**
+	 * 生成间断性黑块数据
+	 * @param w : 打印纸宽度, 单位点
+	 * @return
+	 */
+	public static byte[] initBlackBlock(int w){
+		int ww = (w + 7)/8 ;
+		int n = (ww + 11)/12;
+		int hh = n * 24;
+		byte[] data = new byte[ hh * ww + 5];
+
+		data[0] = (byte)ww;//xL
+		data[1] = (byte)(ww >> 8);//xH
+		data[2] = (byte)hh;
+		data[3] = (byte)(hh >> 8);
+
+		int k = 4;
+		for(int i=0; i < n; i++){
+			for(int j=0; j<24; j++){
+				for(int m =0; m<ww; m++){
+					if(m/12 == i){
+						data[k++] = (byte)0xFF;
+					}else{
+						data[k++] = 0;
+					}
+				}
+			}
+		}
+		data[k++] = 0x0A;
+		return data;
+	}
+
+	/**
+	 * 生成一大块黑块数据
+	 * @param h : 黑块高度, 单位点
+	 * @param w : 黑块宽度, 单位点, 8的倍数
+	 * @return
+	 */
+	public static byte[] initBlackBlock(int h, int w){
+		int hh = h;
+		int ww = (w - 1)/8 + 1;
+		byte[] data = new byte[ hh * ww + 6];
+
+		data[0] = (byte)ww;//xL
+		data[1] = (byte)(ww >> 8);//xH
+		data[2] = (byte)hh;
+		data[3] = (byte)(hh >> 8);
+
+		int k = 4;
+		for(int i=0; i<hh; i++){
+			for(int j=0; j<ww; j++){
+				data[k++] = (byte)0xFF;
+			}
+		}
+		data[k++] = 0x00;data[k++] = 0x00;
+		return data;
+	}
+
+	/**
+	 * 百度小票 (Baidu ticket for ESC cmd)
+	 */
+	public static byte[] getBaiduTestBytes() {
+		byte[] rv = new byte[]{
+				0x1b, 0x40, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x11, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x1b, 0x45, 0x01, 0x1b, 0x47, 0x01, (byte) 0xb1, (byte) 0xbe
+				, (byte) 0xb5, (byte) 0xea, (byte) 0xc1, (byte) 0xf4, (byte) 0xb4, (byte) 0xe6, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a
+				, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a
+				, 0x2a, 0x0a
+				, 0x1b, 0x40, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x11, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x1b, 0x45, 0x01, 0x1b, 0x47, 0x01, 0x1b, 0x61
+				, 0x01, 0x23, 0x31, 0x35, 0x20, (byte) 0xb0, (byte) 0xd9, (byte) 0xb6, (byte) 0xc8, (byte) 0xcd, (byte) 0xe2, (byte) 0xc2, (byte) 0xf4, 0x0a, 0x5b, (byte) 0xbb, (byte) 0xf5, (byte) 0xb5, (byte) 0xbd, (byte) 0xb8, (byte) 0xb6, (byte) 0xbf, (byte) 0xee, 0x5d, 0x0a, 0x1b, 0x4d, 0x00
+				, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a
+				, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a
+				, 0x1b, 0x40, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x01, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, (byte) 0xc6, (byte) 0xda, (byte) 0xcd, (byte) 0xfb, (byte) 0xcb, (byte) 0xcd, (byte) 0xb4, (byte) 0xef
+				, (byte) 0xca, (byte) 0xb1, (byte) 0xbc, (byte) 0xe4, (byte) 0xa3, (byte) 0xba, (byte) 0xc1, (byte) 0xa2, (byte) 0xbc, (byte) 0xb4, (byte) 0xc5, (byte) 0xe4, (byte) 0xcb, (byte) 0xcd, 0x0a, (byte) 0xb6, (byte) 0xa9, (byte) 0xb5, (byte) 0xa5, (byte) 0xb1, (byte) 0xb8, (byte) 0xd7, (byte) 0xa2, (byte) 0xa3, (byte) 0xba, (byte) 0xc7, (byte) 0xeb, (byte) 0xcb
+				, (byte) 0xcd, (byte) 0xb5, (byte) 0xbd, (byte) 0xbf, (byte) 0xfc, (byte) 0xbf, (byte) 0xc6, (byte) 0xce, (byte) 0xf7, (byte) 0xc3, (byte) 0xc5, 0x2c, (byte) 0xb2, (byte) 0xbb, (byte) 0xd2, (byte) 0xaa, (byte) 0xc0, (byte) 0xb1, 0x0a, (byte) 0xb7, (byte) 0xa2, (byte) 0xc6, (byte) 0xb1, (byte) 0xd0, (byte) 0xc5, (byte) 0xcf, (byte) 0xa2, (byte) 0xa3
+				, (byte) 0xba, (byte) 0xb0, (byte) 0xd9, (byte) 0xb6, (byte) 0xc8, (byte) 0xcd, (byte) 0xe2, (byte) 0xc2, (byte) 0xf4, (byte) 0xb7, (byte) 0xa2, (byte) 0xc6, (byte) 0xb1, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47
+				, 0x00, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a
+				, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a
+				, 0x1b, 0x40, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, (byte) 0xb6, (byte) 0xa9, (byte) 0xb5, (byte) 0xa5, (byte) 0xb1, (byte) 0xe0, (byte) 0xba, (byte) 0xc5
+				, (byte) 0xa3, (byte) 0xba, 0x31, 0x34, 0x31, 0x38, 0x37, 0x31, 0x38, 0x36, 0x39, 0x31, 0x31, 0x36, 0x38, 0x39, 0x0a, (byte) 0xcf, (byte) 0xc2, (byte) 0xb5, (byte) 0xa5, (byte) 0xca, (byte) 0xb1, (byte) 0xbc, (byte) 0xe4, (byte) 0xa3, (byte) 0xba, 0x32
+				, 0x30, 0x31, 0x34, 0x2d, 0x31, 0x32, 0x2d, 0x31, 0x36, 0x20, 0x31, 0x36, 0x3a, 0x33, 0x31, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00
+				, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a
+				, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a
+				, 0x1b, 0x40, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x01, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, (byte) 0xb2, (byte) 0xcb, (byte) 0xc6, (byte) 0xb7, (byte) 0xc3, (byte) 0xfb, (byte) 0xb3, (byte) 0xc6
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, (byte) 0xca, (byte) 0xfd, (byte) 0xc1, (byte) 0xbf, 0x20, 0x20, 0x20, 0x20, 0x20, (byte) 0xbd, (byte) 0xf0, (byte) 0xb6, (byte) 0xee, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61
+				, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x01, 0x1b
+				, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, (byte) 0xcf, (byte) 0xe3, (byte) 0xc0, (byte) 0xb1, (byte) 0xc3, (byte) 0xe6, (byte) 0xcc, (byte) 0xd7, (byte) 0xb2, (byte) 0xcd, 0x1b, 0x24, (byte) 0xf2, 0x00, 0x31, 0x1b, 0x24, 0x25, 0x01, (byte) 0xa3
+				, (byte) 0xa4, 0x34, 0x30, 0x2e, 0x30, 0x30, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x1b, 0x4d, 0x00
+				, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x01, 0x1b, 0x45, 0x00, 0x1b
+				, 0x47, 0x00, 0x1b, 0x61, 0x00, (byte) 0xcb, (byte) 0xd8, (byte) 0xca, (byte) 0xb3, (byte) 0xcc, (byte) 0xec, (byte) 0xcf, (byte) 0xc2, (byte) 0xba, (byte) 0xba, (byte) 0xb1, (byte) 0xa4, 0x1b, 0x24, (byte) 0xf2, 0x00, 0x31, 0x1b, 0x24, 0x25, 0x01, (byte) 0xa3, (byte) 0xa4
+				, 0x33, 0x38, 0x2e, 0x30, 0x30, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x1b, 0x4d, 0x00, 0x1b
+				, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00
+				, 0x1b, 0x40, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
+				, 0x1b, 0x40, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a
+				, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a, 0x1b, 0x4d, 0x00
+				, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x01, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, (byte) 0xd0, (byte) 0xd5, (byte) 0xc3, (byte) 0xfb, (byte) 0xa3, (byte) 0xba, (byte) 0xb0, (byte) 0xd9, (byte) 0xb6, (byte) 0xc8, (byte) 0xb2, (byte) 0xe2, (byte) 0xca
+				, (byte) 0xd4, 0x0a, (byte) 0xb5, (byte) 0xd8, (byte) 0xd6, (byte) 0xb7, (byte) 0xa3, (byte) 0xba, (byte) 0xbf, (byte) 0xfc, (byte) 0xbf, (byte) 0xc6, (byte) 0xbf, (byte) 0xc6, (byte) 0xbc, (byte) 0xbc, (byte) 0xb4, (byte) 0xf3, (byte) 0xcf, (byte) 0xc3, 0x0a, (byte) 0xb5, (byte) 0xe7, (byte) 0xbb, (byte) 0xb0, (byte) 0xa3, (byte) 0xba, 0x31
+				, 0x38, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a
+				, 0x1b, 0x40, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a
+				, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a, (byte) 0xb0, (byte) 0xd9, (byte) 0xb6
+				, (byte) 0xc8, (byte) 0xb2, (byte) 0xe2, (byte) 0xca, (byte) 0xd4, (byte) 0xc9, (byte) 0xcc, (byte) 0xbb, (byte) 0xa7, 0x0a, 0x31, 0x38, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d
+				, 0x21, 0x00, 0x1b, 0x45, 0x00, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a
+				, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a, 0x1b, 0x4d, 0x00, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x00, 0x1b, 0x45, 0x00
+				, 0x1b, 0x47, 0x00, 0x1b, 0x61, 0x00, 0x1b, 0x61, 0x01, 0x23, 0x31, 0x35, 0x20, (byte) 0xb0, (byte) 0xd9, (byte) 0xb6, (byte) 0xc8, (byte) 0xcd, (byte) 0xe2, (byte) 0xc2, (byte) 0xf4, 0x20, 0x20, 0x31, 0x31, (byte) 0xd4, (byte) 0xc2, 0x30
+				, 0x39, (byte) 0xc8, (byte) 0xd5, 0x20, 0x31, 0x37, 0x3a, 0x35, 0x30, 0x3a, 0x33, 0x30, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a
+		};
+		return rv;
+	}
+
+	/**
+	 * 美团小票(Meituan ticket for ESC cmd)
+	 */
+	public static byte[] getMeituanBill() {
+		byte[] rv = new byte[]{
+				0x1b, 0x40, 0x1b, 0x61, 0x01, 0x1d, 0x21, 0x11, (byte) 0xa3, (byte) 0xa3, 0x31, 0x20, 0x20, (byte) 0xc3, (byte) 0xc0, (byte) 0xcd, (byte) 0xc5, (byte) 0xb2, (byte) 0xe2, (byte) 0xca, (byte) 0xd4, 0x0a
+				, 0x0a, 0x1d, 0x21, 0x00, (byte) 0xd4, (byte) 0xc1, (byte) 0xcf, (byte) 0xe3, (byte) 0xb8, (byte) 0xdb, (byte) 0xca, (byte) 0xbd, (byte) 0xc9, (byte) 0xd5, (byte) 0xc0, (byte) 0xb0, 0x28, (byte) 0xb5, (byte) 0xda, 0x31, (byte) 0xc1, (byte) 0xaa
+				, 0x29, 0x0a, 0x1b, 0x21, 0x10, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x2a, 0x20, 0x2a, 0x20, 0x2a, 0x20
+				, 0x2a, 0x20, 0x2a, 0x20, 0x2a, 0x20, 0x20, (byte) 0xd4, (byte) 0xa4, (byte) 0xb6, (byte) 0xa9, (byte) 0xb5, (byte) 0xa5, 0x20, 0x20, 0x2a, 0x20, 0x2a, 0x20, 0x2a, 0x20, 0x2a
+				, 0x20, 0x2a, 0x20, 0x2a, 0x0a, (byte) 0xc6, (byte) 0xda, (byte) 0xcd, (byte) 0xfb, (byte) 0xcb, (byte) 0xcd, (byte) 0xb4, (byte) 0xef, (byte) 0xca, (byte) 0xb1, (byte) 0xbc, (byte) 0xe4, 0x3a, 0x20, 0x5b, 0x31, 0x38
+				, 0x3a, 0x30, 0x30, 0x5d, 0x0a, 0x1d, 0x21, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1b, 0x61, 0x00
+				, (byte) 0xcf, (byte) 0xc2, (byte) 0xb5, (byte) 0xa5, (byte) 0xca, (byte) 0xb1, (byte) 0xbc, (byte) 0xe4, 0x3a, 0x30, 0x31, 0x2d, 0x30, 0x31, 0x20, 0x31, 0x32, 0x3a, 0x30, 0x30, 0x0a, 0x1b
+				, 0x21, 0x10, (byte) 0xb1, (byte) 0xb8, (byte) 0xd7, (byte) 0xa2, 0x3a, (byte) 0xb1, (byte) 0xf0, (byte) 0xcc, (byte) 0xab, (byte) 0xc0, (byte) 0xb1, 0x0a, 0x1d, 0x21, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, (byte) 0xb2, (byte) 0xcb, (byte) 0xc3, (byte) 0xfb, 0x09, 0x09, 0x20, 0x20, 0x20, (byte) 0xca, (byte) 0xfd, (byte) 0xc1, (byte) 0xbf, 0x09, 0x20, 0x20
+				, 0x20, 0x20, (byte) 0xd0, (byte) 0xa1, (byte) 0xbc, (byte) 0xc6, 0x09, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1b, 0x21, 0x10
+				, (byte) 0xba, (byte) 0xec, (byte) 0xc9, (byte) 0xd5, (byte) 0xc8, (byte) 0xe2, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78
+				, 0x31, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x32, 0x0a, 0x1d, 0x21, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x0a, (byte) 0xc5, (byte) 0xe4, (byte) 0xcb, (byte) 0xcd, (byte) 0xb7, (byte) 0xd1, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0x0a, (byte) 0xb2, (byte) 0xcd, (byte) 0xba, (byte) 0xd0, (byte) 0xb7, (byte) 0xd1, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x31, 0x0a, 0x5b, (byte) 0xb3, (byte) 0xac, (byte) 0xca, (byte) 0xb1, (byte) 0xc5, (byte) 0xe2, (byte) 0xb8, (byte) 0xb6, 0x5d, 0x20, 0x2d, (byte) 0xcf, (byte) 0xea, (byte) 0xbc, (byte) 0xfb, (byte) 0xb6, (byte) 0xa9, (byte) 0xb5
+				, (byte) 0xa5, 0x0a, (byte) 0xbf, (byte) 0xc9, (byte) 0xbf, (byte) 0xda, (byte) 0xbf, (byte) 0xc9, (byte) 0xc0, (byte) 0xd6, 0x3a, 0x78, 0x31, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x0a, 0x1b, 0x21, 0x10, (byte) 0xba, (byte) 0xcf, (byte) 0xbc, (byte) 0xc6, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x38, (byte) 0xd4, (byte) 0xaa, 0x0a, 0x1b, 0x40, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1d, 0x21, 0x11, (byte) 0xd5, (byte) 0xc5, 0x2a, 0x20, 0x31, 0x38, 0x33, 0x31, 0x32, 0x33, 0x34
+				, 0x35, 0x36, 0x37, 0x38, 0x0a, (byte) 0xb5, (byte) 0xd8, (byte) 0xd6, (byte) 0xb7, (byte) 0xd0, (byte) 0xc5, (byte) 0xcf, (byte) 0xa2, 0x0a, 0x1d, 0x21, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x01, 0x1d, 0x21, 0x11, (byte) 0xa3, (byte) 0xa3, 0x31, 0x20, 0x20, (byte) 0xc3, (byte) 0xc0
+				, (byte) 0xcd, (byte) 0xc5, (byte) 0xb2, (byte) 0xe2, (byte) 0xca, (byte) 0xd4, 0x0a, 0x1d, 0x21, 0x00, 0x1b, 0x40, 0x0a, 0x0a, 0x0a, 0x1d, 0x56, 0x00
+		};
+		return rv;
+	}
+
+	/**
+	 * 饿了么小票(Eleme ticket for ESC cmd)
+	 */
+	public static byte[] getErlmoData() {
+		byte[] rv = new byte[]{
+				0x1b, 0x40, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x20, 0x1d, 0x21, 0x11, 0x23, 0x31, 0x1d, 0x21, 0x00, 0x00, (byte) 0xb6, (byte) 0xf6
+				, (byte) 0xc1, (byte) 0xcb, (byte) 0xc3, (byte) 0xb4, (byte) 0xcd, (byte) (byte) 0xe2, (byte) 0xc2, (byte) 0xf4, (byte) 0xb5, (byte) 0xa5, 0x20, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a, 0x0a, 0x1b, 0x61
+				, 0x01, (byte) 0xbf, (byte) 0xa8, (byte) 0xc8, (byte) 0xf8, (byte) 0xc5, (byte) 0xfb, (byte) 0xc8, (byte) 0xf8, 0x0a, 0x0a, 0x1b, 0x61, 0x00, 0x1b, 0x61, 0x01, 0x1d, 0x21, 0x11, 0x2d, 0x2d
+				, (byte) 0xd2, (byte) 0xd1, (byte) 0xd6, (byte) 0xa7, (byte) 0xb8, (byte) 0xb6, 0x2d, 0x2d, 0x1d, 0x21, 0x00, 0x00, 0x0a, 0x0a, 0x1b, 0x61, 0x00, 0x1b, 0x61, 0x01, 0x1d, 0x21
+				, 0x11, (byte) 0xd4, (byte) 0xa4, (byte) 0xbc, (byte) 0xc6, 0x31, 0x39, 0x3a, 0x30, 0x30, (byte) 0xcb, (byte) 0xcd, (byte) 0xb4, (byte) (byte) 0xef, 0x1d, 0x21, 0x00, 0x00, 0x0a, 0x0a, 0x1b, 0x61
+				, 0x00, 0x5b, (byte) 0xcf, (byte) 0xc2, (byte) 0xb5, (byte) 0xa5, (byte) 0xca, (byte) 0xb1, (byte) 0xbc, (byte) (byte) 0xe4, 0x5d, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x33, 0x20
+				, 0x31, 0x36, 0x3a, 0x32, 0x31, 0x0a, 0x5b, (byte) 0xb1, (byte) 0xb8, (byte) 0xd7, (byte) 0xa2, 0x5d, 0x1d, 0x21, 0x01, (byte) 0xb2, (byte) 0xbb, (byte) 0xb3, (byte) 0xd4, (byte) 0xc0, (byte) 0xb1, 0x20
+				, (byte) 0xc0, (byte) 0xb1, (byte) 0xd2, (byte) 0xbb, (byte) 0xb5, (byte) (byte) 0xe3, 0x20, (byte) 0xb6, (byte) (byte) 0xe0, (byte) 0xbc, (byte) 0xd3, (byte) 0xc3, (byte) 0xd7, 0x20, (byte) 0xc3, (byte) 0xbb, (byte) 0xc1, (byte) (byte) 0xe3, (byte) 0xc7, (byte) 0xae, 0x1d, 0x21
+				, 0x00, 0x0a, 0x5b, (byte) 0xb7, (byte) 0xa2, (byte) 0xc6, (byte) 0xb1, 0x5d, (byte) 0xd5, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xc7, (byte) 0xd2, (byte) 0xbb, (byte) 0xb8, (byte) 0xf6, (byte) 0xb7, (byte) 0xa2, (byte) 0xc6, (byte) 0xb1, (byte) 0xcc, (byte) 0xa7
+				, (byte) 0xcd, (byte) 0xb7, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, (byte) 0xb2, (byte) 0xcb, (byte) 0xc3, (byte) 0xfb, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, (byte) 0xca, (byte) 0xfd, (byte) 0xc1, (byte) 0xbf, 0x20, 0x20, (byte) 0xd0, (byte) 0xa1
+				, (byte) 0xbc, (byte) 0xc6, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x31, (byte) 0xba, (byte) 0xc5, (byte) 0xc0, (byte) 0xba, (byte) 0xd7, (byte) 0xd3
+				, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1d, 0x21, 0x01, (byte) 0xb2, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xd4, (byte) 0xc3, (byte) 0xc0
+				, (byte) 0xca, (byte) 0xb3, (byte) 0xd2, (byte) 0xbb, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21
+				, 0x01, 0x20, 0x78, 0x34, 0x1d, 0x21, 0x00, 0x1d, 0x21, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x34
+				, 0x1d, 0x21, 0x00, 0x0a, 0x1d, 0x21, 0x01, (byte) 0xb2, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xd4, (byte) 0xc3, (byte) 0xc0, (byte) 0xca, (byte) 0xb3, (byte) 0xb6, (byte) 0xfe, 0x1d, 0x21, 0x00, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x20, 0x78, 0x36, 0x1d, 0x21, 0x00, 0x1d, 0x21
+				, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x36, 0x1d, 0x21, 0x00, 0x0a, 0x1d, 0x21, 0x01, (byte) 0xb2, (byte) (byte) 0xe2
+				, (byte) 0xca, (byte) 0xd4, (byte) 0xc3, (byte) 0xc0, (byte) 0xca, (byte) 0xb3, (byte) 0xc8, (byte) 0xfd, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x20, 0x78, 0x32, 0x1d, 0x21, 0x00, 0x1d, 0x21, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x1d, 0x21, 0x01, 0x32, 0x1d, 0x21, 0x00, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x32, (byte) 0xba
+				, (byte) 0xc5, (byte) 0xc0, (byte) 0xba, (byte) 0xd7, (byte) 0xd3, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1d, 0x21, 0x01, (byte) 0xb2
+				, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xd4, 0x31, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x20, 0x78, 0x31, 0x1d, 0x21, 0x00, 0x1d, 0x21, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x1d, 0x21, 0x01, 0x31, 0x1d, 0x21, 0x00, 0x0a, 0x1d, 0x21, 0x01, (byte) 0xb2, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xd4, 0x32, 0x1d, 0x21, 0x00, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x20, 0x78, 0x31
+				, 0x1d, 0x21, 0x00, 0x1d, 0x21, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x31, 0x1d, 0x21, 0x00, 0x0a
+				, 0x1d, 0x21, 0x01, (byte) 0xb2, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xd4, 0x33, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x20, 0x78, 0x31, 0x1d, 0x21, 0x00, 0x1d, 0x21, 0x01, 0x1d, 0x21, 0x00
+				, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x32, 0x33, 0x1d, 0x21, 0x00, 0x0a, 0x1d, 0x21, 0x01, 0x28, 0x2b, 0x29, (byte) 0xb2, (byte) (byte) 0xe2, (byte) 0xca
+				, (byte) 0xd4, (byte) 0xd1, (byte) 0xf3, (byte) 0xc6, (byte) 0xf8, (byte) 0xa4, (byte) 0xce, (byte) 0xce, (byte) 0xf7, (byte) 0xca, (byte) 0xbd, (byte) 0xcc, (byte) 0xf0, (byte) 0xb5, (byte) (byte) 0xe3, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x1d, 0x21
+				, 0x01, 0x20, 0x78, 0x31, 0x1d, 0x21, 0x00, 0x1d, 0x21, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x31
+				, 0x1d, 0x21, 0x00, 0x0a, 0x1d, 0x21, 0x01, 0x28, 0x2b, 0x29, (byte) 0xb2, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xd4, (byte) 0xcb, (byte) (byte) 0xe1, (byte) 0xc0, (byte) 0xb1, (byte) 0xc4, (byte) 0xbe, (byte) 0xb6, (byte) 0xfa
+				, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x20, 0x78, 0x31, 0x1d, 0x21, 0x00, 0x1d, 0x21
+				, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x38, 0x1d, 0x21, 0x00, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x33, (byte) 0xba, (byte) 0xc5, (byte) 0xc0, (byte) 0xba, (byte) 0xd7, (byte) 0xd3, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1d, 0x21, 0x01, (byte) 0xb2, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xd4, (byte) 0xb2, (byte) 0xcb, (byte) 0xc6, (byte) 0xb7, (byte) 0xc3, (byte) 0xfb, (byte) 0xd7, (byte) 0xd6, (byte) 0xba, (byte) 0xdc
+				, (byte) 0xb3, (byte) 0xa4, (byte) 0xba, (byte) 0xdc, (byte) 0xb3, (byte) 0xa4, (byte) 0xba, (byte) 0xdc, (byte) 0xb3, (byte) 0xa4, (byte) 0xba, (byte) 0xdc, (byte) 0xb3, (byte) 0xa4, (byte) 0xba, (byte) 0xdc, (byte) 0xb3, (byte) 0xa4, 0x1d, 0x21, 0x00, 0x0a
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x1d, 0x21, 0x01, 0x20, 0x78, 0x31, 0x1d, 0x21, 0x00, 0x1d, 0x21, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01
+				, 0x33, 0x30, 0x30, 0x1d, 0x21, 0x00, 0x0a, 0x1d, 0x21, 0x01, (byte) 0xb2, (byte) (byte) 0xe2, (byte) 0xca, (byte) 0xd4, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20
+				, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x20, 0x78, 0x31, 0x1d, 0x21
+				, 0x00, 0x1d, 0x21, 0x01, 0x1d, 0x21, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1d, 0x21, 0x01, 0x31, 0x1d, 0x21, 0x00, 0x0a, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, (byte) 0xc6, (byte) (byte) 0xe4, (byte) 0xcb, (byte) 0xfb, (byte) 0xb7, (byte) 0xd1, (byte) 0xd3, (byte) 0xc3, 0x20, 0x2d, 0x2d, 0x2d
+				, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1d, 0x21, 0x01, (byte) 0xc5, (byte) (byte) 0xe4, (byte) 0xcb, (byte) 0xcd, (byte) 0xb7, (byte) 0xd1, 0x1d, 0x21, 0x00, 0x20
+				, 0x20, 0x20, 0x20, 0x20
+		};
+		return rv;
+	}
+
+	/**
+	 * 口碑小票(KouBei ticket for ESC cmd)
+	 */
+	public static byte[] getKoubeiData() {
+		byte[] rv = new byte[]{
+				0x1b, 0x40, 0x1b, 0x61, 0x01, 0x1d, 0x21, 0x11, 0x23, 0x34, (byte) 0xbf, (byte) 0xda, (byte) 0xb1, (byte) 0xae, (byte) 0xcd, (byte) 0xe2,
+				(byte) 0xc2, (byte) 0xf4, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x01, 0x1d, 0x21, 0x11, 0x0a, 0x1b, 0x40, 0x1b, 0x61,
+				0x01, (byte) 0xb7, (byte) 0xeb, (byte) 0xbc, (byte) 0xc7, (byte) 0xbb, (byte) 0xc6, (byte) 0xec, (byte) 0xcb, (byte) 0xbc, (byte) 0xa6, (byte) 0xc3, (byte) 0xd7, (byte) 0xb7, (byte) 0xb9, 0x0a,
+				0x1b, 0x40, 0x1b, 0x61, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
+				0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
+				0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x11, 0x31, 0x37,
+				0x3a, 0x32, 0x30, 0x20, (byte) 0xbe, (byte) 0xa1, (byte) 0xbf, (byte) 0xec, (byte) 0xcb, (byte) 0xcd, (byte) 0xb4, (byte) 0xef, 0x0a, 0x1b, 0x40, 0x1b,
+				0x61, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x11, 0x31, 0x38, 0x36, 0x31, 0x30, 0x38,
+				0x35, 0x38, 0x33, 0x33, 0x37, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x01, (byte) 0xce, (byte) 0xa4, (byte) 0xd0, (byte) 0xa1, (byte) 0xb1,
+				(byte) 0xa6, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x11, (byte) 0xb4, (byte) 0xb4, (byte) 0xd6, (byte) 0xc7, (byte) 0xcc, (byte) 0xec,
+				(byte) 0xb5, (byte) 0xd8, (byte) 0xb9, (byte) 0xe3, (byte) 0xb3, (byte) 0xa1, 0x37, (byte) 0xba, (byte) 0xc5, (byte) 0xc2, (byte) 0xa5, 0x28, 0x36, 0x30, 0x35, (byte) 0xca,
+				(byte) 0xd2, 0x29, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, 0x1d, 0x21, 0x01,
+				(byte) 0xcf, (byte) 0xc2, (byte) 0xb5, (byte) 0xa5, (byte) 0xa3, (byte) 0xba, 0x31, 0x36, 0x3a, 0x33, 0x35, 0x0a, 0x1b, 0x40, 0x1b, 0x61,
+				0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
+				0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
+				0x2a, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, (byte) 0xb2, (byte) 0xcb, (byte) 0xc6, (byte) 0xb7, 0x20, 0x20, 0x20, 0x20, 0x20,
+				0x20, 0x20, 0x20, 0x20, 0x20, 0x1b, 0x61, 0x00, (byte) 0xca, (byte) 0xfd, (byte) 0xc1, (byte) 0xbf, 0x1b, 0x61, 0x00, 0x20,
+				0x20, (byte) 0xb5, (byte) 0xa5, (byte) 0xbc, (byte) 0xdb, 0x1b, 0x61, 0x00, 0x20, 0x20, (byte) 0xbd, (byte) 0xf0, (byte) 0xb6, (byte) 0xee, 0x0a, 0x1b,
+				0x40, 0x1b, 0x61, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x2d, 0x2d, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, (byte) 0xbb, (byte) 0xc6, (byte) 0xec, (byte) 0xcb, (byte) 0xce, (byte) 0xe5, (byte) 0xbb,
+				(byte) 0xa8, (byte) 0xc8, (byte) 0xe2, (byte) 0xb7, (byte) 0xb9, (byte) 0xa3, (byte) 0xa8, (byte) 0xb4, (byte) 0xf3, (byte) 0xa3, (byte) 0xa9, 0x28, (byte) 0xb2, (byte) 0xbb, (byte) 0xc0, (byte) 0xb1,
+				0x29, 0x0a, 0x1b, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+				0x20, 0x20, 0x1b, 0x61, 0x00, 0x20, 0x31, 0x20, 0x20, 0x1b, 0x61, 0x00, 0x20, 0x20, 0x20, 0x20,
+				0x32, 0x35, 0x1b, 0x61, 0x00, 0x20, 0x20, 0x20, 0x20, 0x32, 0x35, 0x0a, 0x1b, 0x40, 0x1b, 0x61,
+				0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, (byte) 0xc5, (byte) 0xe4, (byte) 0xcb, (byte) 0xcd, (byte) 0xb7, (byte) 0xd1, 0x20, 0x20, 0x20, 0x20,
+				0x20, 0x20, 0x20, 0x20, 0x1b, 0x61, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+				0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x32, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x00, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+				0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x1b, 0x40, 0x1b,
+				0x61, 0x00, 0x1d, 0x21, 0x01, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+				0x20, 0x20, 0x20, 0x20, 0x20, (byte) 0xca, (byte) 0xb5, (byte) 0xb8, (byte) 0xb6, (byte) 0xbd, (byte) 0xf0, (byte) 0xb6, (byte) 0xee, (byte) 0xa3, (byte) 0xba, (byte) 0xa3,
+				(byte) 0xa4, 0x32, 0x37, 0x0a, 0x1b, 0x40, 0x0a, 0x1b, 0x40, 0x0a, 0x1b, 0x40, 0x1b, 0x61, 0x01, 0x1d,
+				0x21, 0x11, (byte) 0xbf, (byte) 0xda, (byte) 0xb1, (byte) 0xae, (byte) 0xcd, (byte) 0xe2, (byte) 0xc2, (byte) 0xf4, 0x0a, 0x1b, 0x40, 0x0a, 0x1b, 0x40,
+				0x1d, 0x56, 0x42, 0x0a, 0x0a
+		};
+		return rv;
+	}
+
+	/**
+	 *	Thermal receipt printer esc cmd set
+	 */
+	public static byte[] customData(){
+		byte[] rv = new byte[]{
+				(byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xBB, (byte) 0xFA, (byte) 0xD7, (byte) 0xD4, (byte) 0xBC, (byte) 0xEC, 0x0A,
+				//打印机自检(printer selfcheck)
+				0x1F, 0X1B, 0x1F, 0x53,
+				//初始化打印机 (printer init)
+				0x1B, 0x40,
+				//分割线---	(Dividing line)
+				0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D, 0x0A,
+				(byte) 0xB8, (byte) 0xC4, (byte) 0xB1, (byte) 0xE4, (byte) 0xD7, (byte) 0xD6, (byte) 0xBC, (byte) 0xE4, (byte) 0xBE, (byte) 0xE0,0x0A,
+				0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,
+				//设置字符右间距 (Set character right margin)
+				0x30,0x2E, 0x30, 0x3A,(byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, 0x0A,
+				0x30,0x2E, 0x35, 0x3A, 0x1B, 0x20, 0x0C,(byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, 0x0A,
+				0x1B, 0x20, 0x00,
+				0x31,0x2E, 0x30, 0x3A, 0x1B, 0x20, 0x18, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, 0x0A,
+				0x1B, 0x20, 0x00,
+				0x32,0x2E, 0x30, 0x3A, 0x1B, 0x20, 0x30, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, (byte) 0xB2, (byte) 0xE2, (byte) 0xCA, (byte) 0xD4, 0x0A,
+				0x1B, 0x20, 0x00,
+				//分割线===	(Dividing line)
+				0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D, 0x0A,
+				(byte) 0xD7, (byte) 0xD6, (byte) 0xCC, (byte) 0xE5, (byte) 0xD0, (byte) 0xA7, (byte) 0xB9, (byte) 0xFB, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D, 0x0A,
+				//字体效果 商米科技
+				//设置加粗、倍高、倍宽、下划线、反白 (Set bold, double height, double width, underline, highlight)
+				0x1B, 0x21, 0x08, (byte) 0xBC, (byte) 0xD3, (byte) 0xB4, (byte) 0xD6, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x1B, 0x21, 0x00,
+				0x1B, 0x45, 0x01, (byte) 0xBC, (byte) 0xD3, (byte) 0xB4, (byte) 0xD6, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x1B, 0x45, 0x00,
+				0x1B, 0x21, 0x10, (byte) 0xB1, (byte) 0xB6, (byte) 0xB8, (byte) 0xDF, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x1B, 0x21, 0x20, (byte) 0xB1, (byte) 0xB6, (byte) 0xBF, (byte) 0xED, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x1D, 0x21, 0x11, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC,
+				0x1D, 0x21, 0x22, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x1D, 0x21, 0x00,
+				0x1B, 0x21, (byte) 0x80, (byte) 0xCF, (byte) 0xC2, (byte) 0xBB, (byte) 0xAE, (byte) 0xCF, (byte) 0xDF, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x1B, 0x21, 0x00,
+				0x1B, 0x2D, 0x01, (byte) 0xCF, (byte) 0xC2, (byte) 0xBB, (byte) 0xAE, (byte) 0xCF, (byte) 0xDF, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x1B, 0x2D, 0x00,
+				0x1D, 0x42, 0x01,0x1B, 0x21, 0x08, (byte) 0xB7, (byte) 0xB4, (byte) 0xB0, (byte) 0xD7, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC, 0x0A,
+				0x1D, 0x42, 0x00,0x1B, 0x21, 0x00,
+				//分割线***	(Dividing line)
+				0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A, 0x0A,
+				(byte) 0xC5, (byte) 0xC5, (byte) 0xB0, (byte) 0xE6, (byte) 0xCE, (byte) 0xBB, (byte) 0xD6, (byte) 0xC3, 0x0A,
+				0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A, 0x0A,
+				//排版位置
+				//设置绝对位置和设置相对位置	(Absolute and relative positions)
+				(byte) 0xD5, (byte) 0xE2, (byte) 0xBE, (byte) 0xE4, (byte) 0xBB, (byte) 0xB0, (byte) 0xB4, (byte) 0xD3, (byte) 0xD0, (byte) 0xD0, (byte) 0xCA, (byte) 0xD7, (byte) 0xBF, (byte) 0xAA, (byte) 0xCA, (byte) 0xBC, 0x0A,
+				(byte) 0xBE, (byte) 0xF8, (byte) 0xB6, (byte) 0xD4, (byte) 0xCE, (byte) 0xBB, (byte) 0xD6, (byte) 0xC3, 0x1B, 0x24, (byte) 0xC0, 0x00, (byte) 0xC6, (byte) 0xAB, (byte) 0xD2, (byte) 0xC6, 0x38, (byte) 0xB8, (byte) 0xF6, (byte) 0xD7, (byte) 0xD6, 0x0A,
+				(byte) 0xCF, (byte) 0xE0, (byte) 0xB6, (byte) 0xD4, (byte) 0xCE, (byte) 0xBB, (byte) 0xD6, (byte) 0xC3, 0x1B, 0x5C, 0x30, 0x00, (byte) 0xC6, (byte) 0xAB, (byte) 0xD2, (byte) 0xC6, 0x32, (byte) 0xB8, (byte) 0xF6, (byte) 0xD7, (byte) 0xD6, 0x0A,
+				//设置对齐方式	(align)
+				(byte) 0xBE, (byte) 0xD3, (byte) 0xD7, (byte) 0xF3, 0x0A,
+				0x1B, 0x61, 0x01, (byte) 0xBE, (byte) 0xD3, (byte) 0xD6, (byte) 0xD0, 0x0A,
+				0x1B, 0x61, 0x02, (byte) 0xBE, (byte) 0xD3, (byte) 0xD3, (byte) 0xD2, 0x0A,
+				0x1B, 0x61, 0x00,
+				//设置左边距 (Left margin)
+				0x1D, 0x4C, 0x30, 0x00,
+				(byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD7, (byte) 0xF3, (byte) 0xB1, (byte) 0xDF, (byte) 0xBE, (byte) 0xE0, 0x34, 0x38, (byte) 0xCF, (byte) 0xF1, (byte) 0xCB, (byte) 0xD8, 0x0A,
+				//设置打印区域宽度	(Printing area width)
+				0x1D, 0x57, (byte) 0xF0, 0x00,
+				(byte) 0xB8, (byte) 0xC4, (byte) 0xB1, (byte) 0xE4, (byte) 0xBF, (byte) 0xC9, (byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xC7, (byte) 0xF8, (byte) 0xD3, (byte) 0xF2, (byte) 0xCE, (byte) 0xAA, 0x32, 0x34, 0x30, (byte) 0xCF, (byte) 0xF1, (byte) 0xCB, (byte) 0xD8, 0x0A,
+				//设置左边距(Left margin)
+				0x1D, 0x4C, 0x60, 0x00,
+				(byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD7, (byte) 0xF3, (byte) 0xB1, (byte) 0xDF, (byte) 0xBE, (byte) 0xE0, 0x39, 0x36, (byte) 0xCF, (byte) 0xF1, (byte) 0xCB, (byte) 0xD8, 0x0A,
+				//设置打印区域宽度	(Printing area width)
+				0x1D, 0x57, (byte) 0x78, 0x00,
+				(byte) 0xB8, (byte) 0xC4, (byte) 0xB1, (byte) 0xE4, (byte) 0xBF, (byte) 0xC9, (byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xC7, (byte) 0xF8, (byte) 0xD3, (byte) 0xF2, (byte) 0xCE, (byte) 0xAA, 0x31, 0x32, 0x30, (byte) 0xCF, (byte) 0xF1, (byte) 0xCB, (byte) 0xD8, 0x0A,
+				0x1D, 0x4C, 0x00, 0x00,
+				0x1D, 0x57, (byte) 0x80, 0x01,
+				//水平制表符-跳格
+				(byte) 0xC4, (byte) 0xAC, 0x09, (byte) 0xC8, (byte) 0xCF, 0x09, (byte) 0xCC, (byte) 0xF8, 0x09, (byte) 0xB8, (byte) 0xF1, 0x09, 0x0A,
+				0x1B, 0x44, 0x01, 0x02, 0x04, 0x08, 0x0A, 0x00,
+				(byte) 0xD7, (byte) 0xD4, 0x09, (byte) 0xB6, (byte) 0xA8, 0x09, (byte) 0xD2, (byte) 0xE5, 0x09, (byte) 0xCC, (byte) 0xF8, 0x09, (byte) 0xB8, (byte) 0xF1, 0x09, 0x0A,
+				//设置行高 (line height)
+				0x1B, 0x33, 0x60, (byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD0, (byte) 0xD0, (byte) 0xB8, (byte) 0xDF, 0x3A, 0x39, 0x36, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,
+				0x1B, 0x33, 0x40, (byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD0, (byte) 0xD0, (byte) 0xB8, (byte) 0xDF, 0x3A, 0x36, 0x34, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,
+				0x1B, 0x33, 0x00, (byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, (byte) 0xD0, (byte) 0xD0, (byte) 0xB8, (byte) 0xDF, 0x3A, 0x30, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,
+				0x1B, 0x32, (byte) 0xC4, (byte) 0xAC, (byte) 0xC8, (byte) 0xCF, (byte) 0xD0, (byte) 0xD0, (byte) 0xB8, (byte) 0xDF, 0x0A,
+				//分割线--- (Dividing line)
+				0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D, 0x0A,
+				(byte) 0xD6, (byte) 0xAE, (byte) 0xBA, (byte) 0xF3, (byte) 0xBD, (byte) 0xAB, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x0A,
+				0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D, 0x0A,
+				//打印并走纸 (printing and feed paper)
+				0x1B, 0x4A, 0x40, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x36, 0x34, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,
+				0x1B, 0x4A, 0x60, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x39, 0x36, (byte) 0xB5, (byte) 0xE3, (byte) 0xD0, (byte) 0xD0, 0x0A,
+				0x1B, 0x64, 0x0A, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x31, 0x30, (byte) 0xD0, (byte) 0xD0, 0x0A,
+				0x1B, 0x64, 0x01, (byte) 0xD7, (byte) 0xDF, (byte) 0xD6, (byte) 0xBD, 0x31, (byte) 0xD0, (byte) 0xD0, 0x0A,
+				//分割线===(Dividing line)
+				0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D, 0x0A,
+				(byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xCC, (byte) 0xF5, (byte) 0xC2, (byte) 0xEB, 0x0A,
+				0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D, 0x0A,
+				//打印条码	(barcode printing)
+				0x1D, 0x48, 0x02,
+				//upca
+				0x1B, 0x61, 0x00, 0x1D, 0x68, 0x20, 0x1D, 0x77, 0x02,
+				0x1D, 0x6B, 0x41, 0x0c, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x0A,
+				0x1D, 0x6B, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x00, 0x0A,
+				//upce
+				0x1B, 0x61, 0x01, 0x1D, 0x68, 0x40, 0x1D, 0x77, 0x04,
+				0x1D, 0x6B, 0x42, 0x08, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x35, 0x0A,
+				0x1D, 0x6B, 0x01, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x35, 0x00, 0x0A,
+				//ean13
+				0x1B, 0x61, 0x02, 0x1D, 0x68, 0x60, 0x1D, 0x77, 0x02,
+				0x1D, 0x6B, 0x43, 0x0D, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x0A,
+				0x1D, 0x6B, 0x02, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x00, 0x0A,
+				//ean8
+				0x1B, 0x61, 0x00, 0x1D, 0x68, (byte) 0x80, 0x1D, 0x77, 0x05,
+				0x1D, 0x6B, 0x44, 0x08, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x35, 0x0A,
+				0x1D, 0x6B, 0x03, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x35, 0x00, 0x0A,
+				//code39
+				0x1B, 0x61, 0x01, 0x1D, 0x68, (byte) 0xA0, 0x1D, 0x77, 0x02,
+				0x1D, 0x6B, 0x45, 0x0A, 0x33, 0x36, 0x39, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x25, 0x24, 0x0A,
+				0x1D, 0x6B, 0x04, 0x33, 0x36, 0x39, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x25, 0x24, 0x00, 0x0A,
+				//itf
+				0x1B, 0x61, 0x02, 0x1D, 0x68, (byte) 0xC0, 0x1D, 0x77, 0x03,
+				0x1D, 0x6B, 0x46, 0x0C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x0A,
+				0x1D, 0x6B, 0x05, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x00, 0x0A,
+				//codebar
+				0x1B, 0x61, 0x00, 0x1D, 0x68, (byte) 0xE0, 0x1D, 0x77, 0x03,
+				0x1D, 0x6B, 0x47, 0x0A, 0x41, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x41, 0x0A,
+				//0x1D, 0x6B, 0x06, 0x41, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x41, 0x00, 0x0A,
+				//code93
+				0x1B, 0x61, 0x01, 0x1D, 0x68, (byte) 0xFF, 0x1D, 0x77, 0x02,
+				0x1D, 0x6B, 0x48, 0x0C, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x0A,
+				//code128
+				0x1B, 0x61, 0x00, 0x1D, 0x68, (byte) 0xB0, 0x1D, 0x77, 0x02,
+				0x1D, 0x6B, 0x49, 0x0A, 0x7B, 0x41, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x30, 0x31, 0x32, 0x0A,
+				0x1D, 0x6B, 0x49, 0x0C, 0x7B, 0x42, 0x53, 0x55, 0x4E, 0x4D, 0x49, 0x73, 0x75, 0x6E, 0x6D, 0x69, 0x0A,
+				0x1D, 0x6B, 0x49, 0x0B, 0x7B, 0x43, 0x01, 0xc, 0x17, 0x22, 0x2d, 0x38, 0x4e, 0x59, 0x5a, 0x0A,
+				//分割线***
+				0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A, 0x0A,
+				(byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xB6, (byte) 0xFE, (byte) 0xCE, (byte) 0xAC, (byte) 0xC2, (byte) 0xEB, 0x0A,
+				0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A,0x2A, 0x2A, 0x2A, 0x2A, 0x0A,
+				//打印二维码	(qrcode printing)
+				0x1B, 0x61, 0x01,
+				0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x43, 0x09,
+				0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x45, 0x32,
+				0x1D, 0x28, 0x6B, 0x0B, 0x00, 0x31, 0x50, 0x30, (byte) 0xC9, (byte) 0xCC, (byte) 0xC3, (byte) 0xD7, (byte) 0xBF, (byte) 0xC6, (byte) 0xBC, (byte) 0xBC,
+				0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x51, 0x30, 0x0A,
+				0x1B, 0x61, 0x00,
+				//分割线---	  (之后将实现打印光栅位图的方法,再次之前使用1b 61 01 居中)
+				0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D, 0x0A,
+				(byte) 0xB4, (byte) 0xF2, (byte) 0xD3, (byte) 0xA1, (byte) 0xB9, (byte) 0xE2, (byte) 0xD5, (byte) 0xA4, (byte) 0xCD, (byte) 0xBC, (byte) 0xCF, (byte) 0xF1, 0x0A,
+				0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, 0x2D,0x2D,0x2D,0x2D,0x2D, 0x0A,
+				0x1B, 0x61, 0x01,
+		};
+		return rv;
+	}
+
+	//部分字符打印的分割线标志
+	public static byte[] wordData(){
+		byte rv[] = new byte[]{
+				//分割线===
+				0x1B, 0x61, 0x00,
+				0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D, 0x0A,
+				(byte) 0xD7, (byte) 0xD6, (byte) 0xB7, (byte) 0xFB, (byte) 0xBC, (byte) 0xAF, (byte) 0xC9, (byte) 0xE8, (byte) 0xD6, (byte) 0xC3, 0x0A,
+				0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D,0x3D, 0x3D, 0x3D, 0x3D, 0x0A,
+				0x1C, 0x26, 0x1C, 0x43, 0x00,
+		};
+		return rv;
+	}
+}
+
+
+

+ 419 - 0
app/src/main/java/com/hw/nativeapp/utils/sunmi/ESCUtil.java

@@ -0,0 +1,419 @@
+package com.hw.nativeapp.utils.sunmi;
+
+import android.graphics.Bitmap;
+
+import java.io.ByteArrayOutputStream;
+
+//常用指令封装
+public class ESCUtil {
+
+	public static final byte ESC = 0x1B;// Escape
+	public static final byte FS =  0x1C;// Text delimiter
+	public static final byte GS =  0x1D;// Group separator
+	public static final byte DLE = 0x10;// data link escape
+	public static final byte EOT = 0x04;// End of transmission
+	public static final byte ENQ = 0x05;// Enquiry character
+	public static final byte SP =  0x20;// Spaces
+	public static final byte HT =  0x09;// Horizontal list
+	public static final byte LF =  0x0A;//Print and wrap (horizontal orientation)
+	public static final byte CR =  0x0D;// Home key
+	public static final byte FF =  0x0C;// Carriage control (print and return to the standard mode (in page mode))
+	public static final byte CAN = 0x18;// Canceled (cancel print data in page mode)
+
+	//初始化打印机
+	public static byte[] init_printer() {
+		byte[] result = new byte[2];
+		result[0] = ESC;
+		result[1] = 0x40;
+		return result;
+	}
+
+	//打印浓度指令
+	public static byte[] setPrinterDarkness(int value){
+		byte[] result = new byte[9];
+		result[0] = GS;
+		result[1] = 40;
+		result[2] = 69;
+		result[3] = 4;
+		result[4] = 0;
+		result[5] = 5;
+		result[6] = 5;
+		result[7] = (byte) (value >> 8);
+		result[8] = (byte) value;
+		return result;
+	}
+
+	/**
+	 * 打印单个二维码 sunmi自定义指令
+	 * @param code:			二维码数据
+	 * @param modulesize:	二维码块大小(单位:点, 取值 1 至 16 )
+	 * @param errorlevel:	二维码纠错等级(0 至 3)
+	 *                0 -- 纠错级别L ( 7%)
+	 *                1 -- 纠错级别M (15%)
+	 *                2 -- 纠错级别Q (25%)
+	 *                3 -- 纠错级别H (30%)
+	 */
+	public static byte[] getPrintQRCode(String code, int modulesize, int errorlevel){
+		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+		try{
+			buffer.write(setQRCodeSize(modulesize));
+			buffer.write(setQRCodeErrorLevel(errorlevel));
+			buffer.write(getQCodeBytes(code));
+			buffer.write(getBytesForPrintQRCode());
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+		return buffer.toByteArray();
+	}
+
+	/**
+	 * 使用光栅位图打印两个二维码
+	 * 将多个二维码转换为光栅位图打印
+	 */
+	public static byte[] getPrintDoubleQRCode(String qr1, String qr2, int size){
+		byte[] bytes1  = new byte[4];
+		bytes1[0] = GS;
+		bytes1[1] = 0x76;
+		bytes1[2] = 0x30;
+		bytes1[3] = 0x00;
+
+		byte[] bytes2 = BytesUtil.getZXingQRCode(qr1, qr2, size);
+		return BytesUtil.byteMerger(bytes1, bytes2);
+	}
+
+	/**
+	 * 打印一维条形码
+	 */
+	public static byte[] getPrintBarCode(String data, int symbology, int height, int width, int textposition){
+		if(symbology < 0 || symbology > 10){
+			return new byte[]{LF};
+		}
+
+		if(width < 2 || width > 6){
+			width = 2;
+		}
+
+		if(textposition <0 || textposition > 3){
+			textposition = 0;
+		}
+
+		if(height < 1 || height>255){
+			height = 162;
+		}
+
+		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+		try{
+			buffer.write(new byte[]{0x1D,0x66,0x01,0x1D,0x48,(byte)textposition,
+					0x1D,0x77,(byte)width,0x1D,0x68,(byte)height,0x0A});
+
+			byte[] barcode;
+			if(symbology == 10){
+				barcode = BytesUtil.getBytesFromDecString(data);
+			}else{
+				barcode = data.getBytes("GB18030");
+			}
+
+
+			if(symbology > 7){
+				buffer.write(new byte[]{0x1D,0x6B,0x49,(byte)(barcode.length+2),0x7B, (byte) (0x41+symbology-8)});
+			}else{
+				buffer.write(new byte[]{0x1D,0x6B,(byte)(symbology + 0x41),(byte)barcode.length});
+			}
+			buffer.write(barcode);
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+		return buffer.toByteArray();
+	}
+
+	//光栅位图打印
+	public static byte[] printBitmap(Bitmap bitmap){
+		byte[] bytes1  = new byte[4];
+		bytes1[0] = GS;
+		bytes1[1] = 0x76;
+		bytes1[2] = 0x30;
+		bytes1[3] = 0x00;
+
+		byte[] bytes2 = BytesUtil.getBytesFromBitMap(bitmap);
+		return BytesUtil.byteMerger(bytes1, bytes2);
+	}
+
+	//光栅位图打印 设置mode
+	public static byte[] printBitmap(Bitmap bitmap, int mode){
+		byte[] bytes1  = new byte[4];
+		bytes1[0] = GS;
+		bytes1[1] = 0x76;
+		bytes1[2] = 0x30;
+		bytes1[3] = (byte) mode;
+
+		byte[] bytes2 = BytesUtil.getBytesFromBitMap(bitmap);
+		return BytesUtil.byteMerger(bytes1, bytes2);
+	}
+
+	//光栅位图打印
+	public static byte[] printBitmap(byte[] bytes){
+		byte[] bytes1  = new byte[4];
+		bytes1[0] = GS;
+		bytes1[1] = 0x76;
+		bytes1[2] = 0x30;
+		bytes1[3] = 0x00;
+
+		return BytesUtil.byteMerger(bytes1, bytes);
+	}
+
+	/*
+	*	选择位图指令 设置mode
+	*	需要设置1B 33 00将行间距设为0
+	 */
+	public static byte[] selectBitmap(Bitmap bitmap, int mode){
+		return BytesUtil.byteMerger(BytesUtil.byteMerger(new byte[]{0x1B, 0x33, 0x00}, BytesUtil.getBytesFromBitMap(bitmap, mode)), new byte[]{0x0A, 0x1B, 0x32});
+	}
+
+	/**
+	 * 跳指定行数
+	 */
+    public static byte[] nextLine(int lineNum) {
+        byte[] result = new byte[lineNum];
+        for (int i = 0; i < lineNum; i++) {
+            result[i] = LF;
+        }
+
+        return result;
+    }
+
+    // ------------------------style set-----------------------------
+	//设置默认行间距
+	public static byte[] setDefaultLineSpace(){
+		return new byte[]{0x1B, 0x32};
+	}
+
+	//设置行间距
+	public static byte[] setLineSpace(int height){
+    	return new byte[]{0x1B, 0x33, (byte) height};
+	}
+
+	// ------------------------underline-----------------------------
+	//设置下划线1点
+	public static byte[] underlineWithOneDotWidthOn() {
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 45;
+		result[2] = 1;
+		return result;
+	}
+
+	//设置下划线2点
+	public static byte[] underlineWithTwoDotWidthOn() {
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 45;
+		result[2] = 2;
+		return result;
+	}
+
+	//取消下划线
+	public static byte[] underlineOff() {
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 45;
+		result[2] = 0;
+		return result;
+	}
+
+	// ------------------------bold-----------------------------
+	/**
+	 * 字体加粗
+	 */
+	public static byte[] boldOn() {
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 69;
+		result[2] = 0xF;
+		return result;
+	}
+
+	/**
+	 * 取消字体加粗
+	 */
+	public static byte[] boldOff() {
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 69;
+		result[2] = 0;
+		return result;
+	}
+
+	// ------------------------character-----------------------------
+	/*
+	*单字节模式开启
+	 */
+	public static byte[] singleByte(){
+		byte[] result = new byte[2];
+		result[0] = FS;
+		result[1] = 0x2E;
+		return result;
+	}
+
+	/*
+	*单字节模式关闭
+ 	*/
+	public static byte[] singleByteOff(){
+		byte[] result = new byte[2];
+		result[0] = FS;
+		result[1] = 0x26;
+		return result;
+	}
+
+	/**
+	 * 设置单字节字符集
+	 */
+	public static byte[] setCodeSystemSingle(byte charset){
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 0x74;
+		result[2] = charset;
+		return result;
+	}
+
+	/**
+	 * 设置多字节字符集
+	 */
+	public static byte[] setCodeSystem(byte charset){
+		byte[] result = new byte[3];
+		result[0] = FS;
+		result[1] = 0x43;
+		result[2] = charset;
+		return result;
+	}
+
+	// ------------------------Align-----------------------------
+
+	/**
+	 * 居左
+	 */
+	public static byte[] alignLeft() {
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 97;
+		result[2] = 0;
+		return result;
+	}
+
+	/**
+	 * 居中对齐
+	 */
+	public static byte[] alignCenter() {
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 97;
+		result[2] = 1;
+		return result;
+	}
+
+	/**
+	 * 居右
+	 */
+	public static byte[] alignRight() {
+		byte[] result = new byte[3];
+		result[0] = ESC;
+		result[1] = 97;
+		result[2] = 2;
+		return result;
+	}
+
+	//切刀
+	public static byte[] cutter() {
+		byte[] data = new byte[]{0x1d, 0x56, 0x01};
+		return data;
+	}
+
+	/**
+	 * 	标签or黑标模式定位
+	 * 	由于兼容性原因只有手持机可以支持SDK,其他设备必须使用指令方法
+	 * 	For compatibility reasons, only the handheld can support the SDK, other devices must use the command method
+	 */
+	public static byte[] labellocate() {
+		return new byte[]{0x1C, 0x28, 0x4C, 0x02, 0x00, 0x43, 0x31};
+	}
+
+	/**
+	 * 标签or黑标模式送出
+	 * 由于兼容性原因只有手持机可以支持SDK,其他设备必须使用指令方法
+	 * For compatibility reasons, only the handheld can support the SDK, other devices must use the command method
+	 */
+	public static byte[] labelout(){
+		return new byte[]{0x1C, 0x28, 0x4C, 0x02, 0x00, 0x42, 0x31};
+	}
+
+
+
+	////////////////////////////////////////////////////////////////////////////////////
+	//////////////////////////          private                /////////////////////////
+	////////////////////////////////////////////////////////////////////////////////////
+	private static byte[] setQRCodeSize(int modulesize){
+		//二维码块大小设置指令
+		byte[] dtmp = new byte[8];
+		dtmp[0] = GS;
+		dtmp[1] = 0x28;
+		dtmp[2] = 0x6B;
+		dtmp[3] = 0x03;
+		dtmp[4] = 0x00;
+		dtmp[5] = 0x31;
+		dtmp[6] = 0x43;
+		dtmp[7] = (byte)modulesize;
+		return dtmp;
+	}
+
+	private static byte[] setQRCodeErrorLevel(int errorlevel){
+		//二维码纠错等级设置指令
+		byte[] dtmp = new byte[8];
+		dtmp[0] = GS;
+		dtmp[1] = 0x28;
+		dtmp[2] = 0x6B;
+		dtmp[3] = 0x03;
+		dtmp[4] = 0x00;
+		dtmp[5] = 0x31;
+		dtmp[6] = 0x45;
+		dtmp[7] = (byte)(48+errorlevel);
+		return dtmp;
+	}
+
+	//打印已存入数据的二维码
+	private static byte[] getBytesForPrintQRCode(){
+		byte[] dtmp = new byte[9];
+		dtmp[0] = 0x1D;
+		dtmp[1] = 0x28;
+		dtmp[2] = 0x6B;
+		dtmp[3] = 0x03;
+		dtmp[4] = 0x00;
+		dtmp[5] = 0x31;
+		dtmp[6] = 0x51;
+		dtmp[7] = 0x30;
+		dtmp[8] = 0x0A;
+		return dtmp;
+	}
+
+	private static byte[] getQCodeBytes(String code) {
+		//二维码存入指令
+		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+		try {
+			byte[] d = code.getBytes("GB18030");
+			int len = d.length + 3;
+			if (len > 7092) len = 7092;
+			buffer.write((byte) 0x1D);
+			buffer.write((byte) 0x28);
+			buffer.write((byte) 0x6B);
+			buffer.write((byte) len);
+			buffer.write((byte) (len >> 8));
+			buffer.write((byte) 0x31);
+			buffer.write((byte) 0x50);
+			buffer.write((byte) 0x30);
+			for (int i = 0; i < d.length && i < len; i++) {
+				buffer.write(d[i]);
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return buffer.toByteArray();
+	}
+}

+ 791 - 0
app/src/main/java/com/hw/nativeapp/utils/sunmi/SunmiPrintHelper.java

@@ -0,0 +1,791 @@
+package com.hw.nativeapp.utils.sunmi;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.RemoteException;
+import android.widget.Toast;
+
+
+import com.hw.nativeapp.R;
+import com.sunmi.peripheral.printer.ExceptionConst;
+import com.sunmi.peripheral.printer.InnerLcdCallback;
+import com.sunmi.peripheral.printer.InnerPrinterCallback;
+import com.sunmi.peripheral.printer.InnerPrinterException;
+import com.sunmi.peripheral.printer.InnerPrinterManager;
+import com.sunmi.peripheral.printer.InnerResultCallback;
+import com.sunmi.peripheral.printer.SunmiPrinterService;
+import com.sunmi.peripheral.printer.WoyouConsts;
+
+/**
+ * <pre>
+ *      This class is used to demonstrate various printing effects
+ *      Developers need to repackage themselves, for details please refer to
+ *      http://sunmi-ota.oss-cn-hangzhou.aliyuncs.com/DOC/resource/re_cn/Sunmiprinter%E5%BC%80%E5%8F%91%E8%80%85%E6%96%87%E6%A1%A31.1.191128.pdf
+ *  </pre>
+ *
+ * @author kaltin
+ * @since create at 2020-02-14
+ */
+public class SunmiPrintHelper {
+
+    public static int NoSunmiPrinter = 0x00000000;
+    public static int CheckSunmiPrinter = 0x00000001;
+    public static int FoundSunmiPrinter = 0x00000002;
+    public static int LostSunmiPrinter = 0x00000003;
+
+    /**
+     *  sunmiPrinter means checking the printer connection status
+     */
+    public int sunmiPrinter = CheckSunmiPrinter;
+    /**
+     *  SunmiPrinterService for API
+     */
+    private SunmiPrinterService sunmiPrinterService;
+
+    private static SunmiPrintHelper helper = new SunmiPrintHelper();
+
+    private SunmiPrintHelper() {}
+
+    public static SunmiPrintHelper getInstance() {
+        return helper;
+    }
+
+    private InnerPrinterCallback innerPrinterCallback = new InnerPrinterCallback() {
+        @Override
+        protected void onConnected(SunmiPrinterService service) {
+            sunmiPrinterService = service;
+            checkSunmiPrinterService(service);
+        }
+
+        @Override
+        protected void onDisconnected() {
+            sunmiPrinterService = null;
+            sunmiPrinter = LostSunmiPrinter;
+        }
+    };
+
+    /**
+     * init sunmi print service
+     */
+    public void initSunmiPrinterService(Context context){
+        try {
+            boolean ret =  InnerPrinterManager.getInstance().bindService(context,
+                    innerPrinterCallback);
+            if(!ret){
+                sunmiPrinter = NoSunmiPrinter;
+            }
+        } catch (InnerPrinterException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *  deInit sunmi print service
+     */
+    public void deInitSunmiPrinterService(Context context){
+        try {
+            if(sunmiPrinterService != null){
+                InnerPrinterManager.getInstance().unBindService(context, innerPrinterCallback);
+                sunmiPrinterService = null;
+                sunmiPrinter = LostSunmiPrinter;
+            }
+        } catch (InnerPrinterException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Check the printer connection,
+     * like some devices do not have a printer but need to be connected to the cash drawer through a print service
+     */
+    private void checkSunmiPrinterService(SunmiPrinterService service){
+        boolean ret = false;
+        try {
+            ret = InnerPrinterManager.getInstance().hasPrinter(service);
+        } catch (InnerPrinterException e) {
+            e.printStackTrace();
+        }
+        sunmiPrinter = ret?FoundSunmiPrinter:NoSunmiPrinter;
+    }
+
+    /**
+     *  Some conditions can cause interface calls to fail
+     *  For example: the version is too low、device does not support
+     *  You can see {@link ExceptionConst}
+     *  So you have to handle these exceptions
+     */
+    private void handleRemoteException(RemoteException e){
+        //TODO process when get one exception
+    }
+
+    /**
+     * send esc cmd
+     */
+    public void sendRawData(byte[] data) {
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+        try {
+            sunmiPrinterService.sendRAWData(data, null);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     *  Printer cuts paper and throws exception on machines without a cutter
+     */
+    public void cutpaper(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+        try {
+            sunmiPrinterService.cutPaper(null);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     *  Initialize the printer
+     *  All style settings will be restored to default
+     */
+    public void initPrinter(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+        try {
+            sunmiPrinterService.printerInit(null);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     *  paper feed three lines
+     *  Not disabled when line spacing is set to 0
+     */
+    public void print3Line(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.lineWrap(3, null);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     * Get printer serial number
+     */
+    public String getPrinterSerialNo(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return "";
+        }
+        try {
+            return sunmiPrinterService.getPrinterSerialNo();
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+            return "";
+        }
+    }
+
+    /**
+     * Get device model
+     */
+    public String getDeviceModel(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return "";
+        }
+        try {
+            return sunmiPrinterService.getPrinterModal();
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+            return "";
+        }
+    }
+
+    /**
+     * Get firmware version
+     */
+    public String getPrinterVersion(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return "";
+        }
+        try {
+            return sunmiPrinterService.getPrinterVersion();
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+            return "";
+        }
+    }
+
+    /**
+     * Get paper specifications
+     */
+    public String getPrinterPaper(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return "";
+        }
+        try {
+            return sunmiPrinterService.getPrinterPaper() == 1?"58mm":"80mm";
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+            return "";
+        }
+    }
+
+    /**
+     * Get paper specifications
+     */
+    public void getPrinterHead(InnerResultCallback callbcak){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+        try {
+             sunmiPrinterService.getPrinterFactory(callbcak);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     * Get printing distance since boot
+     * Get printing distance through interface callback since 1.0.8(printerlibrary)
+     */
+    public void getPrinterDistance(InnerResultCallback callback){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+        try {
+            sunmiPrinterService.getPrintedLength(callback);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     * Set printer alignment
+     */
+    public void setAlign(int align){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+        try {
+            sunmiPrinterService.setAlignment(align, null);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     *  Due to the distance between the paper hatch and the print head,
+     *  the paper needs to be fed out automatically
+     *  But if the Api does not support it, it will be replaced by printing three lines
+     */
+    public void feedPaper(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.autoOutPaper(null);
+        } catch (RemoteException e) {
+            print3Line();
+        }
+    }
+
+    /**
+     * print text
+     * setPrinterStyle:Api require V4.2.22 or later, So use esc cmd instead when not supported
+     *  More settings reference documentation {@link WoyouConsts}
+     * printTextWithFont:
+     *  Custom fonts require V4.14.0 or later!
+     *  You can put the custom font in the 'assets' directory and Specify the font name parameters
+     *  in the Api.
+     */
+    public void printText(String content, float size, boolean isBold, boolean isUnderLine,
+                          String typeface) {
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            try {
+                sunmiPrinterService.setPrinterStyle(WoyouConsts.ENABLE_BOLD, isBold?
+                        WoyouConsts.ENABLE:WoyouConsts.DISABLE);
+            } catch (RemoteException e) {
+                if (isBold) {
+                    sunmiPrinterService.sendRAWData(ESCUtil.boldOn(), null);
+                } else {
+                    sunmiPrinterService.sendRAWData(ESCUtil.boldOff(), null);
+                }
+            }
+            try {
+                sunmiPrinterService.setPrinterStyle(WoyouConsts.ENABLE_UNDERLINE, isUnderLine?
+                        WoyouConsts.ENABLE:WoyouConsts.DISABLE);
+            } catch (RemoteException e) {
+                if (isUnderLine) {
+                    sunmiPrinterService.sendRAWData(ESCUtil.underlineWithOneDotWidthOn(), null);
+                } else {
+                    sunmiPrinterService.sendRAWData(ESCUtil.underlineOff(), null);
+                }
+            }
+            sunmiPrinterService.printTextWithFont(content, typeface, size, null);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * print Bar Code
+     */
+    public void printBarCode(String data, int symbology, int height, int width, int textposition) {
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.printBarCode(data, symbology, height, width, textposition, null);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * print Qr Code
+     */
+    public void printQr(String data, int modulesize, int errorlevel) {
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.printQRCode(data, modulesize, errorlevel, null);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Print a row of a table
+     */
+    public void printTable(String[] txts, int[] width, int[] align) {
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.printColumnsString(txts, width, align, null);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *  Print pictures and text in the specified orde
+     *  After the picture is printed,
+     *  the line feed output needs to be called,
+     *  otherwise it will be saved in the cache
+     *  In this example, the image will be printed because the print text content is added
+     */
+    public void printBitmap(Bitmap bitmap, int orientation) {
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            if(orientation == 0){
+                sunmiPrinterService.printBitmap(bitmap, null);
+                sunmiPrinterService.printText("横向排列\n", null);
+                sunmiPrinterService.printBitmap(bitmap, null);
+                sunmiPrinterService.printText("横向排列\n", null);
+            }else{
+                sunmiPrinterService.printBitmap(bitmap, null);
+                sunmiPrinterService.printText("\n纵向排列\n", null);
+                sunmiPrinterService.printBitmap(bitmap, null);
+                sunmiPrinterService.printText("\n纵向排列\n", null);
+            }
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Gets whether the current printer is in black mark mode
+     */
+    public boolean isBlackLabelMode(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return false;
+        }
+        try {
+            return sunmiPrinterService.getPrinterMode() == 1;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Gets whether the current printer is in label-printing mode
+     */
+    public boolean isLabelMode(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return false;
+        }
+        try {
+            return sunmiPrinterService.getPrinterMode() == 2;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     *  Transaction printing:
+     *  enter->print->exit(get result) or
+     *  enter->first print->commit(get result)->twice print->commit(get result)->exit(don't care
+     *  result)
+     */
+    public void printTrans(Context context, InnerResultCallback callbcak){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.enterPrinterBuffer(true);
+            printExample(context);
+            sunmiPrinterService.exitPrinterBufferWithCallback(true, callbcak);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *  Open cash box
+     *  This method can be used on Sunmi devices with a cash drawer interface
+     *  If there is no cash box (such as V1、P1) or the call fails, an exception will be thrown
+     *
+     *  Reference to https://docs.sunmi.com/general-function-modules/external-device-debug/cash-box-driver/}
+     */
+    public void openCashBox(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.openDrawer(null);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     * LCD screen control
+     * @param flag 1 —— Initialization
+     *             2 —— Light up screen
+     *             3 —— Extinguish screen
+     *             4 —— Clear screen contents
+     */
+    public void controlLcd(int flag){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.sendLCDCommand(flag);
+        } catch (RemoteException e) {
+            handleRemoteException(e);
+        }
+    }
+
+    /**
+     * Display text SUNMI,font size is 16 and format is fill
+     * sendLCDFillString(txt, size, fill, callback)
+     * Since the screen pixel height is 40, the font should not exceed 40
+     */
+    public void sendTextToLcd(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.sendLCDFillString("SUNMI", 16, true, new InnerLcdCallback() {
+                @Override
+                public void onRunResult(boolean show) throws RemoteException {
+                    //TODO handle result
+                }
+            });
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * Display two lines and one empty line in the middle
+     */
+    public void sendTextsToLcd(){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            String[] texts = {"SUNMI", null, "SUNMI"};
+            int[] align = {2, 1, 2};
+            sunmiPrinterService.sendLCDMultiString(texts, align, new InnerLcdCallback() {
+                @Override
+                public void onRunResult(boolean show) throws RemoteException {
+                    //TODO handle result
+                }
+            });
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * Display one 128x40 pixels and opaque picture
+     */
+    public void sendPicToLcd(Bitmap pic){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return;
+        }
+
+        try {
+            sunmiPrinterService.sendLCDBitmap(pic, new InnerLcdCallback() {
+                @Override
+                public void onRunResult(boolean show) throws RemoteException {
+                    //TODO handle result
+                }
+            });
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     *  Sample print receipt
+     */
+    public void printExample(Context context){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return ;
+        }
+
+        try {
+            int paper = sunmiPrinterService.getPrinterPaper();
+            sunmiPrinterService.printerInit(null);
+            sunmiPrinterService.setAlignment(1, null);
+            sunmiPrinterService.printText("测试样张\n", null);
+//            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.sunmi);
+//            sunmiPrinterService.printBitmap(bitmap, null);
+            sunmiPrinterService.lineWrap(1, null);
+            sunmiPrinterService.setAlignment(0, null);
+            try {
+                sunmiPrinterService.setPrinterStyle(WoyouConsts.SET_LINE_SPACING, 0);
+            } catch (RemoteException e) {
+                sunmiPrinterService.sendRAWData(new byte[]{0x1B, 0x33, 0x00}, null);
+            }
+            sunmiPrinterService.printTextWithFont("说明:这是一个自定义的小票样式例子,开发者可以仿照此进行自己的构建\n",
+                    null, 12, null);
+            if(paper == 1){
+                sunmiPrinterService.printText("--------------------------------\n", null);
+            }else{
+                sunmiPrinterService.printText("------------------------------------------------\n",
+                        null);
+            }
+            try {
+                sunmiPrinterService.setPrinterStyle(WoyouConsts.ENABLE_BOLD, WoyouConsts.ENABLE);
+            } catch (RemoteException e) {
+                sunmiPrinterService.sendRAWData(ESCUtil.boldOn(), null);
+            }
+            String txts[] = new String[]{"商品", "价格"};
+            int width[] = new int[]{1, 1};
+            int align[] = new int[]{0, 2};
+            sunmiPrinterService.printColumnsString(txts, width, align, null);
+            try {
+                sunmiPrinterService.setPrinterStyle(WoyouConsts.ENABLE_BOLD, WoyouConsts.DISABLE);
+            } catch (RemoteException e) {
+                sunmiPrinterService.sendRAWData(ESCUtil.boldOff(), null);
+            }
+            if(paper == 1){
+                sunmiPrinterService.printText("--------------------------------\n", null);
+            }else{
+                sunmiPrinterService.printText("------------------------------------------------\n",
+                        null);
+            }
+            txts[0] = "汉堡";
+            txts[1] = "17¥";
+            sunmiPrinterService.printColumnsString(txts, width, align, null);
+            txts[0] = "可乐";
+            txts[1] = "10¥";
+            sunmiPrinterService.printColumnsString(txts, width, align, null);
+            txts[0] = "薯条";
+            txts[1] = "11¥";
+            sunmiPrinterService.printColumnsString(txts, width, align, null);
+            txts[0] = "炸鸡";
+            txts[1] = "11¥";
+            sunmiPrinterService.printColumnsString(txts, width, align, null);
+            txts[0] = "圣代";
+            txts[1] = "10¥";
+            sunmiPrinterService.printColumnsString(txts, width, align, null);
+            if(paper == 1){
+                sunmiPrinterService.printText("--------------------------------\n", null);
+            }else{
+                sunmiPrinterService.printText("------------------------------------------------\n",
+                        null);
+            }
+            sunmiPrinterService.printTextWithFont("总计:          59¥\b", null, 40, null);
+            sunmiPrinterService.setAlignment(1, null);
+            sunmiPrinterService.printQRCode("谢谢惠顾", 10, 0, null);
+            sunmiPrinterService.setFontSize(36, null);
+            sunmiPrinterService.printText("谢谢惠顾", null);
+            sunmiPrinterService.autoOutPaper(null);
+         } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Used to report the real-time query status of the printer, which can be used before each
+     * printing
+     */
+    public void showPrinterStatus(Context context){
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return ;
+        }
+        String result = "Interface is too low to implement interface";
+        try {
+            int res = sunmiPrinterService.updatePrinterState();
+            switch (res){
+                case 1:
+                    result = "printer is running";
+                    break;
+                case 2:
+                    result = "printer found but still initializing";
+                    break;
+                case 3:
+                    result = "printer hardware interface is abnormal and needs to be reprinted";
+                    break;
+                case 4:
+                    result = "printer is out of paper";
+                    break;
+                case 5:
+                    result = "printer is overheating";
+                    break;
+                case 6:
+                    result = "printer's cover is not closed";
+                    break;
+                case 7:
+                    result = "printer's cutter is abnormal";
+                    break;
+                case 8:
+                    result = "printer's cutter is normal";
+                    break;
+                case 9:
+                    result = "not found black mark paper";
+                    break;
+                case 505:
+                    result = "printer does not exist";
+                    break;
+                default:
+                    break;
+            }
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+        Toast.makeText(context, result, Toast.LENGTH_LONG).show();
+    }
+
+    /**
+     * Demo printing a label
+     * After printing one label, in order to facilitate the user to tear the paper, call
+     * labelOutput to push the label paper out of the paper hatch
+     * 演示打印一张标签
+     * 打印单张标签后为了方便用户撕纸可调用labelOutput,将标签纸推出纸舱口
+     */
+    public void printOneLabel() {
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return ;
+        }
+        try {
+            sunmiPrinterService.labelLocate();
+            printLabelContent();
+            sunmiPrinterService.labelOutput();
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Demo printing multi label
+     *
+     After printing multiple labels, choose whether to push the label paper to the paper hatch according to the needs
+     * 演示打印多张标签
+     * 打印多张标签后根据需求选择是否推出标签纸到纸舱口
+     */
+    public void printMultiLabel(int num) {
+        if(sunmiPrinterService == null){
+            //TODO Service disconnection processing
+            return ;
+        }
+        try {
+            for(int i = 0; i < num; i++){
+                sunmiPrinterService.labelLocate();
+                printLabelContent();
+            }
+            sunmiPrinterService.labelOutput();
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     *  Custom label ticket content
+     *  In the example, not all labels can be applied. In actual use, please pay attention to adapting the size of the label. You can adjust the font size and content position.
+     *  自定义的标签小票内容
+     *  例子中并不能适用所有标签纸,实际使用时注意要自适配标签纸大小,可通过调节字体大小,内容位置等方式
+     */
+    private void printLabelContent() throws RemoteException {
+        sunmiPrinterService.setPrinterStyle(WoyouConsts.ENABLE_BOLD, WoyouConsts.ENABLE);
+        sunmiPrinterService.lineWrap(1, null);
+        sunmiPrinterService.setAlignment(0, null);
+        sunmiPrinterService.printText("商品         豆浆\n", null);
+        sunmiPrinterService.printText("到期时间         12-13  14时\n", null);
+        sunmiPrinterService.printBarCode("{C1234567890123456",  8, 90, 2, 2, null);
+        sunmiPrinterService.lineWrap(1, null);
+    }
+}

+ 22 - 3
app/src/main/res/layout/activity_main.xml

@@ -1,20 +1,39 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@mipmap/page_bj"
+    android:orientation="vertical"
+    android:gravity="center"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="center"
+        android:layout_gravity="center|top"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/img_setting"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="10sp"
+            android:layout_gravity="center|right"
+            android:src="@mipmap/img_setting"/>
+
+    </LinearLayout>
+
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
         android:orientation="vertical">
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="30sp"
-            android:layout_marginTop="240dp"
             android:layout_marginRight="30sp"
             android:gravity="center"
             android:orientation="vertical">
@@ -67,4 +86,4 @@
             </LinearLayout>
         </LinearLayout>
     </LinearLayout>
-</RelativeLayout>
+</LinearLayout>

+ 241 - 0
app/src/main/res/layout/activity_setting.xml

@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#F4F4F4"
+    android:orientation="vertical">
+<LinearLayout
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:layout_margin="@dimen/dp_10"
+    android:background="@drawable/bg_corners_01">
+    <LinearLayout
+        android:id="@+id/btn_updatepassword"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="@dimen/dp_10"
+        android:gravity="center"
+        android:orientation="horizontal">
+
+
+        <ImageView
+            android:id="@+id/imageView5"
+            android:layout_width="30dp"
+            android:layout_height="30dp"
+            app:srcCompat="@mipmap/xiugaimima" />
+
+
+        <TextView
+            android:layout_marginStart="20dp"
+            android:id="@+id/textView19"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="修改密码"
+            android:textColor="#484848"
+            android:textSize="23sp" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+        <ImageView
+
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:background="@mipmap/arrow_right" />
+
+    </LinearLayout>
+    <View
+            android:layout_margin="@dimen/dp_10"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#E9E9E9" />
+
+    <LinearLayout
+        android:id="@+id/btn_print"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="@dimen/dp_10"
+        android:gravity="center"
+        android:background="@drawable/bg_corners_01"
+        android:orientation="horizontal">
+
+
+        <ImageView
+            android:layout_width="30dp"
+            android:layout_height="30dp"
+            app:srcCompat="@mipmap/print" />
+
+
+        <TextView
+            android:layout_marginStart="20dp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="打印走纸"
+            android:textColor="#484848"
+            android:textSize="23sp" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+        <ImageView
+
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:background="@mipmap/arrow_right" />
+
+    </LinearLayout>
+
+
+    <View
+        android:layout_margin="@dimen/dp_10"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#E9E9E9" />
+
+    <LinearLayout
+        android:id="@+id/btn_update"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="@dimen/dp_10"
+        android:gravity="center"
+        android:background="@drawable/bg_corners_01"
+        android:orientation="horizontal">
+
+
+        <ImageView
+            android:layout_width="30dp"
+            android:layout_height="30dp"
+            app:srcCompat="@mipmap/update" />
+
+
+        <TextView
+            android:layout_marginStart="20dp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="版本检测"
+            android:textColor="#484848"
+            android:textSize="23sp" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+        <ImageView
+
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:background="@mipmap/arrow_right" />
+
+    </LinearLayout>
+
+    <View
+        android:layout_margin="@dimen/dp_10"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#E9E9E9" />
+    <LinearLayout
+    android:id="@+id/btn_out"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_margin="@dimen/dp_10"
+    android:gravity="center"
+    android:background="@drawable/bg_corners_01"
+    android:orientation="horizontal">
+
+
+    <ImageView
+        android:layout_width="30dp"
+        android:layout_height="30dp"
+        app:srcCompat="@mipmap/zhuxiao" />
+
+
+    <TextView
+        android:layout_marginStart="20dp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="注销账号"
+        android:textColor="#484848"
+        android:textSize="23sp" />
+
+    <View
+        android:layout_width="0dp"
+        android:layout_height="1dp"
+        android:layout_weight="1" />
+    <ImageView
+
+        android:layout_width="20dp"
+        android:layout_height="20dp"
+        android:background="@mipmap/arrow_right" />
+
+</LinearLayout>
+    <View
+        android:layout_margin="@dimen/dp_10"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#E9E9E9" />
+
+
+</LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:gravity="center"
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="版本号:">
+
+            </TextView>
+            <TextView
+                android:id="@+id/tx_appversion"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                tools:text="1.0.0.1">
+
+            </TextView>
+        </LinearLayout>
+        <LinearLayout
+            android:gravity="center"
+            android:layout_marginBottom="@dimen/dp_10"
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="序列号:">
+
+            </TextView>
+            <TextView
+                android:id="@+id/tx_serial"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                tools:text="00000000000">
+
+            </TextView>
+            <TextView
+                android:id="@+id/tx_projectName"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                tools:text="(测试)">
+            </TextView>
+        </LinearLayout>
+    </LinearLayout>
+
+
+
+
+</FrameLayout>

BIN
app/src/main/res/mipmap-hdpi/img_setting.png


BIN
app/src/main/res/mipmap-hdpi/print.png


BIN
app/src/main/res/mipmap-hdpi/update.png


BIN
app/src/main/res/mipmap-hdpi/xiugaimima.png


BIN
app/src/main/res/mipmap-hdpi/zhuxiao.png


+ 2 - 0
config.gradle

@@ -21,6 +21,7 @@ ext {
             "apiName"      : '"serviceapi"',
             "fileApiHost"      : '""',
             "fileApiName"      : '""',
+            "prjectName" : '"正式"',
 
             // 高德地图
             "AMAP_API_KEY" : "565ad55bec6d286e33a95a9ff1911b55",
@@ -33,6 +34,7 @@ ext {
             "apiName"      : '"serviceapi"',
             "fileApiHost"      : '"https://fileupload.hw.hongweisoft.com"',
             "fileApiName"      : '""',
+            "prjectName" : '"测试"',
 
             // 高德地图
             "AMAP_API_KEY" : "565ad55bec6d286e33a95a9ff1911b55",