From 4a6348642d1f28f6b0126aaec1f9eaaecb61e6c3 Mon Sep 17 00:00:00 2001 From: yjj38 Date: Tue, 15 Jul 2025 19:02:16 +0800 Subject: [PATCH] =?UTF-8?q?refactor(app):=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84=E5=92=8C=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为类和方法添加注释,解释其功能和使用场景 -优化变量命名,使其更具描述性和一致性 - 重新组织代码结构,提高逻辑清晰度 -移除冗余代码和不必要的空行 - 统一代码格式和风格 --- .../java/com/android/grape/MainActivity.kt | 36 +++++- .../java/com/android/grape/MainApplication.kt | 27 +++- .../java/com/android/grape/MainViewModel.kt | 22 +++- .../com/android/grape/job/MonitorService.kt | 46 ++++++- .../grape/job/SendCallbackJobService.kt | 21 +++- .../java/com/android/grape/util/ScriptUtil.kt | 24 +++- .../main/java/com/android/grape/util/Util.kt | 118 +++++++++++------- 7 files changed, 235 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/android/grape/MainActivity.kt b/app/src/main/java/com/android/grape/MainActivity.kt index 0a24992..8673abb 100644 --- a/app/src/main/java/com/android/grape/MainActivity.kt +++ b/app/src/main/java/com/android/grape/MainActivity.kt @@ -20,18 +20,52 @@ import com.android.grape.util.ScriptUtil import com.android.grape.util.StoragePermissionHelper import com.android.grape.util.Util.killRecordProcess +/** + * public class MainActivity extends AppCompatActivity + */ class MainActivity : AppCompatActivity() { + + /** + private MainViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class); + */ private val viewModel by viewModels() + + /** + * private ActivityMainBinding viewBinding; + */ private lateinit var viewBinding: ActivityMainBinding private lateinit var permissionHandler: NotificationPermissionHandler private lateinit var socketServer: SocketServer + + /** + * 基础设置:调用 super.onCreate() 和 enableEdgeToEdge() 启用全面屏支持。 + * 绑定视图:使用 ViewBinding 加载布局。 + * + * 权限检查:调用 checkPermission() 请求通知和存储权限。 + * 服务与监听:注册脚本接收器、设置按钮点击监听器以启动或停止监控服务。 + * + * Socket 服务器初始化:创建并配置本地 Socket 服务器(注释部分为通信逻辑)。 + */ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() init() + /** + viewBinding = ActivityMainBinding.inflate(layoutInflater) + 使用 ActivityMainBinding 对当前 Activity 的布局文件进行绑定,生成可访问 UI 元素的绑定对象。 + setContentView(viewBinding.root) 将绑定对象中的根视图设置为 Activity 的内容视图,完成界面加载。 + */ viewBinding = ActivityMainBinding.inflate(layoutInflater) setContentView(viewBinding.root) + socketServer = SocketServer(8888) + + /** + * 这段代码用于适配系统窗口(如状态栏、导航栏)的内边距,确保内容不被遮挡: + * 设置窗口边距监听器:通过 ViewCompat.setOnApplyWindowInsetsListener 为 ID 为 main 的根视图设置监听。 + * 获取系统栏边距:从 insets 中提取状态栏和导航栏的边距信息。 + * 设置视图内边距:将视图的内边距设为系统栏的边距,使内容避开系统栏区域。 + */ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) @@ -177,4 +211,4 @@ class MainActivity : AppCompatActivity() { ) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/android/grape/MainApplication.kt b/app/src/main/java/com/android/grape/MainApplication.kt index c14f3e5..dc0d04d 100644 --- a/app/src/main/java/com/android/grape/MainApplication.kt +++ b/app/src/main/java/com/android/grape/MainApplication.kt @@ -3,10 +3,31 @@ package com.android.grape import android.app.Application import com.blankj.utilcode.util.LogUtils -class MainApplication: Application() { +/** + * Android应用的主入口MainApplication类,其功能如下: + * 单例实例:通过伴生对象的instance属性实现全局访问点。 + * 初始化日志记录:在onCreate()中启用日志写入文件功能。 + * 环境初始化:initEvn()方法设置本地库路径,确保JNI等组件能正确加载。 + */ +class MainApplication : Application() { + + /** + private static MainApplication instance; + + public static MainApplication getInstance() { + return instance; + } + */ companion object { lateinit var instance: MainApplication } + + /** + * 调用父类方法:super.onCreate() 确保系统完成基础初始化。 + * 设置全局实例:instance = this 将当前实例赋值给伴生对象中的 instance。 + * 启用日志写入文件:通过 LogUtils 开启日志记录到文件功能。 + * 初始化环境配置:调用 initEvn() 设置本地库路径。 + */ override fun onCreate() { super.onCreate() instance = this @@ -14,7 +35,7 @@ class MainApplication: Application() { initEvn() } - fun initEvn(){ + fun initEvn() { System.setProperty("java.library.path", this.applicationInfo.nativeLibraryDir) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/android/grape/MainViewModel.kt b/app/src/main/java/com/android/grape/MainViewModel.kt index f25aa77..58b41fa 100644 --- a/app/src/main/java/com/android/grape/MainViewModel.kt +++ b/app/src/main/java/com/android/grape/MainViewModel.kt @@ -8,14 +8,30 @@ import com.android.grape.service.MyAccessibilityService import com.android.grape.work.CheckAccessibilityWorker import java.util.concurrent.TimeUnit -class MainViewModel:ViewModel() { +/** + * 继承 ViewModel:用于在 Activity/Fragment 生命周期中保留 UI 相关数据。 + * 检查无障碍服务状态:调用 CheckAccessibilityWorker.isAccessibilityServiceEnabled() 检查 MyAccessibilityService 是否启用。 + * 定时检测机制:若未启用,则通过 WorkManager 提交一个每 15 分钟执行一次的周期性任务,持续检查用户是否开启该服务。 + */ +class MainViewModel : ViewModel() { + /** + * 这段代码用于检查无障碍服务是否启用,若未启用则定时检测: + * 检查服务状态:调用 CheckAccessibilityWorker.isAccessibilityServiceEnabled() 判断 MyAccessibilityService 是否已开启。 + * 未启用则提交定时任务:若未启用,使用 WorkManager 提交一个每 15 分钟执行一次的后台任务 CheckAccessibilityWorker,用于持续检查用户是否启用了该服务。 + */ fun checkAccessibilityService() { + /** + * boolean accessibilityServiceEnabled = CheckAccessibilityWorker.isAccessibilityServiceEnabled( + * MainApplication.getInstance(), + * MyAccessibilityService.class + * ); + */ val accessibilityServiceEnabled = CheckAccessibilityWorker.isAccessibilityServiceEnabled( MainApplication.instance, MyAccessibilityService::class.java ) - if (!accessibilityServiceEnabled){ + if (!accessibilityServiceEnabled) { val workRequest = PeriodicWorkRequest.Builder( CheckAccessibilityWorker::class.java, 15, TimeUnit.MINUTES ) @@ -23,4 +39,4 @@ class MainViewModel:ViewModel() { WorkManager.getInstance(MainApplication.instance).enqueue(workRequest) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/android/grape/job/MonitorService.kt b/app/src/main/java/com/android/grape/job/MonitorService.kt index 638b9c5..a98e208 100644 --- a/app/src/main/java/com/android/grape/job/MonitorService.kt +++ b/app/src/main/java/com/android/grape/job/MonitorService.kt @@ -8,10 +8,19 @@ import com.android.grape.util.ClashUtil import com.android.grape.util.MockTools import com.android.grape.util.Util + /** - * 监听任务 +这段 Kotlin 代码定义了 MonitorService 类,继承自 JobIntentService,用于执行异步后台任务: + onHandleWork 入口方法,防止重复执行,调用核心逻辑 exec()。 + 伴生对象(Companion Object) 提供静态方法 onEvent 启动服务任务,setRunning 控制任务状态。 */ class MonitorService : JobIntentService() { + + /** + * 这段代码是 MonitorService 中的 onHandleWork 方法,用于处理后台任务: + * 日志记录:打印当前任务开始执行的日志信息。 + * 防止重复执行:通过 running 标志判断是否已在运行,若未运行则将其设为 true 并执行 exec() 方法。 + */ override fun onHandleWork(intent: Intent) { Log.i(TAG, "onHandleWork ... $running") if (!running) { @@ -20,6 +29,14 @@ class MonitorService : JobIntentService() { } } + /** + * 这段代码定义了 exec() 方法,用于执行核心监控任务: + * 设置 APK 权限:通过 chmod 777 修改 APK 文件权限。 + * 切换 VPN 代理:调用 ClashUtil.switchProxyGroup 切换代理组为直连。 + * 判断任务类型: + * 如果 clickTime > 0,触发回调任务 SendCallbackJobService.onEvent。 + * 否则执行默认任务 Util.execTask。 + */ protected fun exec() { try { val apkRoot = "chmod 777 $packageCodePath" @@ -40,12 +57,37 @@ class MonitorService : JobIntentService() { } } + /** + * private static final String TAG = "IOSTQ:MonitorService"; + * private static final int JOB_ID = 101; + * + * private static boolean running = false; + * + * public static void onEvent(Context context) { + * Intent intent = new Intent(context, MonitorService.class); + * enqueueWork(context, MonitorService.class, JOB_ID, intent); + * } + * + * public static void setRunning(boolean runningV) { + * running = runningV; + * } + */ companion object { private const val TAG = "IOSTQ:MonitorService" private const val jobId = 101 private var running = false + /** + * 这段代码定义了一个静态方法 onEvent,用于启动一个后台任务: + * 封装 Intent:创建一个用于启动 MonitorService 的 Intent。 + * 提交异步任务:通过 enqueueWork() 将该服务作为后台任务入队,由系统调度执行。 + * + * public static void onEvent(Context context) { + * Intent intent = new Intent(context, MonitorService.class); + * enqueueWork(context, MonitorService.class, jobId, intent); + * } + */ fun onEvent(context: Context) { enqueueWork( context, @@ -60,4 +102,4 @@ class MonitorService : JobIntentService() { running = runningV } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/android/grape/job/SendCallbackJobService.kt b/app/src/main/java/com/android/grape/job/SendCallbackJobService.kt index 9606d87..28a3ea9 100644 --- a/app/src/main/java/com/android/grape/job/SendCallbackJobService.kt +++ b/app/src/main/java/com/android/grape/job/SendCallbackJobService.kt @@ -18,6 +18,16 @@ import java.io.File import java.util.concurrent.TimeUnit class SendCallbackJobService : JobIntentService() { + + /** + * 日志记录:打印任务开始执行的日志。 + * 判断安装状态:通过 Util.isInstallRet() 判断是否需要发送安装结果。 + * 发送备份数据:调用 SendBackup() 发送备份信息。 + * 根据状态选择操作: + * 若需恢复,则调用 sendReloginEvent()。 + * 否则调用 sendLogEvent() 发送日志事件。 + * 结束任务:调用 Util.setFinish() 标记任务完成。 + */ override fun onHandleWork(intent: Intent) { LogUtils.i(TAG, "onHandleWork") @@ -271,6 +281,11 @@ class SendCallbackJobService : JobIntentService() { return result } + /** + * class PostRet { + * int succ = 0; + * } + */ internal class PostRet { var succ: Int = 0 } @@ -280,6 +295,10 @@ class SendCallbackJobService : JobIntentService() { private const val jobId = 700 + /** + * 封装 Intent:创建一个用于启动 SendCallbackJobService 的 Intent。 + * 提交异步任务:通过 enqueueWork() 将该服务作为后台任务入队,由系统调度执行。 + */ fun onEvent(context: Context) { enqueueWork( context, @@ -290,4 +309,4 @@ class SendCallbackJobService : JobIntentService() { ) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/android/grape/util/ScriptUtil.kt b/app/src/main/java/com/android/grape/util/ScriptUtil.kt index af2ad97..a94a355 100644 --- a/app/src/main/java/com/android/grape/util/ScriptUtil.kt +++ b/app/src/main/java/com/android/grape/util/ScriptUtil.kt @@ -44,6 +44,28 @@ object ScriptUtil { } } + /** + * public static void registerScriptResultReceiver() { + * if (scriptResultReceiver == null) { + * scriptResultReceiver = new ScriptReceiver(); + * try { + * IntentFilter filter = new IntentFilter(AUTOJS_SCRIPT_FINISHED_ACTION); + * ContextCompat.registerReceiver( + * MainApplication.getInstance(), + * scriptResultReceiver, + * filter, + * ContextCompat.RECEIVER_EXPORTED + * ); + * LogUtils.d("广播接收器成功注册", null); + * } catch (Exception e) { + * LogUtils.e("Failed to register receiver", e); + * scriptResultReceiver = null; + * } + * } else { + * LogUtils.d("广播接收器已注册,无需重复注册"); + * } + * } + */ fun registerScriptResultReceiver() { if (scriptResultReceiver == null) { scriptResultReceiver = ScriptReceiver() @@ -101,4 +123,4 @@ object ScriptUtil { return false } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/android/grape/util/Util.kt b/app/src/main/java/com/android/grape/util/Util.kt index f9a55a2..8ef66e4 100644 --- a/app/src/main/java/com/android/grape/util/Util.kt +++ b/app/src/main/java/com/android/grape/util/Util.kt @@ -275,7 +275,7 @@ object Util { } fun isInstallRet(): Boolean { - return installRet?:false + return installRet ?: false } fun setAfLog(afLogV: String) { @@ -469,7 +469,7 @@ object Util { MockTools.exec(cmd) val uid = getPackageUserID( context, - recordPackageName?:"" + recordPackageName ?: "" ) chownSh(getMonitorDir(context), uid) return true @@ -676,11 +676,11 @@ object Util { /** - * 通过将请求发送到具有必要参数的指定URL来执行Relogin任务。 - * 此方法初始化必要组件,构造请求参数,提出邮政请求, - * 并处理响应以确定下一步。 - * - * @param上下文呼叫组件的上下文,用于检索资源和系统级服务 + 构建请求参数:获取设备唯一 ID,拼接请求 URL。 + 发送 POST 请求:调用 MyPost.postData 向服务器提交请求。 + 处理响应结果: + 成功时设置权限、解析 JSON 数据并设置 clickTime。 + 失败或异常时调用 setFinish 结束任务。 */ fun execReloginTask(context: Context) { init() @@ -693,7 +693,8 @@ object Util { val valid = false println("IOSTQ:execReloginTask->url:$url?$params") try { - val result: String? = MyPost.postData(" ".toByteArray(charset = Charsets.UTF_8), + val result: String? = MyPost.postData( + " ".toByteArray(charset = Charsets.UTF_8), "$url?$params" ) LogUtils.e("IOSTQ:execReloginTask->result:$result") @@ -724,22 +725,23 @@ object Util { } /** - * 通过启动必要的配置执行安装任务, - * 将请求发送到带有某些参数的指定服务器URL, - * 并处理响应以执行后续操作。 - * - * @param 上下文执行任务的上下文。它习惯了 - * 访问系统资源和特定于应用程序的详细信息。 + * 初始化并构建请求参数:获取设备唯一 ID(ANDROID_ID),拼接请求 URL。 + * 发送 POST 请求:通过 MyPost.postData 向服务器提交安装请求。 + * 处理响应结果: + * 成功时解析 JSON 数据、设置权限,并触发 clickTime 为 1 表示需执行点击操作。 + * 失败或异常时调用 setFinish 结束任务。 */ fun execInstallTask(context: Context) { init() val url = "http://39.103.73.250/tt/ddj/preRequest!requestInstall.do" - val ANDROID_ID = Settings.System.getString(context.contentResolver, Settings.System.ANDROID_ID) + val ANDROID_ID = + Settings.System.getString(context.contentResolver, Settings.System.ANDROID_ID) val params = "platform=Android&tag=119&uuid=$ANDROID_ID" printStr("IOSTQ:request result : $url?$params") try { - val result: String? = MyPost.postData(" ".toByteArray(charset = Charsets.UTF_8), + val result: String? = MyPost.postData( + " ".toByteArray(charset = Charsets.UTF_8), "$url?$params" ) @@ -763,7 +765,7 @@ object Util { setFinish(context) } } catch (e: Exception) { - LogUtils.i(TAG, "execTask error:"+e.message); + LogUtils.i(TAG, "execTask error:" + e.message); setFinish(context) } } @@ -1030,7 +1032,7 @@ object Util { val ret: String? = MyPost.postData("".toByteArray(), url) Log.i(TAG, "ret:$ret") - val jo = JSONObject(ret?:"") + val jo = JSONObject(ret ?: "") if (jo.getInt("code") == 1) { regEmailJson = jo.getJSONObject("emailInfo") @@ -1141,7 +1143,11 @@ object Util { try { var url = "http://39.103.73.250/tt/upload/ddj/$recordFileName" var ret = false - ret = if (checkAppInstalled(context, recordPackageName) || !CheckAppNeedUpgrade(context)) { + ret = if (checkAppInstalled( + context, + recordPackageName + ) || !CheckAppNeedUpgrade(context) + ) { true } else { downloadFile(url, "/sdcard/apks/$recordFileName") @@ -1157,15 +1163,19 @@ object Util { if (isNeedRestored) { println("IOSTQ:开始下载留存文件") taskJson?.let { - if (it.has("BackupFileUrl1") && it.getString("BackupFileUrl1").isNotEmpty()) { - var restored_zip = "http://192.168.1.111/tt/" + it.getString("BackupFileUrl1") + if (it.has("BackupFileUrl1") && it.getString("BackupFileUrl1") + .isNotEmpty() + ) { + var restored_zip = + "http://192.168.1.111/tt/" + it.getString("BackupFileUrl1") if (backUpServerIp.isNotEmpty()) { - restored_zip = "http://" + backUpServerIp + "/tt/" + it.getString("BackupFileUrl1") + restored_zip = + "http://" + backUpServerIp + "/tt/" + it.getString("BackupFileUrl1") } ret = downloadFile(restored_zip, getRecordDataFileName(context)) } } - if (taskJson == null){ + if (taskJson == null) { ret = false } } @@ -1312,11 +1322,11 @@ object Util { deviceJo.put("installServerTimeFromGP", 0) } - val origin_gaid: String = AdvertisingIdClient.getGoogleAdId(context)?:"" + val origin_gaid: String = AdvertisingIdClient.getGoogleAdId(context) ?: "" deviceJo.put("origin_gaid", origin_gaid) paramsJson!!.put("device", deviceJo) val params = paramsJson.toString() - ServiceUtils.setEnableApp(recordPackageName?:"", true) + ServiceUtils.setEnableApp(recordPackageName ?: "", true) ServiceUtils.setEnableApp("org.mozilla.firefox", true) ServiceUtils.setEnableApp("com.google.android.webview", true) ServiceUtils.setEnableApp("com.android.chrome", true) @@ -1385,11 +1395,11 @@ object Util { //proxyJo.put("forwardIp", Util.getDelegateIp()); Log.d("IOSTQ", "firstInstalTime == " + installTime) Log.d("IOSTQ", "paramsJson == " + paramsJson) - val origin_gaid: String = AdvertisingIdClient.getGoogleAdId(context)?:"" + val origin_gaid: String = AdvertisingIdClient.getGoogleAdId(context) ?: "" deviceJo.put("origin_gaid", origin_gaid) paramsJson!!.put("device", deviceJo) val params = paramsJson.toString() - ServiceUtils.setEnableApp(recordPackageName?:"", true) + ServiceUtils.setEnableApp(recordPackageName ?: "", true) ServiceUtils.setEnableApp("org.mozilla.firefox", true) ServiceUtils.setEnableApp("com.google.android.webview", true) ServiceUtils.setEnableApp("com.android.chrome", true) @@ -1458,7 +1468,7 @@ object Util { val url = "http://127.0.0.1:8090/ctl/notcl" try { - val ret: String = MyPost.postData("".toByteArray(charset("utf-8")), url)?:"" + val ret: String = MyPost.postData("".toByteArray(charset("utf-8")), url) ?: "" Log.i(TAG, "notcl ret : $ret") } catch (e: Exception) { e.printStackTrace() @@ -1471,7 +1481,7 @@ object Util { val checked = false try { - val ret: String = MyPost.postData("".toByteArray(charset("utf-8")), url)?:"" + val ret: String = MyPost.postData("".toByteArray(charset("utf-8")), url) ?: "" Log.i(TAG, "checkHook ret : $ret") if ("it works!" == ret) { return true @@ -1524,7 +1534,7 @@ object Util { Log.i(TAG, "开始启动应用 ...$targetPackageName") val packageManager: PackageManager = context.packageManager - var intent:Intent? = null + var intent: Intent? = null intent = packageManager.getLaunchIntentForPackage(targetPackageName) if (intent == null) { @@ -1718,9 +1728,9 @@ object Util { } val create_dir = file.parentFile - if (create_dir != null && !create_dir.exists()){ + if (create_dir != null && !create_dir.exists()) { forceMakeDir(create_dir) - }else if (create_dir == null){ + } else if (create_dir == null) { return false } @@ -1831,7 +1841,8 @@ object Util { fun isBackground(context: Context): Boolean { val activityManager: ActivityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager - val appProcesses: List = activityManager.getRunningAppProcesses() + val appProcesses: List = + activityManager.getRunningAppProcesses() var isBackground = true var processName = "empty" for (appProcess in appProcesses) { @@ -1876,14 +1887,14 @@ object Util { val zipFile = getRecordDataFileName(context) val reloginDataDir = getApkDataDir( context, - recordPackageName?:return false + recordPackageName ?: return false ) Log.i( TAG, "recoverRecordData: dir=$reloginDataDir" ) - if (reloginDataDir == null){ + if (reloginDataDir == null) { return false } @@ -2258,7 +2269,7 @@ object Util { val url = "http://127.0.0.1:8090/ctl/setTarget?target=" + recordPackageName - val ret: String = MyPost.postData("".toByteArray(), url)?:"" + val ret: String = MyPost.postData("".toByteArray(), url) ?: "" Log.i(TAG, "Hook Open App ret : $ret") } @@ -2357,7 +2368,7 @@ object Util { } tags = filterStr(tags) // Log.e(TAG, "getCid:*"+tags+"*"); - return tags?:"" + return tags ?: "" } fun getPropertiesFromAssets(context: Context, fileName: String): Properties { @@ -2505,7 +2516,8 @@ object Util { context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager //获得当前运行的task(任务) - val taskInfoList: List = activityManager.getRunningTasks(100) + val taskInfoList: List = + activityManager.getRunningTasks(100) for (taskInfo in taskInfoList) { //找到本应用的 task,并将它切换到前台 if (taskInfo.baseActivity?.packageName == context.packageName) { @@ -2666,12 +2678,13 @@ object Util { */ fun backupDataFile(context: Context, packageName: String?): String? { Log.i(TAG, "start backUpDataFile : $packageName") - if (packageName == null){ + if (packageName == null) { return null } try { val zipDirName = getBaseFilesDir(context) + "/" + monitorDir + "/" + packageName - val zipFileName = getBaseFilesDir(context) + "/" + monitorDir + "/" + packageName + ".zip" + val zipFileName = + getBaseFilesDir(context) + "/" + monitorDir + "/" + packageName + ".zip" Log.i(TAG, "backupDataFile-> zipDirName:$zipDirName ; zipFileName:$zipFileName") val zipFile = File(zipFileName) forceMakeDir(File(getRecordDataDirName(context))) @@ -2686,7 +2699,8 @@ object Util { if (file.exists()) { val ss = getStringFromFile(context, file.absolutePath) if (ss.isNotEmpty()) { - val arr = ss.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + val arr = + ss.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() for (line in arr) { Log.i(TAG, "line:$line") val blankPos = line.lastIndexOf(" ") @@ -2883,11 +2897,19 @@ object Util { backUp(context, recordPackageName) } + /** - * 停止与给定软件包名称关联的申请过程。 + * public static void killRecordProcess(Context context, String packageName) { + * Log.i(TAG, "start killRecordProcess :" + packageName); * - * @param上下文调用该方法的上下文。 - * @param packageName 将强制终止的应用程序的软件包名称。 + * try { + * String cmd = "am force-stop " + packageName; + * Log.i(TAG, "killRecordProcess-> cmd:" + cmd); + * MockTools.exec(cmd); + * } catch (Exception e) { + * e.printStackTrace(); + * } + * } */ fun killRecordProcess(context: Context?, packageName: String?) { Log.i(TAG, "start killRecordProcess :$packageName") @@ -2973,7 +2995,7 @@ object Util { Log.e("newpath", newpath!!) //将xapk换成zip格式 - FileUtils.renameFile(oldpath?:"", newpath?:"") + FileUtils.renameFile(oldpath ?: "", newpath ?: "") //进行解压 Thread { @@ -2982,7 +3004,7 @@ object Util { try { FileUtils.upZipFile( - File(newpath?:""), + File(newpath ?: ""), "$apk_path/$zip_name" ) } catch (e: IOException) { @@ -2993,7 +3015,7 @@ object Util { } Log.e("zip:", "文件解压成功") }.start() - FileUtils.renameFile(newpath?:"", oldpath?:"") + FileUtils.renameFile(newpath ?: "", oldpath ?: "") } @@ -3107,4 +3129,4 @@ object Util { } return packageName } -} \ No newline at end of file +}