打印机封装
This commit is contained in:
+34
-11
@@ -1,25 +1,47 @@
|
|||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import java.util.Properties
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
alias(libs.plugins.kotlin.compose)
|
alias(libs.plugins.kotlin.compose)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 自动版本号管理
|
||||||
|
val versionPropsFile = file("version.properties")
|
||||||
|
fun getVersionCode(): Int {
|
||||||
|
val props = Properties()
|
||||||
|
if (versionPropsFile.exists()) {
|
||||||
|
props.load(versionPropsFile.inputStream())
|
||||||
|
}
|
||||||
|
val code = props.getProperty("VERSION_CODE", "1").toInt()
|
||||||
|
props.setProperty("VERSION_CODE", (code + 1).toString())
|
||||||
|
props.store(versionPropsFile.outputStream(), null)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getVersionName(): String {
|
||||||
|
val props = Properties()
|
||||||
|
if (versionPropsFile.exists()) {
|
||||||
|
props.load(versionPropsFile.inputStream())
|
||||||
|
}
|
||||||
|
return props.getProperty("VERSION_NAME", "1.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
val autoVersionCode = getVersionCode()
|
||||||
|
val autoVersionName = getVersionName()
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.example.ops_android"
|
namespace = "com.example.ops_android"
|
||||||
compileSdk {
|
compileSdk = 36
|
||||||
version = release(36) {
|
|
||||||
minorApiLevel = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.example.ops_android"
|
applicationId = "com.example.ops_android"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 2
|
versionCode = autoVersionCode
|
||||||
versionName = "1.1"
|
versionName = autoVersionName
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
@@ -50,7 +72,6 @@ android {
|
|||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose = true
|
compose = true
|
||||||
aidl = true
|
|
||||||
buildConfig = true
|
buildConfig = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,11 +79,9 @@ android {
|
|||||||
androidComponents {
|
androidComponents {
|
||||||
onVariants { variant ->
|
onVariants { variant ->
|
||||||
variant.outputs.forEach { output ->
|
variant.outputs.forEach { output ->
|
||||||
val versionName = "1.1"
|
|
||||||
val versionCode = "2"
|
|
||||||
val buildType = variant.buildType
|
val buildType = variant.buildType
|
||||||
val date = SimpleDateFormat("yyyyMMdd").format(Date())
|
val date = SimpleDateFormat("yyyyMMdd").format(Date())
|
||||||
output.outputFileName.set("PDA_Printer_Test_v${versionName}_${versionCode}_${buildType}_${date}.apk")
|
output.outputFileName.set("PDA_Printer_Test_v${autoVersionName}_${autoVersionCode}_${buildType}_${date}.apk")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,6 +95,10 @@ dependencies {
|
|||||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||||
implementation(libs.androidx.core.ktx)
|
implementation(libs.androidx.core.ktx)
|
||||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||||
|
|
||||||
|
// 打印SDK
|
||||||
|
implementation(files("libs/lcprintsdk-release.aar"))
|
||||||
|
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||||
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
||||||
|
|||||||
Binary file not shown.
@@ -1,21 +0,0 @@
|
|||||||
package android.bld;
|
|
||||||
|
|
||||||
interface IPrintManager {
|
|
||||||
void initPrinter();
|
|
||||||
void closePrinter();
|
|
||||||
void printText(String text);
|
|
||||||
void printText2(String text);
|
|
||||||
void printQR(String content, int size);
|
|
||||||
void printBarcode(String content, int type, int width, int height);
|
|
||||||
void printBitmap(in byte[] bitmap, int width, int height);
|
|
||||||
void printLine(int lineCount);
|
|
||||||
void start();
|
|
||||||
void setFontSize(int size);
|
|
||||||
void setTextBold(boolean bold);
|
|
||||||
void setUnderLine(boolean underline);
|
|
||||||
void setConcentration(int level);
|
|
||||||
void setFeedPaperSpace(int space);
|
|
||||||
void setUnwindPaperLen(int length);
|
|
||||||
void printEnableMark(boolean enable);
|
|
||||||
void printGoToNextMark();
|
|
||||||
}
|
|
||||||
@@ -35,6 +35,11 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
printerManager.bindService()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
printerManager.unbindService()
|
printerManager.unbindService()
|
||||||
@@ -49,6 +54,14 @@ fun PrinterTestScreen(
|
|||||||
var statusMessage by remember { mutableStateOf("未连接打印服务") }
|
var statusMessage by remember { mutableStateOf("未连接打印服务") }
|
||||||
var isConnected by remember { mutableStateOf(false) }
|
var isConnected by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
DisposableEffect(printerManager) {
|
||||||
|
printerManager.setConnectionCallback { connected, message ->
|
||||||
|
isConnected = connected
|
||||||
|
statusMessage = message
|
||||||
|
}
|
||||||
|
onDispose { }
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
@@ -56,14 +69,12 @@ fun PrinterTestScreen(
|
|||||||
.verticalScroll(rememberScrollState()),
|
.verticalScroll(rememberScrollState()),
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
) {
|
) {
|
||||||
// 标题
|
|
||||||
Text(
|
Text(
|
||||||
text = "PDA 打印机测试",
|
text = "PDA 打印机测试",
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
modifier = Modifier.padding(bottom = 8.dp)
|
modifier = Modifier.padding(bottom = 8.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 版本信息
|
|
||||||
Text(
|
Text(
|
||||||
text = "v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE}) - ${BuildConfig.AUTHOR}",
|
text = "v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE}) - ${BuildConfig.AUTHOR}",
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
@@ -71,7 +82,7 @@ fun PrinterTestScreen(
|
|||||||
modifier = Modifier.padding(bottom = 8.dp)
|
modifier = Modifier.padding(bottom = 8.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 状态显示
|
// ── 状态卡片 ──────────────────────────────────────
|
||||||
Card(
|
Card(
|
||||||
colors = CardDefaults.cardColors(
|
colors = CardDefaults.cardColors(
|
||||||
containerColor = if (isConnected)
|
containerColor = if (isConnected)
|
||||||
@@ -87,48 +98,40 @@ fun PrinterTestScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Divider()
|
HorizontalDivider()
|
||||||
|
|
||||||
// 连接控制区
|
// ══════════════════════════════════════════════════
|
||||||
|
// 连接控制
|
||||||
|
// ══════════════════════════════════════════════════
|
||||||
Text("连接控制", style = MaterialTheme.typography.titleMedium)
|
Text("连接控制", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = { printerManager.bindService() },
|
||||||
val success = printerManager.bindService()
|
|
||||||
isConnected = success
|
|
||||||
statusMessage = if (success) "正在连接打印服务..." else "连接失败"
|
|
||||||
},
|
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("绑定服务") }
|
||||||
Text("绑定服务")
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.initPrinter().fold(
|
printerManager.initDevice().fold(
|
||||||
onSuccess = { statusMessage = "打印机初始化成功" },
|
onSuccess = { statusMessage = "打印机初始化成功" },
|
||||||
onFailure = { statusMessage = "初始化失败: ${it.message}" }
|
onFailure = { statusMessage = "初始化失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("初始化") }
|
||||||
Text("初始化")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.closePrinter().fold(
|
printerManager.closeDevice().fold(
|
||||||
onSuccess = { statusMessage = "打印机已关闭" },
|
onSuccess = { statusMessage = "打印机已关闭" },
|
||||||
onFailure = { statusMessage = "关闭失败: ${it.message}" }
|
onFailure = { statusMessage = "关闭失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("关闭打印机") }
|
||||||
Text("关闭打印机")
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
@@ -137,186 +140,248 @@ fun PrinterTestScreen(
|
|||||||
statusMessage = "服务已解绑"
|
statusMessage = "服务已解绑"
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("解绑服务") }
|
||||||
Text("解绑服务")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Divider()
|
HorizontalDivider()
|
||||||
|
|
||||||
// 基础打印测试
|
// ══════════════════════════════════════════════════
|
||||||
Text("基础打印测试", style = MaterialTheme.typography.titleMedium)
|
// 快速打印
|
||||||
|
// ══════════════════════════════════════════════════
|
||||||
|
Text("快速打印", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.quickPrintText("Hello Printer!\n测试打印\n").fold(
|
printerManager.quickText("Hello Printer!\n测试打印\n").fold(
|
||||||
onSuccess = { statusMessage = "快速打印成功" },
|
onSuccess = { statusMessage = "快速打印成功" },
|
||||||
onFailure = { statusMessage = "打印失败: ${it.message}" }
|
onFailure = { statusMessage = "打印失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) { Text("快速打印测试") }
|
||||||
Text("快速打印测试")
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.buildJob()
|
||||||
|
.text("工单号: WO-001\n操作员: 张三\n")
|
||||||
|
.build()
|
||||||
|
.fold(
|
||||||
|
onSuccess = { statusMessage = "PrintJob 打印成功" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) { Text("PrintJob 构建器测试") }
|
||||||
|
|
||||||
|
HorizontalDivider()
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════
|
||||||
|
// 单步打印(手动组合)
|
||||||
|
// ══════════════════════════════════════════════════
|
||||||
|
Text("单步打印", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.ensureOpen().fold(
|
||||||
|
onSuccess = {
|
||||||
|
printerManager.addText("手动 text\n").fold(
|
||||||
|
onSuccess = { statusMessage = "文字已加入缓冲区" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) { Text("添加文字") }
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.ensureOpen().fold(
|
||||||
|
onSuccess = {
|
||||||
|
printerManager.addQR("https://example.com").fold(
|
||||||
|
onSuccess = { statusMessage = "QR 已加入缓冲区" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) { Text("添加QR") }
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.printText("使用 printText\n").fold(
|
printerManager.ensureOpen().fold(
|
||||||
onSuccess = { statusMessage = "printText 调用成功" },
|
onSuccess = {
|
||||||
|
printerManager.addBarcode("1234567890").fold(
|
||||||
|
onSuccess = { statusMessage = "条码已加入缓冲区" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("添加条码") }
|
||||||
Text("printText")
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.printText2("使用 printText2\n").fold(
|
printerManager.ensureOpen().fold(
|
||||||
onSuccess = { statusMessage = "printText2 调用成功" },
|
onSuccess = {
|
||||||
|
printerManager.addLineFeed(3).fold(
|
||||||
|
onSuccess = { statusMessage = "空行已加入缓冲区" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("添加空行") }
|
||||||
Text("printText2")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.start().fold(
|
printerManager.ensureOpen().fold(
|
||||||
onSuccess = { statusMessage = "开始打印(出纸)" },
|
onSuccess = {
|
||||||
|
printerManager.commit().fold(
|
||||||
|
onSuccess = { statusMessage = "已提交打印" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) { Text("提交打印 (start)") }
|
||||||
Text("start() - 提交打印")
|
|
||||||
}
|
|
||||||
|
|
||||||
Divider()
|
HorizontalDivider()
|
||||||
|
|
||||||
// 样式测试
|
// ══════════════════════════════════════════════════
|
||||||
|
// 样式设置
|
||||||
|
// ══════════════════════════════════════════════════
|
||||||
Text("样式设置", style = MaterialTheme.typography.titleMedium)
|
Text("样式设置", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.setFontSize(24).fold(
|
printerManager.ensureOpen().fold(
|
||||||
onSuccess = { statusMessage = "字体大小已设置" },
|
onSuccess = { statusMessage = "设备已打开,可设置样式" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
printerManager.setFontSize(32).fold(
|
||||||
|
onSuccess = { statusMessage = "大字体已设置" },
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("大字体") }
|
||||||
Text("大字体")
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.setTextBold(true).fold(
|
printerManager.ensureOpen().fold(
|
||||||
onSuccess = { statusMessage = "已设置粗体" },
|
onSuccess = { statusMessage = "设备已打开" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
printerManager.setBold(true).fold(
|
||||||
|
onSuccess = { statusMessage = "粗体已设置" },
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("粗体") }
|
||||||
Text("粗体")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.setUnderLine(true).fold(
|
printerManager.setUnderline(true).fold(
|
||||||
onSuccess = { statusMessage = "已设置下划线" },
|
onSuccess = { statusMessage = "下划线已设置" },
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("下划线") }
|
||||||
Text("下划线")
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.setConcentration(5).fold(
|
printerManager.setDensity(5).fold(
|
||||||
onSuccess = { statusMessage = "浓度已设置" },
|
onSuccess = { statusMessage = "浓度已设置" },
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("浓度") }
|
||||||
Text("浓度")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Divider()
|
HorizontalDivider()
|
||||||
|
|
||||||
// 二维码/条形码测试
|
// ══════════════════════════════════════════════════
|
||||||
Text("二维码与条形码", style = MaterialTheme.typography.titleMedium)
|
// 标签打印
|
||||||
|
// ══════════════════════════════════════════════════
|
||||||
|
Text("标签打印(黑标对齐)", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.printQR("https://example.com", 6).fold(
|
printerManager.quickLabel("标签打印测试\n工单号: WO-001\n").fold(
|
||||||
onSuccess = { statusMessage = "二维码已加入队列" },
|
onSuccess = { statusMessage = "标签打印成功" },
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "标签打印失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) { Text("快速标签打印") }
|
||||||
Text("打印二维码")
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
printerManager.printBarcode("1234567890", 0, 2, 60).fold(
|
|
||||||
onSuccess = { statusMessage = "条形码已加入队列" },
|
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
|
||||||
)
|
|
||||||
},
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
Text("打印条形码")
|
|
||||||
}
|
|
||||||
|
|
||||||
Divider()
|
|
||||||
|
|
||||||
// 走纸控制
|
|
||||||
Text("走纸控制", style = MaterialTheme.typography.titleMedium)
|
|
||||||
|
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.printLine(3).fold(
|
printerManager.enableMarkDetection(true).fold(
|
||||||
onSuccess = { statusMessage = "打印空行" },
|
onSuccess = { statusMessage = "已开启黑标检测" },
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) { Text("开启黑标") }
|
||||||
Text("打印3空行")
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.enableMarkDetection(false).fold(
|
||||||
|
onSuccess = { statusMessage = "已关闭黑标检测" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) { Text("关闭黑标") }
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
printerManager.setFeedPaperSpace(100).fold(
|
printerManager.ensureOpen().fold(
|
||||||
onSuccess = { statusMessage = "走纸间距已设置" },
|
onSuccess = {
|
||||||
|
printerManager.enableMarkDetection(true).fold(
|
||||||
|
onSuccess = {
|
||||||
|
printerManager.gotoNextMark().fold(
|
||||||
|
onSuccess = { statusMessage = "已移动到下一标签" },
|
||||||
onFailure = { statusMessage = "失败: ${it.message}" }
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.weight(1f)
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
) {
|
)
|
||||||
Text("走纸间距")
|
},
|
||||||
}
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
}
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) { Text("下一标签") }
|
||||||
|
|
||||||
Divider()
|
HorizontalDivider()
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════
|
||||||
// 综合测试
|
// 综合测试
|
||||||
|
// ══════════════════════════════════════════════════
|
||||||
Text("综合测试", style = MaterialTheme.typography.titleMedium)
|
Text("综合测试", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
@@ -327,9 +392,7 @@ fun PrinterTestScreen(
|
|||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = MaterialTheme.colorScheme.secondary
|
containerColor = MaterialTheme.colorScheme.secondary
|
||||||
)
|
)
|
||||||
) {
|
) { Text("运行完整测试") }
|
||||||
Text("运行完整测试")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,54 +402,47 @@ private fun runComprehensiveTest(
|
|||||||
) {
|
) {
|
||||||
onStatus("开始综合测试...")
|
onStatus("开始综合测试...")
|
||||||
|
|
||||||
printerManager.initPrinter().onFailure {
|
printerManager.initDevice().onFailure {
|
||||||
onStatus("初始化失败: ${it.message}")
|
onStatus("初始化失败: ${it.message}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 标题
|
|
||||||
printerManager.setFontSize(32)
|
printerManager.setFontSize(32)
|
||||||
printerManager.setTextBold(true)
|
printerManager.setBold(true)
|
||||||
printerManager.printText2("=== 打印测试 ===\n")
|
printerManager.addText("=== 打印测试 ===\n")
|
||||||
|
|
||||||
// 普通文本
|
|
||||||
printerManager.setFontSize(24)
|
printerManager.setFontSize(24)
|
||||||
printerManager.setTextBold(false)
|
printerManager.setBold(false)
|
||||||
printerManager.printText2("普通文本测试\n")
|
printerManager.addText("普通文本测试\n")
|
||||||
|
|
||||||
// 粗体文本
|
printerManager.setBold(true)
|
||||||
printerManager.setTextBold(true)
|
printerManager.addText("粗体文本测试\n")
|
||||||
printerManager.printText2("粗体文本测试\n")
|
printerManager.setBold(false)
|
||||||
printerManager.setTextBold(false)
|
|
||||||
|
|
||||||
// 下划线文本
|
printerManager.setUnderline(true)
|
||||||
printerManager.setUnderLine(true)
|
printerManager.addText("下划线文本测试\n")
|
||||||
printerManager.printText2("下划线文本测试\n")
|
printerManager.setUnderline(false)
|
||||||
printerManager.setUnderLine(false)
|
|
||||||
|
|
||||||
// 空行
|
printerManager.addLineFeed(1)
|
||||||
printerManager.printLine(1)
|
|
||||||
|
|
||||||
// 二维码
|
printerManager.addText("二维码测试:\n")
|
||||||
printerManager.printText2("二维码测试:\n")
|
printerManager.addQR("https://example.com")
|
||||||
printerManager.printQR("https://example.com", 6)
|
printerManager.addLineFeed(1)
|
||||||
printerManager.printLine(1)
|
|
||||||
|
|
||||||
// 条形码
|
printerManager.addText("条形码测试:\n")
|
||||||
printerManager.printText2("条形码测试:\n")
|
printerManager.addBarcode("123456789012")
|
||||||
printerManager.printBarcode("123456789012", 0, 2, 60)
|
printerManager.addLineFeed(3)
|
||||||
printerManager.printLine(3)
|
|
||||||
|
|
||||||
// 分隔线
|
printerManager.addText("--------------------------------\n")
|
||||||
printerManager.printText2("--------------------------------\n")
|
printerManager.addText("测试完成\n")
|
||||||
printerManager.printText2("测试完成\n")
|
printerManager.addLineFeed(2)
|
||||||
printerManager.printLine(2)
|
|
||||||
|
|
||||||
// 提交打印
|
printerManager.commit().fold(
|
||||||
printerManager.start().fold(
|
onSuccess = {
|
||||||
onSuccess = { onStatus("综合测试完成,开始打印") },
|
onStatus("综合测试完成,开始打印")
|
||||||
|
Thread.sleep(1500)
|
||||||
|
printerManager.closeDevice()
|
||||||
|
},
|
||||||
onFailure = { onStatus("提交打印失败: ${it.message}") }
|
onFailure = { onStatus("提交打印失败: ${it.message}") }
|
||||||
)
|
)
|
||||||
|
|
||||||
printerManager.closePrinter()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.example.ops_android.printer
|
||||||
|
|
||||||
|
class PrintJob(private val manager: PrinterManager) {
|
||||||
|
|
||||||
|
private var textContent: String? = null
|
||||||
|
private var qrContent: String? = null
|
||||||
|
private var barcodeContent: String? = null
|
||||||
|
private var lineFeeds: Int = 0
|
||||||
|
private var useLabelMode: Boolean = false
|
||||||
|
|
||||||
|
fun text(text: String): PrintJob {
|
||||||
|
textContent = text
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun qr(content: String): PrintJob {
|
||||||
|
qrContent = content
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun barcode(content: String): PrintJob {
|
||||||
|
barcodeContent = content
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun lineFeed(count: Int = 1): PrintJob {
|
||||||
|
lineFeeds = count
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun labelMode(): PrintJob {
|
||||||
|
useLabelMode = true
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 → 添加内容 → 提交 → 等待 → 关闭 */
|
||||||
|
fun build(): Result<Unit> = runCatching {
|
||||||
|
manager.initDevice().getOrThrow()
|
||||||
|
|
||||||
|
if (useLabelMode)
|
||||||
|
manager.enableMarkDetection(true).getOrThrow()
|
||||||
|
|
||||||
|
textContent?.let { manager.addText(it).getOrThrow() }
|
||||||
|
qrContent?.let { manager.addQR(it).getOrThrow() }
|
||||||
|
barcodeContent?.let { manager.addBarcode(it).getOrThrow() }
|
||||||
|
if (lineFeeds > 0) manager.addLineFeed(lineFeeds).getOrThrow()
|
||||||
|
|
||||||
|
manager.commit().getOrThrow()
|
||||||
|
Thread.sleep(1500)
|
||||||
|
manager.closeDevice().getOrThrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 → 添加内容 → 提交(不关闭) */
|
||||||
|
fun print(): Result<Unit> = runCatching {
|
||||||
|
manager.ensureOpen().getOrThrow()
|
||||||
|
|
||||||
|
if (useLabelMode)
|
||||||
|
manager.enableMarkDetection(true).getOrThrow()
|
||||||
|
|
||||||
|
textContent?.let { manager.addText(it).getOrThrow() }
|
||||||
|
qrContent?.let { manager.addQR(it).getOrThrow() }
|
||||||
|
barcodeContent?.let { manager.addBarcode(it).getOrThrow() }
|
||||||
|
if (lineFeeds > 0) manager.addLineFeed(lineFeeds).getOrThrow()
|
||||||
|
|
||||||
|
manager.commit().getOrThrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,136 +1,322 @@
|
|||||||
package com.example.ops_android.printer
|
package com.example.ops_android.printer
|
||||||
|
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.graphics.Bitmap
|
||||||
import android.content.ServiceConnection
|
import android.os.Handler
|
||||||
import android.os.IBinder
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.bld.IPrintManager
|
import android.bld.PrintManager
|
||||||
|
import android.bld.print.aidl.PrinterBinderListener
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.TimeoutCancellationException
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlinx.coroutines.withTimeout
|
||||||
|
|
||||||
class PrinterManager(private val context: Context) {
|
class PrinterManager(private val context: Context) {
|
||||||
private var printService: IPrintManager? = null
|
|
||||||
private var isBound = false
|
// ── 内部状态 ────────────────────────────────────────────
|
||||||
|
internal var printManager: PrintManager? = null
|
||||||
|
private set
|
||||||
|
@Volatile internal var isOpen = false
|
||||||
|
private set
|
||||||
|
@Volatile private var intentionalClose = false
|
||||||
|
private var connectionCallback: ((Boolean, String) -> Unit)? = null
|
||||||
|
private val mainHandler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "PrinterManager"
|
private const val TAG = "PrinterManager"
|
||||||
private const val PRINT_SERVICE_ACTION = "android.bld.PrintManager"
|
private const val CONNECT_TIMEOUT_MS = 10_000L
|
||||||
private const val PRINT_SERVICE_PACKAGE = "android.bld"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val serviceConnection = object : ServiceConnection {
|
// 错误码
|
||||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
internal const val ERROR_NO_ERROR = 0
|
||||||
printService = IPrintManager.Stub.asInterface(service)
|
internal const val ERROR_DEV_IS_BUSY = 1
|
||||||
isBound = true
|
internal const val ERROR_PRINT_HOT = 2
|
||||||
Log.d(TAG, "Print service connected")
|
internal const val ERROR_PRINT_NOPAPER = 3
|
||||||
}
|
internal const val ERROR_DEV_NO_BATTERY = 4
|
||||||
|
internal const val ERROR_DEV_FEED = 5
|
||||||
|
internal const val ERROR_DEV_PRINT = 6
|
||||||
|
internal const val ERROR_DEV_BMARK = 7
|
||||||
|
internal const val ERROR_DEV_NOT_OPEN = 16
|
||||||
|
internal const val ERROR_NO_DATA = 17
|
||||||
|
internal const val ERROR_DATA_INVALID = 18
|
||||||
|
internal const val ERROR_CMD = 19
|
||||||
|
internal const val ERROR_GRAY_INVALID = 20
|
||||||
|
|
||||||
override fun onServiceDisconnected(name: ComponentName?) {
|
fun getErrorMessage(errorCode: Int): String = when (errorCode) {
|
||||||
printService = null
|
ERROR_NO_ERROR -> "正常"
|
||||||
isBound = false
|
ERROR_DEV_IS_BUSY -> "设备忙"
|
||||||
Log.d(TAG, "Print service disconnected")
|
ERROR_PRINT_HOT -> "打印头过热"
|
||||||
|
ERROR_PRINT_NOPAPER -> "缺纸"
|
||||||
|
ERROR_DEV_NO_BATTERY -> "电量不足"
|
||||||
|
ERROR_DEV_FEED -> "走纸错误"
|
||||||
|
ERROR_DEV_PRINT -> "打印错误"
|
||||||
|
ERROR_DEV_BMARK -> "黑标错误"
|
||||||
|
ERROR_DEV_NOT_OPEN -> "设备未打开"
|
||||||
|
ERROR_NO_DATA -> "无数据"
|
||||||
|
ERROR_DATA_INVALID -> "数据无效"
|
||||||
|
ERROR_CMD -> "指令错误"
|
||||||
|
ERROR_GRAY_INVALID -> "浓度无效"
|
||||||
|
165 -> "数据输入错误"
|
||||||
|
else -> "未知错误($errorCode)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bindService(): Boolean {
|
// ── 连接回调 ───(运行在 Binder 线程,需切换到主线程)──────
|
||||||
return try {
|
private val printerListener = object : PrinterBinderListener {
|
||||||
val intent = Intent(PRINT_SERVICE_ACTION).apply {
|
override fun onPrintCallback(status: Int) {
|
||||||
setPackage(PRINT_SERVICE_PACKAGE)
|
Log.d(TAG, "Printer callback: status=$status (${getErrorMessage(status)})")
|
||||||
|
mainHandler.post {
|
||||||
|
when (status) {
|
||||||
|
ERROR_NO_ERROR -> {
|
||||||
|
isOpen = true
|
||||||
|
connectionCallback?.invoke(true, "打印机已就绪")
|
||||||
}
|
}
|
||||||
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
|
ERROR_DEV_NOT_OPEN -> {
|
||||||
|
if (intentionalClose) return@post
|
||||||
|
isOpen = false
|
||||||
|
connectionCallback?.invoke(false, "设备未打开,请重新连接")
|
||||||
|
}
|
||||||
|
else -> connectionCallback?.invoke(false, getErrorMessage(status))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setConnectionCallback(callback: (Boolean, String) -> Unit) {
|
||||||
|
connectionCallback = callback
|
||||||
|
}
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
// 连接管理
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
fun bindService() {
|
||||||
|
notifyConnection(false, "正在连接打印服务...")
|
||||||
|
Thread {
|
||||||
|
try {
|
||||||
|
kotlinx.coroutines.runBlocking {
|
||||||
|
withTimeout(CONNECT_TIMEOUT_MS) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
intentionalClose = false
|
||||||
|
Log.d(TAG, "Attempting to get PrintManager instance...")
|
||||||
|
val manager = PrintManager.getDefaultInstance(context)
|
||||||
|
if (manager == null) {
|
||||||
|
notifyConnection(false, "设备不支持打印功能")
|
||||||
|
return@withContext
|
||||||
|
}
|
||||||
|
printManager = manager
|
||||||
|
manager.addPrintListener(printerListener)
|
||||||
|
Log.d(TAG, "Opening printer...")
|
||||||
|
val success = manager.open()
|
||||||
|
Log.d(TAG, "open() returned: $success")
|
||||||
|
if (success) {
|
||||||
|
isOpen = true
|
||||||
|
val version = manager.getPrinterVer()
|
||||||
|
if (version != null) {
|
||||||
|
notifyConnection(true, "打印机已连接 (固件: $version)")
|
||||||
|
} else {
|
||||||
|
notifyConnection(true, "打印机已连接")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isOpen = false
|
||||||
|
notifyConnection(false, "打印机打开失败,请检查设备")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: TimeoutCancellationException) {
|
||||||
|
Log.e(TAG, "bindService timeout after ${CONNECT_TIMEOUT_MS}ms")
|
||||||
|
notifyConnection(false, "连接超时,请检查打印服务是否运行")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Failed to bind print service", e)
|
Log.e(TAG, "Failed to open print service", e)
|
||||||
false
|
notifyConnection(false, "连接异常: ${e.message}")
|
||||||
}
|
}
|
||||||
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unbindService() {
|
fun unbindService() {
|
||||||
if (isBound) {
|
Thread {
|
||||||
context.unbindService(serviceConnection)
|
try {
|
||||||
isBound = false
|
if (isOpen) {
|
||||||
|
printManager?.removePrintListener(printerListener)
|
||||||
|
printManager?.close()
|
||||||
|
isOpen = false
|
||||||
|
notifyConnection(false, "服务已断开")
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Failed to close print service", e)
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isConnected(): Boolean = isOpen && printManager != null
|
||||||
|
|
||||||
|
fun getFirmwareVersion(): String? {
|
||||||
|
return try {
|
||||||
|
printManager?.getPrinterVer()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Failed to get printer version", e)
|
||||||
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 基础连接方法
|
// ══════════════════════════════════════════════════════════
|
||||||
fun initPrinter(): Result<Unit> = runCatching {
|
// 设备控制
|
||||||
printService?.initPrinter() ?: throw Exception("Print service not connected")
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
fun ensureOpen(): Result<Unit> = runCatching {
|
||||||
|
checkPrinter()
|
||||||
|
if (!isOpen) {
|
||||||
|
intentionalClose = false
|
||||||
|
val opened = printManager?.open() ?: false
|
||||||
|
if (!opened) throw Exception("设备未打开,请重新绑定服务")
|
||||||
|
isOpen = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun closePrinter(): Result<Unit> = runCatching {
|
fun initDevice(): Result<Unit> = runCatching {
|
||||||
printService?.closePrinter() ?: throw Exception("Print service not connected")
|
ensureOpen().getOrThrow()
|
||||||
|
val result = printManager!!.reset()
|
||||||
|
if (result != ERROR_NO_ERROR) throw Exception("初始化失败: ${getErrorMessage(result)}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打印方法
|
fun closeDevice(): Result<Unit> = runCatching {
|
||||||
fun printText(text: String): Result<Unit> = runCatching {
|
checkOpen()
|
||||||
printService?.printText(text) ?: throw Exception("Print service not connected")
|
isOpen = false
|
||||||
|
intentionalClose = true
|
||||||
|
printManager?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun printText2(text: String): Result<Unit> = runCatching {
|
fun commit(): Result<Unit> = runCatching {
|
||||||
printService?.printText2(text) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun printQR(content: String, size: Int = 6): Result<Unit> = runCatching {
|
// ══════════════════════════════════════════════════════════
|
||||||
printService?.printQR(content, size) ?: throw Exception("Print service not connected")
|
// 内容添加(供 PrintJob 使用)
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
internal fun addText(text: String): Result<Unit> = runCatching {
|
||||||
|
checkOpen()
|
||||||
|
val pm = printManager!!
|
||||||
|
pm.addText(0, pm.getFontSize() ?: 24, pm.isFontBold() ?: false, pm.isUnderLine() ?: false, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun printBarcode(content: String, type: Int = 0, width: Int = 2, height: Int = 60): Result<Unit> = runCatching {
|
internal fun addQR(content: String): Result<Unit> = runCatching {
|
||||||
printService?.printBarcode(content, type, width, height) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.addQRCode(2, 384, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun printBitmap(bitmap: ByteArray, width: Int, height: Int): Result<Unit> = runCatching {
|
internal fun addBarcode(content: String): Result<Unit> = runCatching {
|
||||||
printService?.printBitmap(bitmap, width, height) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.addBarcode(2, 60, content, 73, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun printLine(lineCount: Int = 1): Result<Unit> = runCatching {
|
internal fun addLineFeed(count: Int = 1): Result<Unit> = runCatching {
|
||||||
printService?.printLine(lineCount) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.addLineFeed(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun start(): Result<Unit> = runCatching {
|
// ══════════════════════════════════════════════════════════
|
||||||
printService?.start() ?: throw Exception("Print service not connected")
|
// 样式设置
|
||||||
}
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
// 样式设置方法
|
|
||||||
fun setFontSize(size: Int): Result<Unit> = runCatching {
|
fun setFontSize(size: Int): Result<Unit> = runCatching {
|
||||||
printService?.setFontSize(size) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.setFontSize(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTextBold(bold: Boolean): Result<Unit> = runCatching {
|
fun setBold(bold: Boolean): Result<Unit> = runCatching {
|
||||||
printService?.setTextBold(bold) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.setFontBold(bold)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setUnderLine(underline: Boolean): Result<Unit> = runCatching {
|
fun setUnderline(underline: Boolean): Result<Unit> = runCatching {
|
||||||
printService?.setUnderLine(underline) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.setUnderLine(underline)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setConcentration(level: Int): Result<Unit> = runCatching {
|
fun setDensity(level: Int): Result<Unit> = runCatching {
|
||||||
printService?.setConcentration(level) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.setDensity(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
// 走纸控制
|
// 走纸控制
|
||||||
fun setFeedPaperSpace(space: Int): Result<Unit> = runCatching {
|
// ══════════════════════════════════════════════════════════
|
||||||
printService?.setFeedPaperSpace(space) ?: throw Exception("Print service not connected")
|
|
||||||
|
fun setPaperGap(dots: Int): Result<Unit> = runCatching {
|
||||||
|
checkOpen()
|
||||||
|
printManager!!.setFeedPaperSpace(dots)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setUnwindPaperLen(length: Int): Result<Unit> = runCatching {
|
fun setUnwindLength(len: Int): Result<Unit> = runCatching {
|
||||||
printService?.setUnwindPaperLen(length) ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.setUnwindPaperLen(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 标签纸控制
|
// ══════════════════════════════════════════════════════════
|
||||||
fun printEnableMark(enable: Boolean): Result<Unit> = runCatching {
|
// 黑标 / 标签
|
||||||
printService?.printEnableMark(enable) ?: throw Exception("Print service not connected")
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
fun enableMarkDetection(enable: Boolean): Result<Unit> = runCatching {
|
||||||
|
checkOpen()
|
||||||
|
printManager!!.setBlackLabel(enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun printGoToNextMark(): Result<Unit> = runCatching {
|
fun gotoNextMark(): Result<Unit> = runCatching {
|
||||||
printService?.printGoToNextMark() ?: throw Exception("Print service not connected")
|
checkOpen()
|
||||||
|
printManager!!.addLineFeed(1)
|
||||||
|
printManager!!.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 便捷组合方法
|
// ══════════════════════════════════════════════════════════
|
||||||
fun quickPrintText(text: String): Result<Unit> = runCatching {
|
// 图片
|
||||||
initPrinter().getOrThrow()
|
// ══════════════════════════════════════════════════════════
|
||||||
printText2(text).getOrThrow()
|
|
||||||
start().getOrThrow()
|
fun printImage(bitmap: Bitmap, align: Int = 1): Result<Unit> = runCatching {
|
||||||
closePrinter().getOrThrow()
|
checkOpen()
|
||||||
|
printManager!!.addImage(align, bitmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isServiceConnected(): Boolean = isBound && printService != null
|
// ══════════════════════════════════════════════════════════
|
||||||
|
// 便捷方法
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
fun quickText(text: String): Result<Unit> = runCatching {
|
||||||
|
initDevice().getOrThrow()
|
||||||
|
addText(text).getOrThrow()
|
||||||
|
commit().getOrThrow()
|
||||||
|
Thread.sleep(1500)
|
||||||
|
closeDevice().getOrThrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun quickLabel(text: String): Result<Unit> = runCatching {
|
||||||
|
initDevice().getOrThrow()
|
||||||
|
enableMarkDetection(true).getOrThrow()
|
||||||
|
addText(text).getOrThrow()
|
||||||
|
commit().getOrThrow()
|
||||||
|
Thread.sleep(1500)
|
||||||
|
closeDevice().getOrThrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 创建链式打印任务 */
|
||||||
|
fun buildJob(): PrintJob = PrintJob(this)
|
||||||
|
|
||||||
|
// ── 内部工具 ────────────────────────────────────────────
|
||||||
|
|
||||||
|
internal fun checkPrinter() {
|
||||||
|
if (printManager == null)
|
||||||
|
throw Exception("打印服务未初始化,请先点击'绑定服务'")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkOpen() {
|
||||||
|
checkPrinter()
|
||||||
|
if (!isOpen)
|
||||||
|
throw Exception("打印服务未连接,请先点击'绑定服务'")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notifyConnection(connected: Boolean, message: String) {
|
||||||
|
mainHandler.post { connectionCallback?.invoke(connected, message) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#Wed Jun 24 20:47:38 CST 2026
|
||||||
|
VERSION_CODE=23
|
||||||
|
VERSION_NAME=1.2
|
||||||
Reference in New Issue
Block a user