基础基础热敏打印功能
This commit is contained in:
parent
daf6cba15e
commit
3bdf2b9849
|
|
@ -45,6 +45,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
|
||||||
implementation("com.jakewharton.timber:timber:5.0.1")
|
implementation("com.jakewharton.timber:timber:5.0.1")
|
||||||
implementation("io.github.justson:agentweb-core:v5.1.1-androidx")
|
implementation("io.github.justson:agentweb-core:v5.1.1-androidx")
|
||||||
implementation("com.github.Justson:Downloader:v5.0.4-androidx")
|
implementation("com.github.Justson:Downloader:v5.0.4-androidx")
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -47,6 +47,12 @@
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/Theme.StandAPP" />
|
android:theme="@style/Theme.StandAPP" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".printer.PrintTestActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:label="打印测试"
|
||||||
|
android:theme="@style/Theme.AppCompat.Light.DarkActionBar" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.example.kingway.ptt.pttActivity"
|
android:name="com.example.kingway.ptt.pttActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 164 KiB |
|
|
@ -24,6 +24,7 @@ class LoginActivity : AppCompatActivity() {
|
||||||
val cbRemember = findViewById<CheckBox>(R.id.cb_remember)
|
val cbRemember = findViewById<CheckBox>(R.id.cb_remember)
|
||||||
val btnLogin = findViewById<Button>(R.id.btn_login)
|
val btnLogin = findViewById<Button>(R.id.btn_login)
|
||||||
val btnPttExample = findViewById<Button>(R.id.btn_ptt_example)
|
val btnPttExample = findViewById<Button>(R.id.btn_ptt_example)
|
||||||
|
val btnPrinterTest = findViewById<Button>(R.id.btn_printer_test)
|
||||||
val ivSettings = findViewById<ImageView>(R.id.iv_settings)
|
val ivSettings = findViewById<ImageView>(R.id.iv_settings)
|
||||||
|
|
||||||
// 1. 加载保存的状态和凭据
|
// 1. 加载保存的状态和凭据
|
||||||
|
|
@ -59,7 +60,17 @@ class LoginActivity : AppCompatActivity() {
|
||||||
val intent = Intent(this, com.example.kingway.ptt.pttActivity::class.java)
|
val intent = Intent(this, com.example.kingway.ptt.pttActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Toast.makeText(this, "打开 PTT 示例失败: ${e.message}", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "打开 PTT 示例失败: ${e.message}", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 打印测试按钮点击事件
|
||||||
|
btnPrinterTest.setOnClickListener {
|
||||||
|
try {
|
||||||
|
val intent = Intent(this, com.stand.standapp.printer.PrintTestActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Toast.makeText(this, "打开打印测试失败: ${e.message}", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
package com.stand.standapp.printer;
|
||||||
|
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.dp.dp_serialportlist.Serialport_Factory;
|
||||||
|
import com.stand.standapp.R;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class PrintTestActivity extends AppCompatActivity implements View.OnClickListener {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("szzkserialport");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Spinner spPortPath, spBaudrate;
|
||||||
|
private EditText etManualPath;
|
||||||
|
private CheckBox cbManualMode;
|
||||||
|
private Button btnOpen;
|
||||||
|
private TextView tvStatus;
|
||||||
|
|
||||||
|
private Serialport_Factory sf;
|
||||||
|
private String[] portNames;
|
||||||
|
|
||||||
|
private Handler mHandler = new Handler(new Handler.Callback() {
|
||||||
|
@Override
|
||||||
|
public boolean handleMessage(Message msg) {
|
||||||
|
if (msg.what == Serialport_Factory.PAPER_STATE) {
|
||||||
|
boolean hasPaper = msg.getData().getBoolean("PAPER_STATE");
|
||||||
|
tvStatus.setText("打印机状态: " + (hasPaper ? "有纸" : "缺纸"));
|
||||||
|
Toast.makeText(PrintTestActivity.this, hasPaper ? "打印机有纸" : "打印机缺纸", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_printer_test);
|
||||||
|
|
||||||
|
initViews();
|
||||||
|
|
||||||
|
sf = Serialport_Factory.getSerialport_Factory(this, mHandler);
|
||||||
|
loadSerialPorts();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
|
spPortPath = findViewById(R.id.sp_port_path);
|
||||||
|
spBaudrate = findViewById(R.id.sp_baudrate);
|
||||||
|
etManualPath = findViewById(R.id.et_manual_path);
|
||||||
|
cbManualMode = findViewById(R.id.cb_manual_mode);
|
||||||
|
btnOpen = findViewById(R.id.btn_open);
|
||||||
|
tvStatus = findViewById(R.id.tv_status);
|
||||||
|
|
||||||
|
cbManualMode.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
spPortPath.setVisibility(isChecked ? View.GONE : View.VISIBLE);
|
||||||
|
etManualPath.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btnOpen.setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_print_text).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_print_barcode).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_print_qr).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_print_img).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_print_column).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_print_demo1).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_print_demo2).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_print_test_page).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_check_paper).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_cut_all).setOnClickListener(this);
|
||||||
|
findViewById(R.id.btn_back).setOnClickListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSerialPorts() {
|
||||||
|
try {
|
||||||
|
portNames = sf.getAllDevices();
|
||||||
|
if (portNames != null && portNames.length > 0) {
|
||||||
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, portNames);
|
||||||
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
spPortPath.setAdapter(adapter);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "未检测到串口设备,请检查硬件权限", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
int id = v.getId();
|
||||||
|
if (id == R.id.btn_open) {
|
||||||
|
openPort();
|
||||||
|
} else if (id == R.id.btn_back) {
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
if (!sf.isConnection()) {
|
||||||
|
Toast.makeText(this, "请先开启串口", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handlePrintAction(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openPort() {
|
||||||
|
String path;
|
||||||
|
if (cbManualMode.isChecked()) {
|
||||||
|
path = etManualPath.getText().toString().trim();
|
||||||
|
} else {
|
||||||
|
if (spPortPath.getSelectedItem() == null) return;
|
||||||
|
path = spPortPath.getSelectedItem().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
String baudrate = spBaudrate.getSelectedItem().toString();
|
||||||
|
if (sf.OpenPort(path, baudrate)) {
|
||||||
|
tvStatus.setText("状态: 已连接 (" + path + ")");
|
||||||
|
tvStatus.setTextColor(0xFF4CAF50);
|
||||||
|
Toast.makeText(this, "串口已开启", Toast.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
tvStatus.setText("状态: 连接失败");
|
||||||
|
tvStatus.setTextColor(0xFFFF0000);
|
||||||
|
Toast.makeText(this, "串口开启失败", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePrintAction(int id) {
|
||||||
|
if (id == R.id.btn_print_text) {
|
||||||
|
sf.PrintText("StandAPP 打印测试", 2, 1, 30);
|
||||||
|
sf.PrintText("文本内容居左测试", 1, 1, 20);
|
||||||
|
sf.PaperCut();
|
||||||
|
} else if (id == R.id.btn_print_barcode) {
|
||||||
|
sf.PrintBarcode("88888888", 3, 100, 5, 2, 2);
|
||||||
|
sf.PrintText("\n", 1, 1, 50);
|
||||||
|
sf.PaperCut();
|
||||||
|
} else if (id == R.id.btn_print_qr) {
|
||||||
|
sf.PrintQR("StandAPP-Integrated", 6, 2);
|
||||||
|
sf.PrintText("\n", 1, 1, 50);
|
||||||
|
sf.PaperCut();
|
||||||
|
} else if (id == R.id.btn_print_img) {
|
||||||
|
Bitmap bm = getImageFromAssetsFile("1.jpg");
|
||||||
|
if (bm != null) {
|
||||||
|
sf.PrintImage(bm, 384, 0, 2);
|
||||||
|
sf.PrintText("\n", 1, 1, 50);
|
||||||
|
sf.PaperCut();
|
||||||
|
}
|
||||||
|
} else if (id == R.id.btn_print_column) {
|
||||||
|
sf.Printcolumncontent("项目", 0, "单价", 180, "数量", 250, "金额", 320);
|
||||||
|
sf.Printcolumncontent("测试商品", 0, "10.0", 180, "1", 250, "10.0", 320, 70);
|
||||||
|
sf.PrintText("\n", 1, 1, 50);
|
||||||
|
sf.PaperCut();
|
||||||
|
} else if (id == R.id.btn_print_demo1) {
|
||||||
|
printDemo(false);
|
||||||
|
} else if (id == R.id.btn_print_demo2) {
|
||||||
|
printDemo(true);
|
||||||
|
} else if (id == R.id.btn_print_test_page) {
|
||||||
|
sf.PrintTestPage();
|
||||||
|
} else if (id == R.id.btn_check_paper) {
|
||||||
|
sf.Check_Paper();
|
||||||
|
} else if (id == R.id.btn_cut_all) {
|
||||||
|
sf.PaperAllCut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printDemo(boolean is3Inch) {
|
||||||
|
int width = is3Inch ? 400 : 300;
|
||||||
|
int right = is3Inch ? 120 : 100;
|
||||||
|
sf.PrintText("\nStandAPP 业务测试单", 2, 1, 30);
|
||||||
|
sf.PrintText("--------------------------------", 1, 1, 10);
|
||||||
|
sf.Printcolumncontent("名称", 0, "单价", 180, "数量", 250, "金额", width);
|
||||||
|
sf.Printcolumncontent("演示商品A", 0, "9.9", 180, "1", 250, "9.90", width, right);
|
||||||
|
sf.PrintText("--------------------------------", 1, 1, 10);
|
||||||
|
sf.PrintQR("http://www.standapp.com", 6, 2);
|
||||||
|
sf.PrintText("\n\n\n", 1, 1, 10);
|
||||||
|
sf.PaperCut();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap getImageFromAssetsFile(String fileName) {
|
||||||
|
try {
|
||||||
|
InputStream is = getAssets().open(fileName);
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeStream(is);
|
||||||
|
is.close();
|
||||||
|
return bitmap;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (sf != null) sf.Disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -133,11 +133,21 @@
|
||||||
android:id="@+id/btn_ptt_example"
|
android:id="@+id/btn_ptt_example"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="50dp"
|
android:layout_height="50dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
android:background="@drawable/shape_button_login"
|
android:background="@drawable/shape_button_login"
|
||||||
android:text="PTT 示例"
|
android:text="PTT 示例"
|
||||||
android:textColor="#FFFFFF"
|
android:textColor="#FFFFFF"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_printer_test"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:background="@drawable/shape_button_login"
|
||||||
|
android:text="打印测试"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#F5F5F5">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp">
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_back"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="返回" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:text="串口打印集成测试"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="1. 串口配置"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="#FFFFFF"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/sp_port_path"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/et_manual_path"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="手动路径 (如 /dev/ttyS0)"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/cb_manual_mode"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="手动输入模式" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/sp_baudrate"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:entries="@array/baudrates" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_open"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="打开串口" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_status"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="状态: 未连接"
|
||||||
|
android:textColor="#FF0000" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="2. 打印操作"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<GridLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:columnCount="2">
|
||||||
|
|
||||||
|
<Button android:id="@+id/btn_print_text" android:text="打印文本" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_print_barcode" android:text="打印条码" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_print_qr" android:text="打印二维码" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_print_img" android:text="打印图片" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_print_column" android:text="多列排版" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_print_demo1" android:text="2寸样单" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_print_demo2" android:text="3寸样单" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_print_test_page" android:text="打印自检" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_check_paper" android:text="缺纸检测" android:layout_columnWeight="1"/>
|
||||||
|
<Button android:id="@+id/btn_cut_all" android:text="全切纸" android:layout_columnWeight="1"/>
|
||||||
|
</GridLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<resources>
|
||||||
|
<string-array name="baudrates">
|
||||||
|
<item>9600</item>
|
||||||
|
<item>19200</item>
|
||||||
|
<item>38400</item>
|
||||||
|
<item>57600</item>
|
||||||
|
<item>115200</item>
|
||||||
|
</string-array>
|
||||||
|
</resources>
|
||||||
Loading…
Reference in New Issue