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

[Android]使用AlarmManager设置周期性任务

设置周期性任务每隔一小时执行一次任务

闹钟

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.SystemClock

/// 4.设置闹钟
/// 1小时
fun setupAlarmAction(context: Context) {
    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
    val intent = Intent(context, MyAlarmReceiver::class.java)
    // 设置 PendingIntent 时使用了 PendingIntent.FLAG_UPDATE_CURRENT 标志,这意味着如果相同的 PendingIntent 已经存在,它将被更新,而不是创建新的 PendingIntent。
    val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

    // 设置每小时触发一次的闹钟
    val interval = AlarmManager.INTERVAL_HOUR
    val triggerAtMillis = SystemClock.elapsedRealtime() + interval

    alarmManager.setInexactRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        triggerAtMillis,
        interval,
        pendingIntent
    )
}

/// 30秒
fun setupAlarmAction1(context: Context) {
    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
    val intent = Intent(context, MyAlarmReceiver::class.java)
    val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

    // 设置每30秒触发一次的闹钟
    val interval: Long = 20000L // 30秒 = 30,000毫秒
    val triggerAtMillis = SystemClock.elapsedRealtime() + interval

    alarmManager.setRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        triggerAtMillis,
        interval,
        pendingIntent
    )
}

MyAlarmReceiver

import android.app.ActivityManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.PowerManager
import com.mofang.call.callphone.utils.NSLog

/// 每小时打开屏幕一次,避免设备强制睡眠
class MyAlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        NSLog("MyAlarmReceiver onReceive")
        // 重启应用
        restartApp(context)
    }

    /**
     * 检查应用是否正在运行:通过 ActivityManager 检查应用是否正在运行。
     * 根据应用状态决定是否重启:如果应用正在运行,则只打开应用;如果应用被杀掉,则重启应用。
     * */
    private fun restartApp(context: Context) {
        val packageManager = context.packageManager
        val packageName = context.packageName
        val intent = packageManager.getLaunchIntentForPackage(packageName)
        if (intent != null) {
            NSLog("MyAlarmReceiver 重启APP")
            /// 2
            if (isAppInForeground(context, packageName)) {
                // 如果应用正在前台运行,忽略启动操作
                NSLog("应用正在前台运行,忽略启动操作")
                return
            } else {
                // 打开屏幕
                NSLog("打开屏幕")
                // 获取电源管理器
                val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
                // 获取 PowerManager 实例,用于控制设备电源状态
                val wakeLock = powerManager.newWakeLock(
                    PowerManager.FULL_WAKE_LOCK or
                            PowerManager.ACQUIRE_CAUSES_WAKEUP or
                            PowerManager.ON_AFTER_RELEASE, "MyApp::MyWakeLockTag"
                )
                // 创建一个 WakeLock,确保设备在启动应用时保持唤醒状态。获取 WakeLock 并保持 10 分钟(防止设备在这段时间内进入休眠)
                wakeLock.acquire(10*60*1000L /*10 minutes*/)
                // 释放 WakeLock,允许设备在适当时机进入休眠
                wakeLock.release()
            }

        }
    }

    /// 判断APP是否在前台运行
    private fun isAppInForeground(context: Context, packageName: String): Boolean {
        val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val runningAppProcesses = activityManager.runningAppProcesses
        for (processInfo in runningAppProcesses) {
            if (processInfo.processName == packageName) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    return true
                }
            }
        }
        return false
    }

}

AndroidManifest.xml

    <!-- AlarmManager闹钟管理权限 -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
  
<application>
    <!-- 闹钟管理 -->
    <receiver android:name=".MyAlarmReceiver"
        android:enabled="true"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
  </application>

首页

当你从登录页进入首页时设置了一次 AlarmManager 闹钟,然后退出登录再次进入首页并重新设置一次 AlarmManager 闹钟,此时你实际上只有一个闹钟。原因是你在设置 PendingIntent 时使用了 PendingIntent.FLAG_UPDATE_CURRENT 标志,这意味着如果相同的 PendingIntent 已经存在,它将被更新,而不是创建新的 PendingIntent。

/**
 * 首页
 * */
class StartPageActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
        // 设置 AlarmManager
        setupAlarmAction(this)
    }

}  


http://www.kler.cn/a/556337.html

相关文章:

  • [C++]使用纯opencv部署yolov12目标检测onnx模型
  • idea任意版本的安装
  • 第1章:LangChain4j的聊天与语言模型
  • rk3588/3576板端编译程序无法运行视频推理
  • OpenBMC:BmcWeb实例化App
  • 清影2.0(AI视频生成)技术浅析(五):音频处理技术
  • AI Agent Service Toolkit:一站式大模型智能体开发套件
  • C++与Python:两种编程语言的区别
  • 【存储中间件API】MySQL、Redis、MongoDB、ES常见api操作及性能比较
  • windows怎样查看系统信息(处理器等)
  • 2025最新Python机器视觉实战:基于OpenCV与深度学习的多功能工业视觉检测系统(附完整代码)
  • Maven 的高级调试技巧与常见问题
  • 动态存储斐波那契数列(递归优化)
  • Unity游戏制作中的C#基础(2)变量与数据类型
  • Kettle 实战面试题及参考答案(完整版)
  • 【Java基础-46.3】Java泛型通配符详解:解锁类型安全的灵活编程
  • JavaScript如何创建一个对象?对象字面量和构造函数创建对象有什么区别?
  • 【第三节】C++设计模式(创建型模式)-单例模式
  • 通过监督微调提升多语言大语言模型性能
  • 模电知识点总结(5)