Android 周期任务

AlarmManager使用

1.创建意图

// 创建意图,启动MonthlyTaskServiceIntent intent = new Intent(getContext(), TimeTaskService.class);
// 传递数据intent.putExtra(TimeTaskService.KEY_TITLE,userRemind.getTitle());intent.putExtra(TimeTaskService.KEY_DEC,userRemind.getDescription());

TimeTaskService.class 是任务执行的具体内容。是一个服务

public class TimeTaskService extends Service {public static final String KEY_TITLE = "key_title";public static final String KEY_DEC = "key_dsc";public TimeTaskService() {}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 执行任务逻辑LogUtil.i("shawn", "onStartCommand 任务执行");String string = intent.getStringExtra(KEY_TITLE);String dec = intent.getStringExtra(KEY_DEC);// 任务完成后,停止服务stopSelf();return START_NOT_STICKY;}@Overridepublic IBinder onBind(Intent intent) {return null;}
}

创建通知

private void showNotification(String title, String description) {if (StringUtils.isEmpty(title) || StringUtils.isEmpty(description)) {return;}NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);// 设置通知点击事件Intent notificationIntent = new Intent(getContext(), MainActivity.class);notificationIntent.putExtra(NotificationConstants.NOTIFICATION_KEY, NotificationConstants.NOTIFICATION_VALUE);PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);Notification.Builder notificationBuilder;// 创建通知渠道if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {NotificationChannel channel = new NotificationChannel(NotificationConstants.NOTIFICATION_CHANNEL_ID, NotificationConstants.NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);channel.setDescription(NotificationConstants.NOTIFICATION_CHANNEL_DESC);notificationManager.createNotificationChannel(channel);// 构建通知notificationBuilder = (new Notification.Builder(getContext(), NotificationConstants.NOTIFICATION_CHANNEL_ID))
//                    .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.drawable.app_icon)).setSmallIcon(R.drawable.app_icon).setContentTitle(title).setContentText(description).setContentIntent(pendingIntent).setAutoCancel(true);// 设置点击通知后自动取消通知// 启动前台服务startForeground(NotificationConstants.FOREGROUND_ID, notificationBuilder.build());} else {// 构建通知notificationBuilder = new Notification.Builder(getContext())
//                    .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.drawable.app_icon)).setSmallIcon(R.drawable.app_icon).setContentTitle(title).setContentText(description).setContentIntent(pendingIntent).setPriority(Notification.PRIORITY_DEFAULT).setAutoCancel(true);// 设置点击通知后自动取消通知}// 发送通知notificationManager.notify(NotificationConstants.NOTIFICATION_ID, notificationBuilder.build());}

注意:在android 8.0以上 启动服务时,要启动前台通知。告知用户。否则会崩溃

2.创建PendingIntent

PendingIntent pendingIntent;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {pendingIntent = PendingIntent.getForegroundService(getContext(),(int) requestCode,intent,PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);} else {pendingIntent = PendingIntent.getService(getContext(),(int) requestCode,intent,PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);}

注意:在使用场景中,经过测试发现。如果把进程杀掉,则任务不执行。所以,在上面的代码中,判断当前版本,大于等于 android 26时,使用PendingIntent.getForegroundService 启动前台服务的方式获取pendingIntent 。经测试,就算杀掉进程,任务也可以执行。

3.启动任务

闹钟触发方式

// 注意:在实际应用中,你可能需要根据实际需求选择合适的触发方式,// 例如使用RTC_WAKEUP替代RTC,确保在设备休眠时也能唤醒系统执行任务// 闹钟类型// ELAPSED_REALTIME - 基于自设备启动以来所经过的时间触发待定 intent,但不会唤醒设备。经过的时间包括设备处于休眠状态期间的任何时间。// ELAPSED_REALTIME_WAKEUP - 唤醒设备,并在自设备启动以来特定时间过去之后触发待定 Intent。// RTC - 在指定的时间触发待定 Intent,但不会唤醒设备。// RTC_WAKEUP - 唤醒设备以在指定的时间触发待定 Intent。

执行1次性任务

// 获取AlarmManager实例AlarmManager alarmManager = (AlarmManager) getApplication().getSystemService(Context.ALARM_SERVICE);if (repetitionType == MyConstants.REPEAT_NO) {if (alarmManager != null && pendingIntent != null) {// 设置一次性闹钟LogUtil.i("shawn", "设置一次性闹钟");
//                alarmManager.set(
//                        AlarmManager.RTC_WAKEUP,
//                        triggerAtMillis,
//                        pendingIntent
//                );
// 设置精确闹钟
// 设置精确重复闹钟//低电耗模式和应用待机模式的影响//为了延长设备的电池续航时间,我们在 Android 6.0(API 级别 23)中引入了低电耗模式和应用待机模式。// 当设备处于低电耗模式时,所有标准闹钟都会推迟,直到设备退出低电耗模式或维护期开始。// 如果必须让某个闹钟在低电耗模式下也能触发,// 可以使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。// 您的应用将在处于空闲状态时(即用户在一段时间内未使用应用,并且应用没有前台进程时)进入应用待机模式。// 当应用处于应用待机模式时,闹钟会像设备处于低电耗模式一样被延迟。// 当应用不再处于空闲状态或者当设备接通电源时,该限制便会解除alarmManager.setExact(AlarmManager.RTC_WAKEUP,triggerAtMillis,pendingIntent);}return;}

上面代码有2种任务执行类型,alarmManager.set 设置的不精确闹钟,setExact设置的是精确闹钟,如果对任务的执行时间没有严格的要求,建议使用set方法,对设备的电量友好。

triggerAtMillis:任务执行的时间

设置重复闹钟

if (alarmManager != null && pendingIntent != null) {// 设置重复闹钟alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,triggerAtMillis,intervalMillis,pendingIntent);}

参数解释:

AlarmManager.RTC_WAKEUP:闹钟触发方式
triggerAtMillis:执行时间
intervalMillis:间隔时间
pendingIntent:任务执行内容

4.任务取消

Intent intent = new Intent(getContext(), TimeTaskService.class);intent.setAction("com.calendar.timeTaskService");AlarmManager alarmManager = (AlarmManager) getApplication().getSystemService(Context.ALARM_SERVICE);PendingIntent pendingIntent;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {pendingIntent = PendingIntent.getForegroundService(getContext(),(int) aLong,intent,PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);LogUtil.i("shawn","getForegroundService job");} else {pendingIntent = PendingIntent.getService(getContext(),(int) aLong,intent,PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);LogUtil.i("shawn","getService job");}if (pendingIntent != null) {LogUtil.i("shawn","cancel job");alarmManager.cancel(pendingIntent);} else {LogUtil.i("shawn","pendingIntent is null");}

5.任务查看

adb shell dumpsys alarm > abc.txt

通过使用adb命令,可以查看当前系统的所有alarm任务,然后筛选包名,查看任务

 u0a647:com.calendar.master.gp +11ms running, 1 wakeups:+11ms 1 wakes 1 alarms, last -2m15s264ms:*walarm*:com.calendar.master.gp/.ui.calendar.TimeTaskService

6.参考

关于Android中设置闹钟的相对完善的解决方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/34615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCPDF生成PDF文件,含jpjraph生成雷达图

TCPDF生成PDF文件,含jpjraph生成雷达图 依赖自行安装 "tecnickcom/tcpdf": "^6.6","amenadiel/jpgraph": "4"雷达图生成 中文字体添加安装 没有封装,只作为测试案例展示 // 创建新的PDF文档$pdf new \TCPD…

MySQL~事务的四大特性和隔离级别

事务的四大特性 1.原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个…

C语言实现三子棋游戏

大家好,欢迎观看Mr.kanglong的CSDN博客,今天和大家讨论的是如何使用C语言来实现三子棋游戏。相信大家儿时或多或少玩过三子棋游戏,那么怎么用C语言实现这样一个游戏呢?且听亢龙娓娓道来~ 目录 三子棋介绍 游戏效果 实现代码 gam…

设计模式行为型——模板模式

目录 模板模式的定义 模板模式的实现 模板模式角色 模板模式类图 模板模式举例 模板模式代码实现 模板模式的特点 优点 缺点 使用场景 注意事项 实际应用 模板模式的定义 模板模式(Template Pattern)属于行为型设计模式,又叫模版…

【python】pycharm 2023.02导入matplotlib报错

换新电脑、重装系统后,新装的pycharm 2023.02版本导入matplotlib会报错:找不到指定的模块 需要重新安装 Microsoft Visual C 2015 Redistributable Update 3或更高版本 下载链接:Download Microsoft Visual C 2015 Redistributable Update …

[数据集][目标检测]PCB板缺陷目标检测数据集VOC格式693张6类别

数据集格式:Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件,仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数):693 标注数量(xml文件个数):693 标注类别数:6 标注类别名称:["missing_hole",…

WPF实战项目十一(API篇):待办事项功能api接口

1、新建ToDoController.cs继承基础控制器BaseApiController,但是一般业务代码不写在控制器内,业务代码写在Service,先新建统一返回值格式ApiResponse.cs: public class ApiResponse{public ApiResponse(bool status, string mess…

连接区块链节点的 JavaScript 库 web3.js

文章目录 前言web3.js 介绍web3.js安装web3.js库模块介绍连接区块链节点向区块链网络发送数据查询区块链网络数据 前言 通过前面的文章我们可以知道基于区块链开发一个DApp,而DApp结合了智能合约和用户界面(客户端),那客户端是如…

ThreadPoolExecutor源码详解

Java中的线程池 谈到池化,通常我们会想到线程池、连接池、对象池等池子。通常池化都会有以下这些共同的好处: 减少资源的消耗。在线程池中重复利用已经创建的线程可以减少创建和销毁的损耗。方便资源的管理。在线程池中我们可以制定线程数量、什么情况…

echarts 图表设置 滚动条

效果图: 代码实现: 第一种方式: 通过 dataZoom 属性缩放进行配置滚动条。 //给x轴设置滚动条 dataZoom: [{start:0,//默认为0end: 100-1500/31,//默认为100type: slider,show: true,xAxisIndex: [0],handleSize: 0,//滑动条的 左右2个滑…

【数据结构•堆】轮廓线

题目描述 轮廓线   • 每一个建筑物用一个三元组表示(L, H, R), 表示左边界, 高度和右边界。   • 轮廓线用X, Y, X, Y…这样的交替式表示。   • 右图的轮廓线为: (1, 11, 3, 13, 9, 0, 12, 7, 16,3, 19, 18, 22, 3, 23, 13, 29, 0) 。   • 给N个建筑,求…

初步制作做一个AI智能工具网站,持续更新

文章目录 介绍AI对话AI绘画AI音视频AI图片处理AI小工具体验 介绍 网页有五大部分:AI对话、AI绘画、AI音视频、AI 图片处理、AI小工具。 AI对话 AI对话是指人工智能技术在模拟人类对话交流方面的应用。通过使用自然语言处理和机器学习算法,AI对话系统可…

SpringBoot复习:(40)@EnableConofigurationProperties注解的用法

一、配置文件: server.port9123 二、配置类: package cn.edu.tju.config;import com.mysql.fabric.Server; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigu…

‘大数据技术与应用’和‘数据科学与大数据技术’有什么区别

一、侧重点不同 ‘大数据技术与应用’主要侧重于大数据的存储、处理和分析技术、包括数据挖掘、机器学习、数据仓库、分布式计算等方面的研究,旨在开发大数据相关的应用程序和系统,以满足商业和企业的需求。 ‘数据科学与大数据技术’则更加注重数据本…

Linux 终端命令之文件浏览(3) less

Linux 文件浏览命令 cat, more, less, head, tail,此五个文件浏览类的命令皆为外部命令。 hannHannYang:~$ which cat /usr/bin/cat hannHannYang:~$ which more /usr/bin/more hannHannYang:~$ which less /usr/bin/less hannHannYang:~$ which head /usr/bin/he…

Vue: el-form 自定义校验规则

Vue 的 el-form 组件可以使用自定义校验规则进行表单验证。自定义校验规则可以通过传递一个函数来实现,该函数接受要校验的字段的值作为参数,并返回一个布尔值或一个 Promise 对象。 下面是一个示例,演示如何在 el-form 中使用自定义校验规则…

Python“牵手”京东工业商城商品详情数据方法介绍

京东工业平台(imall.jd.com)是一个 B2B 电商平台,提供了丰富的工业品类商品,涵盖了机械、化工、建材、劳保用品等品类。如果您需要采集京东工业平台的商品详情数据,可以尝试以下步骤: 选定目标品类和 SKU …

433. 最小基因变化

基因序列可以表示为一条由 8 个字符组成的字符串,其中每个字符都是 A、C、G 和 T 之一。 假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。 例如,"AACCGGTT" -->…

React组件实例的三大属性

React组件实例的三大属性分别是:state、props和refs。 State属性:用来存储组件内部的状态,只能在组件内部修改。当state被修改时,React会重新渲染组件。 Props属性:用来传递父组件的数据到子组件中,是组件…

Redis_哨兵模式

9. 哨兵模式 9.1 简介 当主库宕机,在从库中选择一个,切换为主库。 问题: 主库是否真正宕机?哪一个从库可以作为主库使用?如何实现将新的主库的信息通过给从库和客户端? 9.2 基本流程 哨兵主要任务: 监控选择主库通知 会有…