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

Android 待办类应用提醒功能的实现及其问题

方式一:AlarmManager

设置时间点时的闹钟,主要通过 AlarmManager 的 setExact 方法在 reminderTime 时间点触发发送广播,从而在应用的广播接收器中处理弹出提醒通知。

    public static void setAlarm(Context context, AlarmManager alarmManager, TodoItem todoItem, long reminderTime) {Intent intent = new Intent(context, AlarmReceiver.class);AlarmIntentParams alarmIntentParams = new AlarmIntentParams(todoItem);intent.putExtra(AlarmReceiver.KEY_ALARM_PARAMS, AlarmIntentParams.toByteArray(alarmIntentParams));intent.setAction(AlarmReceiver.ACTION_ALARM_TODO_NOTIFICATION);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, alarmIntentParams.hashCode(),intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);alarmManager.setExact(AlarmManager.RTC_WAKEUP, reminderTime, pendingIntent);}

因为可能同时设置多个闹钟及其通知,需要构造唯一的 id ,这里通过alarmIntentParams.hashCode() 方法实现 ,主要参数为 AlarmIntentParams 的属性合集的 hash 值

public int hashCode() {return Objects.hash(id, content, time, repeat, important);
}

取消定时的闹钟,需要构造设置闹钟时完全一样的PendingIntent

    public static void cancelAlarm(Context context, AlarmManager alarmManager, TodoItem todoItem, long reminderTime) {Intent intent = new Intent(context, AlarmReceiver.class);AlarmIntentParams alarmIntentParams = new AlarmIntentParams(todoItem);intent.putExtra(AlarmReceiver.KEY_ALARM_PARAMS, AlarmIntentParams.toByteArray(alarmIntentParams));intent.setAction(AlarmReceiver.ACTION_ALARM_TODO_NOTIFICATION);PendingIntent pendingIntent = PendingIntent.getBroadcast(context, alarmIntentParams.hashCode(),intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);alarmManager.cancel(pendingIntent);}

在广播接收器中做提醒通知

public class AlarmReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {mContext = context;mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);String action = intent.getAction();android.util.Log.e("maxx", "AlarmReceiver action=" + action);NotificationManager mTodoNotificationManager = context.getSystemService(NotificationManager.class);if(action.equals(ACTION_ALARM_TODO_NOTIFICATION)){byte[] b = intent.getByteArrayExtra(KEY_ALARM_PARAMS);AlarmIntentParams params = AlarmIntentParams.toParcelable(b,AlarmIntentParams.CREATOR);// 通过获取的参数,显示对应的通知内容,及其通知的按钮Action事件}}
}

只需要在 AndroidManifest.xml 中声明 AlarmReceiver 组件即可,无需额外配置

<receiver android:name=".AlarmReceiver" />

此类实现会有2个问题:

问题1:实现的提醒铃声是集成在通知中的,由系统通知自己实现,无法自己控制铃声的暂停或播放,也无法抢夺音频焦点,在其他应用来通知,并同样有铃声,此时我们的通知铃声就自动停止播放,并且不再恢复。在调节音量的时,我们的通知铃声也会自动停止。
问题2:在应用被清理后台后,AlarmManager 的 setExact 设置的闹钟不再发送广播,通知功能失效。在手机重启后,通知也会功能失效,因为在重启后所有 AlarmManager 设置的闹钟都会被重置失效,需要监听开机广播,重新设置闹钟。

方式二:通过日历

要在 Android 应用中向日历添加事件,您需要使用日历提供程序 API,该 API 提供对日历数据的访问,并允许您创建、修改和删除事件。以下是分步指南:

1. 请求日历权限:

  • 在您的应用的清单文件中,添加访问日历所需的权限:
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />

2. 检查日历访问:

  • 在访问日历之前,请验证用户是否已授予所需的权限。您可以使用checkSelfPermission()方法来检查权限。
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED ||ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR}, REQUEST_CODE_CALENDAR_PERMISSIONS);} else {// Proceed with calendar access}

3.创建ContentResolver:

  • 获取一个ContentResolver对象来与日历提供程序交互。
ContentResolver contentResolver = getContentResolver();

4. 构建活动内容价值:

  • 创建一个ContentValues对象来存储事件的详细信息。
ContentValues eventValues = new ContentValues();eventValues.put(CalendarContract.Events.CALENDAR_ID, DEFAULT_CALENDAR_ID); // Replace with your calendar ID
eventValues.put(CalendarContract.Events.TITLE, "Event Title");
eventValues.put(CalendarContract.Events.DESCRIPTION, "Event Description");
eventValues.put(CalendarContract.Events.EVENT_LOCATION, "Event Location");// Set start and end times in milliseconds
long startTimeMillis = System.currentTimeMillis();
long endTimeMillis = startTimeMillis + 3600000; // 1 hour in millisecondseventValues.put(CalendarContract.Events.DTSTART, startTimeMillis);
eventValues.put(CalendarContract.Events.DTEND, endTimeMillis);eventValues.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());

5.插入事件:

  • 使用ContentResolver将事件插入日历。
Uri calendarUri = CalendarContract.Events.CONTENT_URI;
Uri eventUri = contentResolver.insert(calendarUri, eventValues);if (eventUri != null) {// Event successfully added
} else {// Handle insertion failure
}

6.附加选项:

  • 您可以通过向对象添加相应的值来为事件添加更多详细信息,例如参加者、提醒和警报ContentValues
  • 您可以使用ContentResolver根据事件的 ID 或其他条件来查询、更新或删除事件。

记住要妥善处理潜在的错误,例如权限拒绝或插入失败。

相关文章:

  • ⌈ 传知代码 ⌋ 高速公路车辆速度检测软件
  • 全同态加密生态项目盘点:FHE技术的崛起以及应用
  • 编译链接问题
  • 面试的内容
  • java面试(多线程)
  • Canny算子
  • 幼儿园老师投稿渠道
  • 01 一文理解,Prometheus详细介绍
  • Java-Stream流-概述、创建、使用:遍历/匹配、筛选、聚合、映射、归约、排序、提取/组合
  • LeetCode hot100-51-G
  • iOS--工厂设计模式
  • Linux基础知识,配置网卡(七)
  • 【算法】位运算算法——两整数之和
  • 手写电纸书天花板,阅读办公新体验 | 汉王手写电纸本 N10 2024 版使用评测
  • 【Python-Pandas】DataFrame选取行数据
  • 2017届校招提前批面试回顾
  • 2019年如何成为全栈工程师?
  • Angular4 模板式表单用法以及验证
  • CentOS从零开始部署Nodejs项目
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • JavaScript 基础知识 - 入门篇(一)
  • 阿里云前端周刊 - 第 26 期
  • 大整数乘法-表格法
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 一些关于Rust在2019年的思考
  • 大数据全解:定义、价值及挑战
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • # dbt source dbt source freshness命令详解
  • #etcd#安装时出错
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (C语言)fgets与fputs函数详解
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (done) 声音信号处理基础知识(4) (Understanding Audio Signals for ML)
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (一)Thymeleaf用法——Thymeleaf简介
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .net 7和core版 SignalR
  • .NET gRPC 和RESTful简单对比
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • /etc/shadow字段详解
  • @取消转义
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [52PJ] Java面向对象笔记(转自52 1510988116)
  • [BZOJ4010]菜肴制作
  • [C#]OpenCvSharp使用帧差法或者三帧差法检测移动物体
  • [c]统计数字
  • [C++][opencv]基于opencv实现photoshop算法色阶调整
  • [CERC2017]Cumulative Code
  • [CSS]CSS 字体属性
  • [CSS]浮动