up
This commit is contained in:
@@ -0,0 +1,88 @@
|
|||||||
|
# 构建信息
|
||||||
|
|
||||||
|
## APK 信息
|
||||||
|
|
||||||
|
- **文件名**: `PDA_Printer_Test_v1.1_2_release_20260624.apk`
|
||||||
|
- **版本名称**: 1.1
|
||||||
|
- **版本号**: 2
|
||||||
|
- **构建类型**: Release
|
||||||
|
- **构建日期**: 2026-06-24
|
||||||
|
- **作者**: 无闻风
|
||||||
|
|
||||||
|
## 文件位置
|
||||||
|
|
||||||
|
```
|
||||||
|
app/build/outputs/apk/release/PDA_Printer_Test_v1.1_2_release_20260624.apk
|
||||||
|
```
|
||||||
|
|
||||||
|
## 版本历史
|
||||||
|
|
||||||
|
### v1.1 (Build 2) - 2026-06-24
|
||||||
|
- ✨ 新增完整的打印机测试界面
|
||||||
|
- ✨ 支持所有打印功能测试(文本、二维码、条形码)
|
||||||
|
- ✨ 支持样式设置(字体、粗体、下划线、浓度)
|
||||||
|
- ✨ 添加走纸控制功能
|
||||||
|
- ✨ 实时状态显示
|
||||||
|
- ✨ 综合测试功能
|
||||||
|
- 📦 集成 android.bld.PrintManager AIDL 接口
|
||||||
|
- 👤 作者信息集成到应用中
|
||||||
|
|
||||||
|
### v1.0 (Build 1) - 初始版本
|
||||||
|
- 基础项目框架
|
||||||
|
|
||||||
|
## 应用特性
|
||||||
|
|
||||||
|
### 核心功能
|
||||||
|
- 打印机服务绑定与管理
|
||||||
|
- 文本打印(printText / printText2)
|
||||||
|
- 二维码打印
|
||||||
|
- 条形码打印
|
||||||
|
- 样式控制(字体大小、粗体、下划线、浓度)
|
||||||
|
- 走纸控制
|
||||||
|
- 标签纸支持
|
||||||
|
|
||||||
|
### 测试功能
|
||||||
|
- 快速打印测试
|
||||||
|
- 单项功能测试
|
||||||
|
- 完整综合测试
|
||||||
|
- 实时状态反馈
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
- **语言**: Kotlin
|
||||||
|
- **UI 框架**: Jetpack Compose
|
||||||
|
- **最低 SDK**: 24 (Android 7.0)
|
||||||
|
- **目标 SDK**: 36
|
||||||
|
- **构建工具**: Gradle 9.4.1
|
||||||
|
- **AIDL**: android.bld.PrintManager
|
||||||
|
|
||||||
|
## 安装说明
|
||||||
|
|
||||||
|
1. 将 APK 文件传输到 PDA 设备
|
||||||
|
2. 在设备上安装 APK
|
||||||
|
3. 确保设备已预装 `android.bld.PrintManager` 系统服务
|
||||||
|
4. 打开应用开始测试
|
||||||
|
|
||||||
|
## 使用流程
|
||||||
|
|
||||||
|
1. 点击 **"绑定服务"** 连接打印服务
|
||||||
|
2. 点击 **"初始化"** 初始化打印机
|
||||||
|
3. 使用各项测试按钮进行功能测试
|
||||||
|
4. 或直接点击 **"运行完整测试"** 执行所有功能
|
||||||
|
5. 完成后点击 **"关闭打印机"** 和 **"解绑服务"**
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
⚠️ 此应用仅适用于预装 `android.bld.PrintManager` 系统服务的 PDA 设备
|
||||||
|
⚠️ 所有打印内容添加后必须调用 `start()` 才会实际出纸
|
||||||
|
⚠️ 使用完毕后应释放打印机资源
|
||||||
|
|
||||||
|
## 下次构建
|
||||||
|
|
||||||
|
下次构建时版本号将自动递增到 v1.2 (Build 3)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**构建者**: 无闻风
|
||||||
|
**构建时间**: 2026-06-24
|
||||||
|
**项目路径**: `/Users/wuwenfeng/Documents/prj/ops_android`
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
# PDA 打印机测试应用
|
||||||
|
|
||||||
|
一个用于测试内置 PDA 终端打印机的 Android 应用,基于 Jetpack Compose 构建。
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## 📱 应用截图
|
||||||
|
|
||||||
|
应用提供完整的打印机测试界面,包含:
|
||||||
|
- 实时连接状态显示
|
||||||
|
- 完整的打印功能测试
|
||||||
|
- 样式设置控制
|
||||||
|
- 二维码/条形码打印
|
||||||
|
- 走纸控制
|
||||||
|
- 一键综合测试
|
||||||
|
|
||||||
|
## ✨ 功能特性
|
||||||
|
|
||||||
|
### 🔌 连接管理
|
||||||
|
- 绑定/解绑打印服务
|
||||||
|
- 初始化/关闭打印机
|
||||||
|
- 实时状态监控
|
||||||
|
|
||||||
|
### 📄 打印功能
|
||||||
|
- 文本打印 (printText / printText2)
|
||||||
|
- 二维码生成与打印
|
||||||
|
- 条形码生成与打印
|
||||||
|
- 图片打印支持
|
||||||
|
|
||||||
|
### 🎨 样式控制
|
||||||
|
- 字体大小调整
|
||||||
|
- 粗体设置
|
||||||
|
- 下划线设置
|
||||||
|
- 打印浓度控制
|
||||||
|
|
||||||
|
### 📏 走纸控制
|
||||||
|
- 打印空行
|
||||||
|
- 走纸间距设置
|
||||||
|
- 标签纸支持
|
||||||
|
|
||||||
|
### 🧪 测试工具
|
||||||
|
- 快速打印测试
|
||||||
|
- 单项功能测试
|
||||||
|
- 完整综合测试
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 环境要求
|
||||||
|
|
||||||
|
- Android Studio Hedgehog 或更高版本
|
||||||
|
- JDK 11
|
||||||
|
- Android SDK 24+
|
||||||
|
- 目标设备需预装 `android.bld.PrintManager` 系统服务
|
||||||
|
|
||||||
|
### 编译安装
|
||||||
|
|
||||||
|
#### 方法一:使用自动构建脚本(推荐)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build_release.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
该脚本会自动:
|
||||||
|
- 增加版本号
|
||||||
|
- 清理并编译 Release APK
|
||||||
|
- 复制 APK 到项目根目录
|
||||||
|
|
||||||
|
#### 方法二:手动编译
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew clean assembleRelease
|
||||||
|
```
|
||||||
|
|
||||||
|
生成的 APK 位于:
|
||||||
|
```
|
||||||
|
app/build/outputs/apk/release/PDA_Printer_Test_v{版本号}_release_{日期}.apk
|
||||||
|
```
|
||||||
|
|
||||||
|
### 安装到设备
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb install -r app/build/outputs/apk/release/PDA_Printer_Test_v1.1_2_release_20260624.apk
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📖 使用说明
|
||||||
|
|
||||||
|
### 基本流程
|
||||||
|
|
||||||
|
1. **启动应用** → 打开 PDA 打印机测试应用
|
||||||
|
2. **绑定服务** → 点击"绑定服务"按钮连接打印服务
|
||||||
|
3. **初始化** → 点击"初始化"按钮初始化打印机
|
||||||
|
4. **测试打印** → 使用各项测试按钮或运行完整测试
|
||||||
|
5. **关闭释放** → 完成后点击"关闭打印机"和"解绑服务"
|
||||||
|
|
||||||
|
### 快速测试
|
||||||
|
|
||||||
|
点击 **"快速打印测试"** 按钮可一键完成:
|
||||||
|
```
|
||||||
|
初始化 → 打印测试文本 → 提交打印 → 关闭打印机
|
||||||
|
```
|
||||||
|
|
||||||
|
### 综合测试
|
||||||
|
|
||||||
|
点击 **"运行完整测试"** 按钮将打印包含以下内容的测试单:
|
||||||
|
- 标题(大字体、粗体)
|
||||||
|
- 普通文本示例
|
||||||
|
- 粗体文本示例
|
||||||
|
- 下划线文本示例
|
||||||
|
- 二维码(https://example.com)
|
||||||
|
- 条形码(123456789012)
|
||||||
|
- 分隔线
|
||||||
|
|
||||||
|
## 🏗️ 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
ops_android/
|
||||||
|
├── app/
|
||||||
|
│ └── src/
|
||||||
|
│ └── main/
|
||||||
|
│ ├── aidl/android/bld/
|
||||||
|
│ │ └── IPrintManager.aidl # 打印服务接口定义
|
||||||
|
│ ├── java/com/example/ops_android/
|
||||||
|
│ │ ├── MainActivity.kt # 主界面
|
||||||
|
│ │ └── printer/
|
||||||
|
│ │ └── PrinterManager.kt # 打印机管理器
|
||||||
|
│ └── AndroidManifest.xml
|
||||||
|
├── build_release.sh # 自动构建脚本
|
||||||
|
├── BUILD_INFO.md # 构建信息
|
||||||
|
└── README_PRINTER_TEST.md # 详细文档
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 API 参考
|
||||||
|
|
||||||
|
### PrinterManager 主要方法
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// 连接控制
|
||||||
|
fun bindService(): Boolean
|
||||||
|
fun unbindService()
|
||||||
|
fun initPrinter(): Result<Unit>
|
||||||
|
fun closePrinter(): Result<Unit>
|
||||||
|
|
||||||
|
// 打印内容
|
||||||
|
fun printText(text: String): Result<Unit>
|
||||||
|
fun printText2(text: String): Result<Unit>
|
||||||
|
fun printQR(content: String, size: Int = 6): Result<Unit>
|
||||||
|
fun printBarcode(content: String, type: Int = 0, width: Int = 2, height: Int = 60): Result<Unit>
|
||||||
|
fun printLine(lineCount: Int = 1): Result<Unit>
|
||||||
|
fun start(): Result<Unit> // ⚠️ 必须调用才会实际打印
|
||||||
|
|
||||||
|
// 样式设置
|
||||||
|
fun setFontSize(size: Int): Result<Unit>
|
||||||
|
fun setTextBold(bold: Boolean): Result<Unit>
|
||||||
|
fun setUnderLine(underline: Boolean): Result<Unit>
|
||||||
|
fun setConcentration(level: Int): Result<Unit>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用示例
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val printerManager = PrinterManager(context)
|
||||||
|
|
||||||
|
// 打印文本
|
||||||
|
printerManager.bindService()
|
||||||
|
printerManager.initPrinter()
|
||||||
|
printerManager.printText2("Hello World\n")
|
||||||
|
printerManager.start() // ⚠️ 重要:提交打印
|
||||||
|
printerManager.closePrinter()
|
||||||
|
printerManager.unbindService()
|
||||||
|
|
||||||
|
// 打印二维码
|
||||||
|
printerManager.initPrinter()
|
||||||
|
printerManager.printQR("https://example.com", 6)
|
||||||
|
printerManager.start()
|
||||||
|
printerManager.closePrinter()
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚠️ 注意事项
|
||||||
|
|
||||||
|
1. **必须调用 start()**: 所有打印内容添加后,必须调用 `start()` 方法才会实际出纸
|
||||||
|
2. **服务依赖**: 应用依赖设备预装的 `android.bld.PrintManager` 系统服务
|
||||||
|
3. **资源管理**: 使用完毕后应及时释放打印机资源
|
||||||
|
4. **错误处理**: 所有方法返回 `Result<Unit>`,需要正确处理成功/失败情况
|
||||||
|
|
||||||
|
## 📝 版本历史
|
||||||
|
|
||||||
|
### v1.1 (Build 2) - 2026-06-24
|
||||||
|
- ✨ 完整的打印机测试界面
|
||||||
|
- ✨ 所有打印功能支持
|
||||||
|
- ✨ 实时状态显示
|
||||||
|
- ✨ 综合测试功能
|
||||||
|
- 📦 AIDL 接口集成
|
||||||
|
- 👤 作者信息显示
|
||||||
|
|
||||||
|
### v1.0 (Build 1)
|
||||||
|
- 🎉 初始版本
|
||||||
|
|
||||||
|
## 👤 作者
|
||||||
|
|
||||||
|
**无闻风**
|
||||||
|
|
||||||
|
## 📄 许可证
|
||||||
|
|
||||||
|
本项目仅供内部测试使用
|
||||||
|
|
||||||
|
## 🤝 技术支持
|
||||||
|
|
||||||
|
如有问题或建议,请联系开发团队。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**最后更新**: 2026-06-24
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
# PDA 打印机测试应用
|
||||||
|
|
||||||
|
这是一个用于测试内置 PDA 终端打印机的 Android 应用,通过 `android.bld.PrintManager` 系统服务进行打印控制。
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
### 连接控制
|
||||||
|
- **绑定服务**:连接到系统的打印服务
|
||||||
|
- **初始化打印机**:初始化打印设备
|
||||||
|
- **关闭打印机**:释放打印设备
|
||||||
|
- **解绑服务**:断开打印服务连接
|
||||||
|
|
||||||
|
### 基础打印
|
||||||
|
- **快速打印测试**:一键完成初始化→打印→提交→关闭的完整流程
|
||||||
|
- **printText**:标准文本打印方法
|
||||||
|
- **printText2**:增强文本打印方法
|
||||||
|
- **start()**:提交打印队列,开始实际出纸
|
||||||
|
|
||||||
|
### 样式设置
|
||||||
|
- **字体大小**:调整打印文字大小
|
||||||
|
- **粗体**:设置文字粗体
|
||||||
|
- **下划线**:添加文字下划线
|
||||||
|
- **浓度**:调整打印浓度
|
||||||
|
|
||||||
|
### 二维码与条形码
|
||||||
|
- **打印二维码**:生成并打印 QR 码
|
||||||
|
- **打印条形码**:生成并打印一维条形码
|
||||||
|
|
||||||
|
### 走纸控制
|
||||||
|
- **打印空行**:添加空白行
|
||||||
|
- **走纸间距**:设置纸张走纸距离
|
||||||
|
|
||||||
|
### 综合测试
|
||||||
|
- **运行完整测试**:自动执行完整的功能测试流程,包含所有打印特性
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 基本流程
|
||||||
|
|
||||||
|
1. **绑定服务** → 连接到打印服务
|
||||||
|
2. **初始化** → 初始化打印机硬件
|
||||||
|
3. **设置样式**(可选)→ 设置字体、粗体等
|
||||||
|
4. **添加内容** → 调用 printText/printQR 等方法
|
||||||
|
5. **提交打印** → 调用 start() 开始实际打印
|
||||||
|
6. **关闭打印机** → 完成后释放资源
|
||||||
|
|
||||||
|
### 快速测试
|
||||||
|
|
||||||
|
点击 **"快速打印测试"** 按钮可以一键完成整个流程,打印 "Hello Printer!" 测试文本。
|
||||||
|
|
||||||
|
### 完整测试
|
||||||
|
|
||||||
|
点击 **"运行完整测试"** 按钮将执行包含以下内容的完整测试:
|
||||||
|
- 标题(大字体、粗体)
|
||||||
|
- 普通文本
|
||||||
|
- 粗体文本
|
||||||
|
- 下划线文本
|
||||||
|
- 二维码
|
||||||
|
- 条形码
|
||||||
|
- 分隔线
|
||||||
|
|
||||||
|
## 代码结构
|
||||||
|
|
||||||
|
```
|
||||||
|
app/src/main/
|
||||||
|
├── aidl/android/bld/
|
||||||
|
│ └── IPrintManager.aidl # AIDL 接口定义
|
||||||
|
├── java/com/example/ops_android/
|
||||||
|
│ ├── MainActivity.kt # 主界面和测试 UI
|
||||||
|
│ └── printer/
|
||||||
|
│ └── PrinterManager.kt # 打印机封装类
|
||||||
|
```
|
||||||
|
|
||||||
|
## AIDL 接口
|
||||||
|
|
||||||
|
系统服务 `android.bld.PrintManager` 提供的主要方法:
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `initPrinter()` | 初始化打印机 |
|
||||||
|
| `closePrinter()` | 关闭打印机 |
|
||||||
|
| `printText(text)` | 打印文本 |
|
||||||
|
| `printText2(text)` | 打印文本(增强版) |
|
||||||
|
| `printQR(content, size)` | 打印二维码 |
|
||||||
|
| `printBarcode(content, type, width, height)` | 打印条形码 |
|
||||||
|
| `printLine(count)` | 打印空行 |
|
||||||
|
| `start()` | **重要:提交打印,开始出纸** |
|
||||||
|
| `setFontSize(size)` | 设置字体大小 |
|
||||||
|
| `setTextBold(bold)` | 设置粗体 |
|
||||||
|
| `setUnderLine(underline)` | 设置下划线 |
|
||||||
|
| `setConcentration(level)` | 设置浓度 |
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **必须调用 start()**:所有打印内容添加到队列后,必须调用 `start()` 才会实际打印出纸
|
||||||
|
2. **服务绑定**:需要先绑定服务并初始化打印机才能使用打印功能
|
||||||
|
3. **资源释放**:使用完毕后应调用 `closePrinter()` 和 `unbindService()` 释放资源
|
||||||
|
4. **错误处理**:所有方法返回 `Result<Unit>` 类型,使用 `fold` 或 `onSuccess`/`onFailure` 处理结果
|
||||||
|
5. **系统服务**:此应用依赖于设备预装的 `android.bld.PrintManager` 系统服务,普通 Android 设备无此服务
|
||||||
|
|
||||||
|
## 编译要求
|
||||||
|
|
||||||
|
- Android SDK 24+
|
||||||
|
- Kotlin
|
||||||
|
- Jetpack Compose
|
||||||
|
- AIDL 支持(已在 build.gradle.kts 中启用)
|
||||||
|
|
||||||
|
## 测试环境
|
||||||
|
|
||||||
|
此应用专为内置 PDA 打印机的定制 Android 设备设计,需要设备厂商在 `/system/framework/` 下预装 `android.bld.PrintManager` 服务。
|
||||||
|
|
||||||
|
## 状态显示
|
||||||
|
|
||||||
|
应用顶部的状态卡片会实时显示:
|
||||||
|
- 连接状态(绿色:已连接,红色:未连接)
|
||||||
|
- 操作结果
|
||||||
|
- 错误信息
|
||||||
|
|
||||||
|
## 示例代码
|
||||||
|
|
||||||
|
### 基础使用
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val printerManager = PrinterManager(context)
|
||||||
|
|
||||||
|
// 绑定服务
|
||||||
|
printerManager.bindService()
|
||||||
|
|
||||||
|
// 打印
|
||||||
|
printerManager.initPrinter()
|
||||||
|
printerManager.printText2("Hello World\n")
|
||||||
|
printerManager.start()
|
||||||
|
printerManager.closePrinter()
|
||||||
|
|
||||||
|
// 解绑
|
||||||
|
printerManager.unbindService()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 样式控制
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
printerManager.setFontSize(32)
|
||||||
|
printerManager.setTextBold(true)
|
||||||
|
printerManager.printText2("标题\n")
|
||||||
|
printerManager.setTextBold(false)
|
||||||
|
printerManager.printText2("内容\n")
|
||||||
|
printerManager.start()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 打印二维码
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
printerManager.initPrinter()
|
||||||
|
printerManager.printQR("https://example.com", 6)
|
||||||
|
printerManager.start()
|
||||||
|
printerManager.closePrinter()
|
||||||
|
```
|
||||||
+32
-2
@@ -1,3 +1,6 @@
|
|||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
alias(libs.plugins.kotlin.compose)
|
alias(libs.plugins.kotlin.compose)
|
||||||
@@ -15,10 +18,14 @@ android {
|
|||||||
applicationId = "com.example.ops_android"
|
applicationId = "com.example.ops_android"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 1
|
versionCode = 2
|
||||||
versionName = "1.0"
|
versionName = "1.1"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
// 作者信息
|
||||||
|
buildConfigField("String", "AUTHOR", "\"无闻风\"")
|
||||||
|
buildConfigField("String", "BUILD_DATE", "\"${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@@ -26,6 +33,15 @@ android {
|
|||||||
optimization {
|
optimization {
|
||||||
enable = false
|
enable = false
|
||||||
}
|
}
|
||||||
|
isMinifyEnabled = false
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix = ".debug"
|
||||||
|
versionNameSuffix = "-debug"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@@ -34,6 +50,20 @@ android {
|
|||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose = true
|
compose = true
|
||||||
|
aidl = true
|
||||||
|
buildConfig = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
androidComponents {
|
||||||
|
onVariants { variant ->
|
||||||
|
variant.outputs.forEach { output ->
|
||||||
|
val versionName = "1.1"
|
||||||
|
val versionCode = "2"
|
||||||
|
val buildType = variant.buildType
|
||||||
|
val date = SimpleDateFormat("yyyyMMdd").format(Date())
|
||||||
|
output.outputFileName.set("PDA_Printer_Test_v${versionName}_${versionCode}_${buildType}_${date}.apk")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
@@ -4,44 +4,389 @@ import android.os.Bundle
|
|||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.ops_android.printer.PrinterManager
|
||||||
import com.example.ops_android.ui.theme.Ops_androidTheme
|
import com.example.ops_android.ui.theme.Ops_androidTheme
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
private lateinit var printerManager: PrinterManager
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
printerManager = PrinterManager(this)
|
||||||
|
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
Ops_androidTheme {
|
Ops_androidTheme {
|
||||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||||
Greeting(
|
PrinterTestScreen(
|
||||||
name = "Android",
|
printerManager = printerManager,
|
||||||
modifier = Modifier.padding(innerPadding)
|
modifier = Modifier.padding(innerPadding)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
override fun onDestroy() {
|
||||||
fun Greeting(name: String, modifier: Modifier = Modifier) {
|
super.onDestroy()
|
||||||
Text(
|
printerManager.unbindService()
|
||||||
text = "Hello $name!",
|
|
||||||
modifier = modifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Composable
|
|
||||||
fun GreetingPreview() {
|
|
||||||
Ops_androidTheme {
|
|
||||||
Greeting("Android")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PrinterTestScreen(
|
||||||
|
printerManager: PrinterManager,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
var statusMessage by remember { mutableStateOf("未连接打印服务") }
|
||||||
|
var isConnected by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp)
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
|
) {
|
||||||
|
// 标题
|
||||||
|
Text(
|
||||||
|
text = "PDA 打印机测试",
|
||||||
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
|
modifier = Modifier.padding(bottom = 8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 版本信息
|
||||||
|
Text(
|
||||||
|
text = "v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE}) - ${BuildConfig.AUTHOR}",
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
modifier = Modifier.padding(bottom = 8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 状态显示
|
||||||
|
Card(
|
||||||
|
colors = CardDefaults.cardColors(
|
||||||
|
containerColor = if (isConnected)
|
||||||
|
MaterialTheme.colorScheme.primaryContainer
|
||||||
|
else
|
||||||
|
MaterialTheme.colorScheme.errorContainer
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = statusMessage,
|
||||||
|
modifier = Modifier.padding(16.dp),
|
||||||
|
style = MaterialTheme.typography.bodyMedium
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
|
||||||
|
// 连接控制区
|
||||||
|
Text("连接控制", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
val success = printerManager.bindService()
|
||||||
|
isConnected = success
|
||||||
|
statusMessage = if (success) "正在连接打印服务..." else "连接失败"
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("绑定服务")
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.initPrinter().fold(
|
||||||
|
onSuccess = { statusMessage = "打印机初始化成功" },
|
||||||
|
onFailure = { statusMessage = "初始化失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("初始化")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.closePrinter().fold(
|
||||||
|
onSuccess = { statusMessage = "打印机已关闭" },
|
||||||
|
onFailure = { statusMessage = "关闭失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("关闭打印机")
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.unbindService()
|
||||||
|
isConnected = false
|
||||||
|
statusMessage = "服务已解绑"
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("解绑服务")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
|
||||||
|
// 基础打印测试
|
||||||
|
Text("基础打印测试", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.quickPrintText("Hello Printer!\n测试打印\n").fold(
|
||||||
|
onSuccess = { statusMessage = "快速打印成功" },
|
||||||
|
onFailure = { statusMessage = "打印失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text("快速打印测试")
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.printText("使用 printText\n").fold(
|
||||||
|
onSuccess = { statusMessage = "printText 调用成功" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("printText")
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.printText2("使用 printText2\n").fold(
|
||||||
|
onSuccess = { statusMessage = "printText2 调用成功" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("printText2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.start().fold(
|
||||||
|
onSuccess = { statusMessage = "开始打印(出纸)" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text("start() - 提交打印")
|
||||||
|
}
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
|
||||||
|
// 样式测试
|
||||||
|
Text("样式设置", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.setFontSize(24).fold(
|
||||||
|
onSuccess = { statusMessage = "字体大小已设置" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("大字体")
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.setTextBold(true).fold(
|
||||||
|
onSuccess = { statusMessage = "已设置粗体" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("粗体")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.setUnderLine(true).fold(
|
||||||
|
onSuccess = { statusMessage = "已设置下划线" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("下划线")
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.setConcentration(5).fold(
|
||||||
|
onSuccess = { statusMessage = "浓度已设置" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("浓度")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
|
||||||
|
// 二维码/条形码测试
|
||||||
|
Text("二维码与条形码", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.printQR("https://example.com", 6).fold(
|
||||||
|
onSuccess = { statusMessage = "二维码已加入队列" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
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)) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.printLine(3).fold(
|
||||||
|
onSuccess = { statusMessage = "打印空行" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("打印3空行")
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
printerManager.setFeedPaperSpace(100).fold(
|
||||||
|
onSuccess = { statusMessage = "走纸间距已设置" },
|
||||||
|
onFailure = { statusMessage = "失败: ${it.message}" }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
) {
|
||||||
|
Text("走纸间距")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
|
||||||
|
// 综合测试
|
||||||
|
Text("综合测试", style = MaterialTheme.typography.titleMedium)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
runComprehensiveTest(printerManager) { msg -> statusMessage = msg }
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.secondary
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("运行完整测试")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runComprehensiveTest(
|
||||||
|
printerManager: PrinterManager,
|
||||||
|
onStatus: (String) -> Unit
|
||||||
|
) {
|
||||||
|
onStatus("开始综合测试...")
|
||||||
|
|
||||||
|
printerManager.initPrinter().onFailure {
|
||||||
|
onStatus("初始化失败: ${it.message}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
printerManager.setFontSize(32)
|
||||||
|
printerManager.setTextBold(true)
|
||||||
|
printerManager.printText2("=== 打印测试 ===\n")
|
||||||
|
|
||||||
|
// 普通文本
|
||||||
|
printerManager.setFontSize(24)
|
||||||
|
printerManager.setTextBold(false)
|
||||||
|
printerManager.printText2("普通文本测试\n")
|
||||||
|
|
||||||
|
// 粗体文本
|
||||||
|
printerManager.setTextBold(true)
|
||||||
|
printerManager.printText2("粗体文本测试\n")
|
||||||
|
printerManager.setTextBold(false)
|
||||||
|
|
||||||
|
// 下划线文本
|
||||||
|
printerManager.setUnderLine(true)
|
||||||
|
printerManager.printText2("下划线文本测试\n")
|
||||||
|
printerManager.setUnderLine(false)
|
||||||
|
|
||||||
|
// 空行
|
||||||
|
printerManager.printLine(1)
|
||||||
|
|
||||||
|
// 二维码
|
||||||
|
printerManager.printText2("二维码测试:\n")
|
||||||
|
printerManager.printQR("https://example.com", 6)
|
||||||
|
printerManager.printLine(1)
|
||||||
|
|
||||||
|
// 条形码
|
||||||
|
printerManager.printText2("条形码测试:\n")
|
||||||
|
printerManager.printBarcode("123456789012", 0, 2, 60)
|
||||||
|
printerManager.printLine(3)
|
||||||
|
|
||||||
|
// 分隔线
|
||||||
|
printerManager.printText2("--------------------------------\n")
|
||||||
|
printerManager.printText2("测试完成\n")
|
||||||
|
printerManager.printLine(2)
|
||||||
|
|
||||||
|
// 提交打印
|
||||||
|
printerManager.start().fold(
|
||||||
|
onSuccess = { onStatus("综合测试完成,开始打印") },
|
||||||
|
onFailure = { onStatus("提交打印失败: ${it.message}") }
|
||||||
|
)
|
||||||
|
|
||||||
|
printerManager.closePrinter()
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
package com.example.ops_android.printer
|
||||||
|
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.ServiceConnection
|
||||||
|
import android.os.IBinder
|
||||||
|
import android.util.Log
|
||||||
|
import android.bld.IPrintManager
|
||||||
|
|
||||||
|
class PrinterManager(private val context: Context) {
|
||||||
|
private var printService: IPrintManager? = null
|
||||||
|
private var isBound = false
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "PrinterManager"
|
||||||
|
private const val PRINT_SERVICE_ACTION = "android.bld.PrintManager"
|
||||||
|
private const val PRINT_SERVICE_PACKAGE = "android.bld"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val serviceConnection = object : ServiceConnection {
|
||||||
|
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||||
|
printService = IPrintManager.Stub.asInterface(service)
|
||||||
|
isBound = true
|
||||||
|
Log.d(TAG, "Print service connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onServiceDisconnected(name: ComponentName?) {
|
||||||
|
printService = null
|
||||||
|
isBound = false
|
||||||
|
Log.d(TAG, "Print service disconnected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bindService(): Boolean {
|
||||||
|
return try {
|
||||||
|
val intent = Intent(PRINT_SERVICE_ACTION).apply {
|
||||||
|
setPackage(PRINT_SERVICE_PACKAGE)
|
||||||
|
}
|
||||||
|
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Failed to bind print service", e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unbindService() {
|
||||||
|
if (isBound) {
|
||||||
|
context.unbindService(serviceConnection)
|
||||||
|
isBound = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基础连接方法
|
||||||
|
fun initPrinter(): Result<Unit> = runCatching {
|
||||||
|
printService?.initPrinter() ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun closePrinter(): Result<Unit> = runCatching {
|
||||||
|
printService?.closePrinter() ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印方法
|
||||||
|
fun printText(text: String): Result<Unit> = runCatching {
|
||||||
|
printService?.printText(text) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printText2(text: String): Result<Unit> = runCatching {
|
||||||
|
printService?.printText2(text) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printQR(content: String, size: Int = 6): Result<Unit> = runCatching {
|
||||||
|
printService?.printQR(content, size) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printBarcode(content: String, type: Int = 0, width: Int = 2, height: Int = 60): Result<Unit> = runCatching {
|
||||||
|
printService?.printBarcode(content, type, width, height) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printBitmap(bitmap: ByteArray, width: Int, height: Int): Result<Unit> = runCatching {
|
||||||
|
printService?.printBitmap(bitmap, width, height) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printLine(lineCount: Int = 1): Result<Unit> = runCatching {
|
||||||
|
printService?.printLine(lineCount) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start(): Result<Unit> = runCatching {
|
||||||
|
printService?.start() ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 样式设置方法
|
||||||
|
fun setFontSize(size: Int): Result<Unit> = runCatching {
|
||||||
|
printService?.setFontSize(size) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setTextBold(bold: Boolean): Result<Unit> = runCatching {
|
||||||
|
printService?.setTextBold(bold) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setUnderLine(underline: Boolean): Result<Unit> = runCatching {
|
||||||
|
printService?.setUnderLine(underline) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setConcentration(level: Int): Result<Unit> = runCatching {
|
||||||
|
printService?.setConcentration(level) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 走纸控制
|
||||||
|
fun setFeedPaperSpace(space: Int): Result<Unit> = runCatching {
|
||||||
|
printService?.setFeedPaperSpace(space) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setUnwindPaperLen(length: Int): Result<Unit> = runCatching {
|
||||||
|
printService?.setUnwindPaperLen(length) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标签纸控制
|
||||||
|
fun printEnableMark(enable: Boolean): Result<Unit> = runCatching {
|
||||||
|
printService?.printEnableMark(enable) ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printGoToNextMark(): Result<Unit> = runCatching {
|
||||||
|
printService?.printGoToNextMark() ?: throw Exception("Print service not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 便捷组合方法
|
||||||
|
fun quickPrintText(text: String): Result<Unit> = runCatching {
|
||||||
|
initPrinter().getOrThrow()
|
||||||
|
printText2(text).getOrThrow()
|
||||||
|
start().getOrThrow()
|
||||||
|
closePrinter().getOrThrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isServiceConnected(): Boolean = isBound && printService != null
|
||||||
|
}
|
||||||
Executable
+66
@@ -0,0 +1,66 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 自动构建脚本 - 自动增加版本号并编译APK
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
echo -e "${BLUE}==================================${NC}"
|
||||||
|
echo -e "${BLUE} PDA 打印机测试应用 - 自动构建${NC}"
|
||||||
|
echo -e "${BLUE}==================================${NC}"
|
||||||
|
|
||||||
|
# 读取当前版本
|
||||||
|
BUILD_FILE="app/build.gradle.kts"
|
||||||
|
CURRENT_VERSION=$(grep "versionCode = " "$BUILD_FILE" | sed 's/.*versionCode = //' | sed 's/[^0-9]//g')
|
||||||
|
CURRENT_VERSION_NAME=$(grep "versionName = " "$BUILD_FILE" | sed 's/.*versionName = "//' | sed 's/".*//')
|
||||||
|
|
||||||
|
echo -e "${GREEN}当前版本: v${CURRENT_VERSION_NAME} (Build ${CURRENT_VERSION})${NC}"
|
||||||
|
|
||||||
|
# 计算新版本
|
||||||
|
NEW_VERSION=$((CURRENT_VERSION + 1))
|
||||||
|
# 计算新版本名称 (简单递增小版本号)
|
||||||
|
IFS='.' read -r major minor <<< "$CURRENT_VERSION_NAME"
|
||||||
|
NEW_MINOR=$((minor + 1))
|
||||||
|
NEW_VERSION_NAME="${major}.${NEW_MINOR}"
|
||||||
|
|
||||||
|
echo -e "${GREEN}新版本: v${NEW_VERSION_NAME} (Build ${NEW_VERSION})${NC}"
|
||||||
|
|
||||||
|
# 更新版本号
|
||||||
|
sed -i.bak "s/versionCode = $CURRENT_VERSION/versionCode = $NEW_VERSION/" "$BUILD_FILE"
|
||||||
|
sed -i.bak "s/versionName = \"$CURRENT_VERSION_NAME\"/versionName = \"$NEW_VERSION_NAME\"/" "$BUILD_FILE"
|
||||||
|
rm -f "${BUILD_FILE}.bak"
|
||||||
|
|
||||||
|
echo -e "${GREEN}✓ 版本号已更新${NC}"
|
||||||
|
|
||||||
|
# 清理并编译
|
||||||
|
echo -e "${BLUE}开始编译...${NC}"
|
||||||
|
./gradlew clean assembleRelease --no-daemon
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}==================================${NC}"
|
||||||
|
echo -e "${GREEN} ✓ 编译成功!${NC}"
|
||||||
|
echo -e "${GREEN}==================================${NC}"
|
||||||
|
|
||||||
|
# 查找生成的APK
|
||||||
|
APK_PATH=$(find app/build/outputs/apk/release -name "*.apk" -type f | head -n 1)
|
||||||
|
|
||||||
|
if [ -n "$APK_PATH" ]; then
|
||||||
|
APK_SIZE=$(du -h "$APK_PATH" | cut -f1)
|
||||||
|
echo -e "${GREEN}APK 文件: ${APK_PATH}${NC}"
|
||||||
|
echo -e "${GREEN}文件大小: ${APK_SIZE}${NC}"
|
||||||
|
|
||||||
|
# 可选:复制到项目根目录
|
||||||
|
cp "$APK_PATH" "./PDA_Printer_Test_latest.apk"
|
||||||
|
echo -e "${GREEN}✓ 已复制到: ./PDA_Printer_Test_latest.apk${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ 编译失败${NC}"
|
||||||
|
# 恢复版本号
|
||||||
|
sed -i.bak "s/versionCode = $NEW_VERSION/versionCode = $CURRENT_VERSION/" "$BUILD_FILE"
|
||||||
|
sed -i.bak "s/versionName = \"$NEW_VERSION_NAME\"/versionName = \"$CURRENT_VERSION_NAME\"/" "$BUILD_FILE"
|
||||||
|
rm -f "${BUILD_FILE}.bak"
|
||||||
|
echo -e "${RED}已恢复原版本号${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user