AlarmManager添加定时任务

发布于:2025-03-17 ⋅ 阅读:(14) ⋅ 点赞:(0)

通过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
        )
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到