当前位置: 首页 > news >正文

AlarmManager添加定时任务

通过AlarmManager添加定时任务,即使应用被杀死了,也会启动intent

用户静默安装前,定时自启动自身应用。直到应用启动完成,取消其他的定时任务

object InstallAppUtils {

    const val DEBUG_UPDATE = false
    private const val PACKAGE_NAME = "com.demo.test"

    suspend fun installApkCmd(
        context: Context,
        filepath: String,
        onFailed: () -> Unit,
        onSuccess: () -> Unit
    ) {
        LogUtils.d("InstallAppUtils installApk filepath=${filepath}")
        try {
            val apkFile = File(filepath)

            scheduleAppRestart(context)
            MmkvUtils.saveUpdatingApkFilePath(apkFile.absolutePath)
            delay(500)//延迟执行命令,先做好升级前的准备
            val process = Runtime.getRuntime()
                .exec(arrayOf("su", "0", "pm", "install", "-r", apkFile.absolutePath))
            process.waitFor()
            if (process.exitValue() == 0) {
                // 安装成功
                LogUtils.d("APK 静默安装成功")
                onSuccess.invoke()
            } else {
                // 安装失败,可读取错误流以获取详细信息
                val errorStream = process.errorStream.bufferedReader().readText()
                LogUtils.d("APK 静默安装失败:$errorStream")
                apkFile.delete()
                onFailed.invoke()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun clearUpdatingFile() {
        try {
            MmkvUtils.getUpdatingApkFilePath()?.let { path ->
                if (path.isNotEmpty()) {
                    LogUtils.d("InstallAppUtils clearUpdatingFile $path")
                    val file = File(path)
                    if (file.exists()) {
                        file.delete()
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            MmkvUtils.clearUpdatingApkFilePath()
        }

    }

    /**
     * 通过AlarmManager尝试每隔10秒启动应用
     */
    fun scheduleAppRestart(context: Context) {
        // 构造启动应用的 Intent,这里假设 MainActivity 为入口
        var triggerAtMillis = System.currentTimeMillis() + 10_000L
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        repeat(6) {
            triggerAtMillis += 10_000L
            getRestartPendingIntent(context, it)?.let { pendingIntent ->
                // setExactAndAllowWhileIdle 确保在低功耗模式下也能执行
                alarmManager.setExactAndAllowWhileIdle(
                    AlarmManager.RTC_WAKEUP,
                    triggerAtMillis,
                    pendingIntent
                )
            }
        }


    }

    // 取消启动应用的定时任务
    fun cancelAlarm(context: Context) {
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        repeat(6) {
            getRestartPendingIntent(context, it)?.let { pendingIntent ->
                alarmManager.cancel(pendingIntent)
            }

        }

    }

    private fun getRestartPendingIntent(context: Context, requestCode: Int): PendingIntent? {
//        val intent = Intent().apply {
//            component = ComponentName(PACKAGE_NAME, LAUNCH_ACTIVITY)
//            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
//        }
        val launchIntent: Intent? =
            getPackageManager().getLaunchIntentForPackage(PACKAGE_NAME)
        return PendingIntent.getActivity(
            context,
            requestCode,
            launchIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
    }
}

相关文章:

  • 【JavaEE】快速上手JSON:构建高效 Java 后端数据桥梁,开启交互新篇,以 @RequestBody 为引的探索之旅
  • Amazon 全球买卖商品 库存模型
  • 2、操作系统之软件基础
  • 新手村:数据预处理-异常值检测方法
  • 94.HarmonyOS NEXT动画系统实现教程:深入理解FuncUtils
  • 从被动响应到主动预见:智能可观测性技术的变革与实践
  • 【CVPR-2023】DR2:解决盲人脸复原无法覆盖真实世界所有退化的问题
  • Redis监控:从睁眼瞎到千里眼的进化史
  • WindowsPE文件格式入门01.PE头
  • Maven 的核心包
  • 浅析Model Context Protocol (MCP)协议:概念、优势与实战应用
  • Nest系列:NestJS 中 Logger 完全指南:从基础到企业级实践-04
  • IE代理切换器v1.2免费版
  • Python中的多态与Java、C#、C++中的多态的区别有哪些?
  • Flash Attention原理讲解
  • 解决下载npm 缓存出现的问题
  • 【Redis】缓存穿透、缓存击穿、缓存雪崩
  • 【前缀和的力量:高效解决子数组和矩阵问题的秘笈】—— 蓝桥杯高频热点题型知识点
  • 向量数据库技术系列一-基本原理
  • rk3568 phy驱动调式_phy寄存器
  • 马上评丨学术不容“近亲繁殖”
  • 习近平出席俄罗斯纪念苏联伟大卫国战争胜利80周年庆典
  • 习近平同瑞典国王卡尔十六世·古斯塔夫就中瑞建交75周年互致贺电
  • 保证断电、碰撞等事故中车门系统能够开启!隐藏式门把手将迎来强制性国家标准
  • 如此城市|上海老邬:《爱情神话》就是我生活的一部分
  • “三德子”赵亮直播间卖“德子土鸡”,外包装商标实为“德子土”