【Android】通知准时送达之日历事件

本文探讨了在Android中如何利用日历事件实现应用通知的准时送达,避免使用不可靠的程序保活方案。通过添加日历权限,操作日历数据库的calendars, events, reminders表,可以方便地创建稳定的通知事件。此外,文章还提到了常驻通知栏的设置,作为用户快速进入应用的入口。" 108455330,9345729,SIMD指令详解与应用,"['CPU指令集', '并行计算', '高性能计算', '浮点运算', '图像处理']
摘要由CSDN通过智能技术生成

案例

场景:商城会在10点发起对一件商品的秒杀,要求客户端在10点之前五分钟通知到客户打开app准备参与秒杀活动

面对这一需求是否我们第一反应就是如果程序被关闭了如何通知到用户呢?是否需要设计程序保活的方案?是否无法做到这个需求?这篇文章主要按照这个需求来说一说这样的产品需求下,app应该如何优雅的应对。

写在前面

android风风雨雨一路过来,正在变得越来越完善,越来越规范。从这一路走过来的程序员相信都面临过:一方面来自自家公司产品要求准时提醒用户做也一些业务(如参加抢购活动),这就涉及到了 程序保活的问题,另一方面面临这国产手机 各种白名单以外的,后台进程的意外回收(主要手机厂商处于省电,和节省内存这方面来考虑)。可以看到网上各种程序保活的方案屡见不鲜。

其实稍懂得操作系统的程序员都知道,android的普通应用只是运行在系统单独分配的独立的 “小空间” 里,级别要比系统应用的权限低。所以说到底猴子是跳不出如来佛祖的手掌心的,如果跳出来了那就是手机系统的bug

其实我们普通的应用程序如果想运行的稳定,最好的方式还是中规中矩的按照系统要求来,同时去想一些折中的用户可以接受的一些方案。啰嗦了这么多,主要来说一下今天的主题为app添加日历事件

为什么要添加日历事件,有哪些好处

前面说了一堆,其实只有一个主题就是背着系统偷偷干的坏事,不是长久之计,增加了app的异常风险。而系统日历事件提醒这个功能,确实是在系统允许的范围之内,允许第三方应用保存通知事件在日历的程序中。这个是从2.2以上的系统就已经有的功能。

  • 好处1:可以不用在考虑那烦人不靠谱的保活的方案
  • 好处2:代码实现非常方便,而且系统应用通知会更稳定
  • 好处3:用户可以接受 ,这一点很关键

这里大概列一些常用的一些保活方案,读者有兴趣可以逐个去尝试

  • 双进程互相监控存活状态,并重启
  • 利用第三方的推送服务
  • 前台service
  • AlarmClock方案
  • 注册系统广播如开机,开关网,来电等等注册一堆然后来唤醒。
    等等…

添加日历事件方案

下面内容我就默认读者已经知道什么是日历事件了,如果不知道的请打开自己的手机日历,然后选择日期并且添加选择日期的提醒事件熟悉一下具体的流程。这里说的只是不通过程序来实现其他程序往日历程序里面添加提醒事件

相关数据表

日历事件的操作,说到底就是对日历应用做增删改查的数据库操作,这里就用到了ContentProvider,跨应用操作数据库,主要涉及以下几张数据表(找个模拟器直接导出calendar.db):
在这里插入图片描述

在这里插入图片描述

如上的几张表分别对应关系如下图示1
在这里插入图片描述
一个用户可以拥有多个 Calendar,每个 Calendar 可以与不同类型的帐号关联(Google Calendar、Exchange 等)。
CalendarContract 定义了 Calendar 和 Event 的数据模型。这些数据存放在以下数据表中。

数据表 说明
Calendars 该表存放日程的定义数据。每行表示一条日程的详细信息,如名称、颜色、同步信息等。
Events 该表存放事件的定义数据。每行表示一个事件,内容包括 — 事件标题、位置、起始时间、结束时间等等。 事件可以是一次性的,也可以重复多次触发。 参与人员、提醒闹钟及附加属性都存放在其他表中,并通过 EVENT_ID 字段与 Events 表中的 _ID 关联。
Instances 该表存放事件每次触发时的起始时间和结束时间。一次性事件只会1:1对应一条实例记录。 对于重复触发的事件而言,则会自动生成多条实例记录,对应每一次的触发。
Reminders 该表存放闹钟/通知数据。每行代表一次闹钟提醒。 一个事件可以拥有多个闹钟提醒。每个事件可拥有的最大提醒数在 MAX_REMINDERS 中定义,这是由拥有该日程的 sync adapter 设置的。 提醒定义了事件触发前的分钟数,以及提醒用户的方式。

我们下面简单的介绍一下使用calendars,events,reninders三张张表来实现事件的新增

calendars表结构

字段名称 含义 类型
account_type 账户类型 TEXT
account_name 账户名称 TEXT
calendar_displayName TEXT
calendar_color 日历显示的颜色背景 int(RGB)
visible 0不可见1可见 INTEGER
calendar_timezone 日历时区 TEXT
sync_events 0不同步1同步 TEXT
sync_events 最大提醒次数 int

events表结构

字段名称 含义 类型
calendar_id 账户id对应calendars表的id INTEGER
dtstart 开始时间戳 INTEGER
dtend 结束时间戳 INTEGER
title 事件标题 TEXT
description 事件描述 TEXT
eventLocation 事件发生的位置(如果设置的话可以直接点击可进入地图) TEXT
eventTimezone 时区,使用系统默认即可 TEXT
eventStatus 时间状态设置1为正常 INTEGER
rrule 提醒重复规则(FREQ=DAILY;UNTIL=结束时间(yyyyMMdd)+T235959Z(T开头Z结尾即可)),详细的设置我们可以在看资料 TEXT

reminders表结构

字段名称 含义 类型
eventID events表对应的id Integer
minutes 提前几分钟通知 Integer
method 通知方式(见下图) Integer

在这里插入图片描述

添加权限

  • Manifest添加对日历数据的读写权限
 <uses-permission android:name="android.permission.READ_CALENDAR" />
 <uses-permission android:name="android.permission.WRITE_CALENDAR" />
  • 动态权限申请
    6.0之后的动态权限检查这块也是不可少的,操作之前要做权限检查
 private boolean checkPromession(){
   
      if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
   
         ActivityCompat.requestPermissions(this,
               new String[]{
   Manifest.permission.WRITE_CALENDAR,
                     Manifest.permission.READ_CALENDAR}, 1);
         return false;
      }
      return true;
   }

日历账户

日历账户这个必须是要有,如果没有的话日历事件就没有归属,相当于我们要创建的事件归属于哪个账户下


  	/**
     * 检查是否存在日历账户
     * @return 存在:日历账户ID  不存在:-1
     */
    private static long checkCalendarAccount(Context context) {
   
        try (Cursor cursor = context.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI,
                null, null, null, null)) {
   
            // 不存在日历账户
            if (null == cursor) {
   
                return -1;
            }
            int count = cursor.getCount();
            // 存在日历账户,获取第一个账户的ID
            if (count > 0) {
   
                cursor.moveToFirst();
                return cursor.getInt(cursor.getColumnIndex(CalendarContract.Calendars._ID))
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值