StandAPP/app/src/main/java/com/stand/standapp/AndroidInterface.kt

184 lines
6.0 KiB
Kotlin

package com.stand.standapp
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.webkit.JavascriptInterface
import android.widget.Toast
import android.print.PrintAttributes
import android.print.PrintManager
import com.stand.standapp.R
class AndroidInterface(private val activity: MainActivity) {
/**
* JS 调用:标准系统打印 (PDF/网络打印机/AirPrint)
* 适用于打印精美的 A4 单据或页面
*/
@JavascriptInterface
fun printPage() {
Handler(Looper.getMainLooper()).post {
try {
val printManager = activity.getSystemService(Context.PRINT_SERVICE) as PrintManager
// 获取 WebView 的打印适配器
val webView = activity.getAgentWeb()?.webCreator?.getWebView()
if (webView == null) {
Toast.makeText(activity, "WebView 未就绪", Toast.LENGTH_SHORT).show()
return@post
}
val printAdapter = webView.createPrintDocumentAdapter("Document")
val jobName = activity.getString(R.string.app_name) + " Print Job"
printManager.print(jobName, printAdapter, PrintAttributes.Builder().build())
} catch (e: Exception) {
Log.e("Print", "系统打印失败", e)
Toast.makeText(activity, "打印服务启动失败", Toast.LENGTH_SHORT).show()
}
}
}
/**
* JS 调用:原始数据打印
* 适用于热敏小票打印机 (蓝牙、USB、网络)
* @param data 可以是 JSON 字符串,包含打印的指令或文本
*/
@JavascriptInterface
fun printRawData(data: String) {
try {
Log.d("Print", "收到 H5 原始打印数据: $data")
Handler(Looper.getMainLooper()).post {
try {
// 这里可以弹出一个选择框让用户选择打印机,或者根据配置自动连接
Toast.makeText(activity, "H5指令打印: $data", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Log.e("Print", "Toast显示失败", e)
}
}
} catch (e: Exception) {
Log.e("Print", "指令解析失败", e)
}
}
/**
* JS 调用:在线升级 (手动触发检查)
*/
@JavascriptInterface
fun startUpdate(apkUrl: String) {
Handler(Looper.getMainLooper()).post {
try {
UpdateManager(activity).checkUpdate()
} catch (e: Exception) {
Log.e("Update", "启动更新检查失败", e)
}
}
}
/**
* JS 调用:退出应用
*/
@JavascriptInterface
fun exitApp() {
Handler(Looper.getMainLooper()).post {
try {
activity.showExitDialog()
} catch (e: Exception) {
Log.e("App", "显示退出弹窗失败", e)
activity.finish()
}
}
}
/**
* 获取版本号给 H5 判断是否需要升级
*/
@JavascriptInterface
fun getVersionName(): String {
return try {
val packageInfo = activity.packageManager.getPackageInfo(activity.packageName, 0)
packageInfo.versionName ?: "1.0.0"
} catch (e: Exception) {
"1.0.0"
}
}
/**
* JS 调用:获取“关于”信息
*/
@JavascriptInterface
fun getAboutInfo(): String {
return try {
val packageInfo = activity.packageManager.getPackageInfo(activity.packageName, 0)
val json = org.json.JSONObject()
json.put("appName", activity.getString(R.string.app_name))
json.put("versionName", packageInfo.versionName)
json.put("model", android.os.Build.MODEL)
json.put("osVersion", android.os.Build.VERSION.RELEASE)
json.toString()
} catch (e: Exception) {
"{ \"appName\": \"StandApp\", \"versionName\": \"1.0.0\" }"
}
}
/**
* JS 调用:保存消息记录
*/
@JavascriptInterface
fun saveMessage(message: String) {
try {
val prefs = activity.getSharedPreferences("msg_records", Context.MODE_PRIVATE)
val currentMsgs = prefs.getString("history", "") ?: ""
val updatedMsgs = if (currentMsgs.isEmpty()) message else "$message|---|$currentMsgs"
// 限制保存最近5000条
val list = updatedMsgs.split("|---|").take(5000)
prefs.edit().putString("history", list.joinToString("|---|")).apply()
} catch (e: Exception) {
Log.e("Storage", "消息保存异常", e)
}
}
/**
* JS 调用:获取消息记录
*/
@JavascriptInterface
fun getMessages(): String {
return try {
val prefs = activity.getSharedPreferences("msg_records", Context.MODE_PRIVATE)
prefs.getString("history", "") ?: ""
} catch (e: Exception) {
""
}
}
/**
* JS 调用:清空消息记录
*/
@JavascriptInterface
fun clearMessages() {
try {
activity.getSharedPreferences("msg_records", Context.MODE_PRIVATE).edit().clear().apply()
Handler(Looper.getMainLooper()).post {
Toast.makeText(activity, "记录已清空", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
Log.e("Storage", "清空记录异常", e)
}
}
/**
* JS 回调:告知 App 页面加载完成
*/
@JavascriptInterface
fun onPageFinished() {
Handler(Looper.getMainLooper()).post {
try {
activity.cancelTimeoutTimer()
activity.findViewById<android.view.View>(R.id.loading_layout)?.visibility = android.view.View.GONE
} catch (e: Exception) {
Log.e("UI", "隐藏加载布局失败", e)
}
}
}
}