From 2d7b00be4539e5f773d6a83e959185191345206c Mon Sep 17 00:00:00 2001 From: "844143714@qq,com" <844143714@qq,com> Date: Thu, 30 Apr 2026 01:30:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=BA=94=E7=94=A8=E9=80=80?= =?UTF-8?q?=E5=87=BA=E4=B8=8E=E5=BC=82=E5=B8=B8=E9=94=80=E6=AF=81=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E3=80=81=E9=A1=B9=E7=9B=AE=E6=80=A7=E8=83=BD=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kingway/ptt/CallBackResolution.java | 21 +++--- .../java/com/stand/standapp/LoginActivity.kt | 67 +++---------------- .../java/com/stand/standapp/MainActivity.kt | 15 +---- .../java/com/stand/standapp/MyApplication.kt | 3 + .../com/stand/standapp/utils/AppKiller.kt | 58 ++++++++++++++++ .../com/stand/standapp/utils/GpioManager.kt | 2 + 6 files changed, 84 insertions(+), 82 deletions(-) create mode 100644 app/src/main/java/com/stand/standapp/utils/AppKiller.kt diff --git a/app/src/main/java/com/example/kingway/ptt/CallBackResolution.java b/app/src/main/java/com/example/kingway/ptt/CallBackResolution.java index 0358f9a..107a36d 100644 --- a/app/src/main/java/com/example/kingway/ptt/CallBackResolution.java +++ b/app/src/main/java/com/example/kingway/ptt/CallBackResolution.java @@ -97,7 +97,7 @@ public class CallBackResolution { case "80"://返回群组信息 Log.d(TAG, "at_OEM_AT_cb get group info: " + lisHex); - String strGroup = ""; + StringBuilder strGroup = new StringBuilder(); String groupId = lisHex.get(6) + "" + lisHex.get(7) + "" + lisHex.get(8) + "" + lisHex.get(9); int groupNo = Integer.valueOf((lisHex.get(4) + "" + lisHex.get(5)), 16); int groupCount = Integer.valueOf((lisHex.get(10) + "" + lisHex.get(11)), 16); @@ -108,9 +108,9 @@ public class CallBackResolution { size = (size / 2) - 1; for (int i = 0; i < size; i++) { if (i == 0) { - strGroup += ngx + lisHex.get(i + numB) + "" + lisHex.get(i + numB - 1); + strGroup.append(ngx).append(lisHex.get(i + numB)).append(lisHex.get(i + numB - 1)); } else { - strGroup += ngx + lisHex.get(i + numB + 1) + "" + lisHex.get(i + numB); + strGroup.append(ngx).append(lisHex.get(i + numB + 1)).append(lisHex.get(i + numB)); numB = numB + 1; } } @@ -118,7 +118,7 @@ public class CallBackResolution { e.printStackTrace(); } finally { String tempTxt = ""; - tempTxt = unicodeToString(strGroup); + tempTxt = unicodeToString(strGroup.toString()); Log.i(TAG, " 组名称 " + tempTxt); CallBackUtil.callBackGroupInfo(groupId, tempTxt, groupNo, groupCount); Log.d(TAG, "at_OEM_AT_cb group info groupId: " + groupId + ", groupNo: " + groupNo+", groupCount: " +groupCount); @@ -129,7 +129,7 @@ public class CallBackResolution { break; case "81"://返回群成员信息 - String groupMemberName = ""; + StringBuilder groupMemberName = new StringBuilder(); String status = lisHex.get(1); boolean haveVideo = lisHex.get(10).equals("01") ? true : false; String memberId = lisHex.get(6) + "" + lisHex.get(7) + "" + lisHex.get(8) + "" + lisHex.get(9); @@ -141,16 +141,16 @@ public class CallBackResolution { size = (size / 2) - 1; for (int i = 0; i < size; i++) { if (i == 0) { - groupMemberName += ngx + lisHex.get(i + numB) + "" + lisHex.get(i + numB - 1); + groupMemberName.append(ngx).append(lisHex.get(i + numB)).append(lisHex.get(i + numB - 1)); } else { - groupMemberName += ngx + lisHex.get(i + numB + 1) + "" + lisHex.get(i + numB); + groupMemberName.append(ngx).append(lisHex.get(i + numB + 1)).append(lisHex.get(i + numB)); numB = numB + 1; } } } catch (Exception e) { e.printStackTrace(); } finally { - String tempTxt = unicodeToString(groupMemberName); + String tempTxt = unicodeToString(groupMemberName.toString()); GroupMemberInfoDto infoDto = new GroupMemberInfoDto(memberId, tempTxt, status, memberNo, haveVideo); if (memberNo == 1) memberInfoDtos.clear(); memberInfoDtos.add(infoDto); @@ -461,10 +461,11 @@ public class CallBackResolution { } catch (Exception e) { e.printStackTrace(); } finally { - String tempTxt = ""; + StringBuilder sb = new StringBuilder(); for (int k = 0; k < strings.size(); k++) { - tempTxt += unicode(strings.get(k)); + sb.append(unicode(strings.get(k))); } + String tempTxt = sb.toString(); Log.i(TAG,"at_Play_TTS_cb " + tempTxt); if (tempTxt.contains("已登录")) { String showName = tempTxt.substring(3, tempTxt.length()); diff --git a/app/src/main/java/com/stand/standapp/LoginActivity.kt b/app/src/main/java/com/stand/standapp/LoginActivity.kt index 3300508..1d160ef 100644 --- a/app/src/main/java/com/stand/standapp/LoginActivity.kt +++ b/app/src/main/java/com/stand/standapp/LoginActivity.kt @@ -65,9 +65,7 @@ class LoginActivity : AppCompatActivity() { // 4. 退出按钮 btnExit.setOnClickListener { - fullCleanup() - finishAffinity() - android.os.Process.killProcess(android.os.Process.myPid()) + com.stand.standapp.utils.AppKiller.killApp(this) } // 5. 彩蛋:点击底部版权 10 次进入开发者模式 @@ -148,18 +146,17 @@ class LoginActivity : AppCompatActivity() { } catch (e: Exception) { Timber.tag("PTT").e(e, "PTT init error") } - Thread { + + Toast.makeText(this@LoginActivity, "PTT初始化中...", Toast.LENGTH_SHORT).show() + + // 使用 Handler 替代硬编码 Thread.sleep,避免阻塞或随意开辟线程 + android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({ try { - Thread.sleep(500) - runOnUiThread { - Toast.makeText(this@LoginActivity, "PTT初始化中", Toast.LENGTH_SHORT).show() - } - Thread.sleep(3000) com.example.kingway.ptt.SendAtUtil.toLogin("gzzdweb01", "123456", "61.243.1.123", 1, 1) } catch (e: Exception) { Timber.tag("PTT").e(e, "PTT login error") } - }.start() + }, 1500) // 2. 启动硬件 GPIO 监听 try { @@ -242,57 +239,9 @@ class LoginActivity : AppCompatActivity() { .setTitle("提示") .setMessage("确定要退出应用吗?") .setPositiveButton("确定") { _, _ -> - fullCleanup() - finishAffinity() - Process.killProcess(Process.myPid()) + com.stand.standapp.utils.AppKiller.killApp(this) } .setNegativeButton("取消", null) .show() } - - private fun fullCleanup() { - pttLogoutAndDestroy() - } - - private fun pttLogoutAndDestroy() { - try { - com.example.kingway.ptt.SendAtUtil.toCancelLogin() - } catch (e: Exception) { - Timber.tag("LoginActivity").e(e, "PTT cancel failed") - } - try { - com.example.kingway.ptt.SendAtUtil.toLogout() - Timber.tag("LoginActivity").i("PTT logout sent") - } catch (e: Exception) { - Timber.tag("LoginActivity").e(e, "PTT logout failed") - } - try { - com.stand.standapp.utils.GpioManager.stopListening() - } catch (e: Exception) { - Timber.tag("LoginActivity").e(e, "GPIO stop failed") - } - try { - com.stand.standapp.utils.GpioManager.stopListening() - } catch (e: Exception) { - Timber.tag("LoginActivity").e(e, "GPIO stop failed") - } - try { -// MyApplication.destroy() - Timber.tag("LoginActivity").i("PTT native destroyed") - } catch (e: Exception) { - Timber.tag("LoginActivity").e(e, "PTT destroy failed") - } - try { -// PrinterManager.shutdown() - Timber.tag("LoginActivity").i("Printer shut down") - } catch (e: Exception) { - Timber.tag("LoginActivity").e(e, "Printer shutdown failed") - } - try { - com.stand.standapp.utils.LogManager.shutdown() - Timber.tag("LoginActivity").i("LogManager shut down") - } catch (e: Exception) { - Timber.tag("LoginActivity").e(e, "LogManager shutdown failed") - } - } } diff --git a/app/src/main/java/com/stand/standapp/MainActivity.kt b/app/src/main/java/com/stand/standapp/MainActivity.kt index 0e625f2..6ddc00b 100644 --- a/app/src/main/java/com/stand/standapp/MainActivity.kt +++ b/app/src/main/java/com/stand/standapp/MainActivity.kt @@ -61,16 +61,7 @@ class MainActivity : AppCompatActivity() { .setMessage("您的 PTT 账号已在其他设备登录,当前设备已被迫下线。\n请点击确认退出并重新登录。") .setCancelable(false) .setPositiveButton("确认") { _, _ -> - try { - com.example.kingway.ptt.SendAtUtil.toLogout() -// com.example.kingway.ptt.MyApplication.destroy() - com.stand.standapp.utils.GpioManager.stopListening() - } catch (_: Exception) {} - val pm = ctx.packageManager - val intent = pm.getLaunchIntentForPackage(ctx.packageName) - intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) - ctx.startActivity(intent) - android.os.Process.killProcess(android.os.Process.myPid()) + com.stand.standapp.utils.AppKiller.killApp(ctx) } .show() } @@ -263,9 +254,7 @@ class MainActivity : AppCompatActivity() { .setTitle("提示") .setMessage("确定要退出应用吗?") .setPositiveButton("确定") { _, _ -> - pttLogoutAndDestroy() - finishAffinity() - android.os.Process.killProcess(android.os.Process.myPid()) + com.stand.standapp.utils.AppKiller.killApp(this) } .setNegativeButton("取消", null) .show() diff --git a/app/src/main/java/com/stand/standapp/MyApplication.kt b/app/src/main/java/com/stand/standapp/MyApplication.kt index 5d48c58..478a5e3 100644 --- a/app/src/main/java/com/stand/standapp/MyApplication.kt +++ b/app/src/main/java/com/stand/standapp/MyApplication.kt @@ -57,6 +57,9 @@ class MyApplication : Application() { super.onCreate() mApp = this pageName = packageName + + com.stand.standapp.utils.AppKiller.setupUncaughtExceptionHandler(this) + initPTT() // 第一步:初始化日志 LogManager.init(this) diff --git a/app/src/main/java/com/stand/standapp/utils/AppKiller.kt b/app/src/main/java/com/stand/standapp/utils/AppKiller.kt new file mode 100644 index 0000000..305af7a --- /dev/null +++ b/app/src/main/java/com/stand/standapp/utils/AppKiller.kt @@ -0,0 +1,58 @@ +package com.stand.standapp.utils + +import android.content.Context +import timber.log.Timber + +object AppKiller { + + fun killApp(context: Context, isCrash: Boolean = false) { + Timber.tag("AppKiller").i("Starting app cleanup. isCrash: $isCrash") + + try { + GpioManager.stopListening() + Timber.tag("AppKiller").i("GPIO stopped") + } catch (e: Exception) { + Timber.tag("AppKiller").e(e, "GPIO stop failed") + } + + try { + com.example.kingway.ptt.SendAtUtil.toCancelLogin() + com.example.kingway.ptt.SendAtUtil.toLogout() + Timber.tag("AppKiller").i("PTT logged out") + } catch (e: Exception) { + Timber.tag("AppKiller").e(e, "PTT logout failed") + } + + try { + com.stand.standapp.printer.PrinterManager.getFactory()?.ClosePort() + Timber.tag("AppKiller").i("Printer port closed") + } catch (e: Exception) { + Timber.tag("AppKiller").e(e, "Printer close failed") + } + + try { + LogManager.shutdown() + } catch (e: Exception) { + // ignore + } + + Timber.tag("AppKiller").i("Cleanup finished. Killing process.") + + if (!isCrash) { + try { + Thread.sleep(200) + } catch (e: Exception) {} + } + + android.os.Process.killProcess(android.os.Process.myPid()) + } + + fun setupUncaughtExceptionHandler(context: Context) { + val defaultHandler = Thread.getDefaultUncaughtExceptionHandler() + Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> + Timber.tag("AppKiller").e(throwable, "Uncaught exception detected! Force cleanup.") + killApp(context, true) + defaultHandler?.uncaughtException(thread, throwable) + } + } +} diff --git a/app/src/main/java/com/stand/standapp/utils/GpioManager.kt b/app/src/main/java/com/stand/standapp/utils/GpioManager.kt index 6ba77c3..072c6db 100644 --- a/app/src/main/java/com/stand/standapp/utils/GpioManager.kt +++ b/app/src/main/java/com/stand/standapp/utils/GpioManager.kt @@ -12,6 +12,7 @@ import timber.log.Timber */ object GpioManager { private var mZysjSystemManager: ZysjSystemManager? = null + @Volatile private var mIsRunning = false private var mThread: Thread? = null private var lastGpioValue = 1 // 默认松开状态 (1) @@ -54,6 +55,7 @@ object GpioManager { fun stopListening() { mIsRunning = false + mThread?.interrupt() mThread = null }