• Android日历提醒增删改查事件、添加天数不对问题


    Android日历提醒是非常好的提醒功能,笔者在做的过程中,遇到的一些问题,现整理出来,以供参考。

     一、申请日历的读写权限

    1. <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    2. <uses-permission android:name="android.permission.READ_CALENDAR" />

    如果需要读取日历数据,需要加入READ_CALENDAR权限。若需要对日历数据进行删改操作,需要WRITE_CALENDAR权限。

    二、事件表

    CalendarContract.Events表包含事件的信息,比如标题、描述、开始时间等,如需查看所支持字段的完整列表,请参阅 CalendarContract.Events。

    常量描述
    _ID事件ID,非常重要,更新删除数据都要用到。
    CALENDAR_ID事件所属日历用户ID。
    TITLE事件的名称。
    DESCRIPTION事件的描述。
    DTSTART事件开始时间,以从公元纪年开始计算的协调世界时毫秒数表示。
    DTEND事件结束时间,以从公元纪年开始计算的协调世界时毫秒数表示。
    EVENT_TIMEZONE事件的时区。
    EVENT_END_TIMEZONE事件结束时间的时区。
    DURATIONRFC5545 格式的事件持续时间。例如,值为 "PT1H" 表示事件应持续一小时,值为 "P2W" 表示持续 2 周。
    ALL_DAY值为 1 表示此事件占用一整天(按照本地时区的定义)。值为 0 表示它是常规事件,可在一天内的任何时间开始和结束。
    RRULE事件的重复发生规则格式。例如,"FREQ=WEEKLY;COUNT=10;WKST=SU"。您可以在此处找到更多示例。
    RDATE事件的重复发生日期。RDATE 与 RRULE 通常联合用于定义一组存在聚合关系的重复实例。如需查看更详细的介绍,请参阅 RFC5545 规范
    AVAILABILITY将此事件视为忙碌时间还是可调度的空闲时间。

    HAS_ALARM

    设置是否有闹钟提醒,0-没有,1-有

    三、日历用户

    增加事件需要用户信息(CalendarContract.Events.CALENDAR_ID),相关代码如下:

    1. private static final String CALENDER_URL = "content://com.android.calendar/calendars";
    2. private static final String CALENDARS_NAME = "XX";// 随便写
    3. private static final String CALENDARS_ACCOUNT_NAME = "XX";// 随便写
    4. private static final String CALENDARS_ACCOUNT_TYPE = CalendarContract.ACCOUNT_TYPE_LOCAL;
    5. private static final String CALENDARS_DISPLAY_NAME = StringUtils.getString(R.string.app_name) + "账户";// 随便写
    6. /**
    7. * 检查是否已经添加了日历账户,如果没有添加先添加一个日历账户再查询
    8. * @return 获取账户成功返回账户id,否则返回-1
    9. */
    10. private static int checkAndAddCalendarAccount(Context context) {
    11. int oldId = checkCalendarAccount(context);
    12. if (oldId >= 0) {
    13. return oldId;
    14. } else {
    15. long addId = addCalendarAccount(context);
    16. if (addId >= 0) {
    17. return checkCalendarAccount(context);
    18. } else {
    19. return -1;
    20. }
    21. }
    22. }
    23. /**
    24. * @return 检查是否存在现有账户,存在则返回账户id,否则返回-1
    25. */
    26. private static int checkCalendarAccount(Context context) {
    27. Cursor userCursor = context.getContentResolver().query(Uri.parse(CALENDER_URL), null, null, null, null);
    28. try {
    29. if (userCursor == null) { //查询返回空值
    30. return -1;
    31. }
    32. int columnIndex = userCursor.getColumnIndex(CalendarContract.Calendars._ID);
    33. int count = userCursor.getCount();
    34. if (count > 0) { //存在现有账户,取第一个账户的id返回
    35. userCursor.moveToFirst();
    36. return userCursor.getInt(columnIndex);
    37. } else {
    38. return -1;
    39. }
    40. } catch (Exception ex) {
    41. // do nothing
    42. return -1;
    43. } finally {
    44. if (userCursor != null) {
    45. userCursor.close();
    46. }
    47. }
    48. }
    49. /**
    50. * @return 添加日历账户,账户创建成功则返回账户id,否则返回-1
    51. */
    52. private static long addCalendarAccount(Context context) {
    53. TimeZone timeZone = TimeZone.getDefault();
    54. ContentValues value = new ContentValues();
    55. value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME);
    56. value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
    57. value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
    58. value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
    59. value.put(CalendarContract.Calendars.VISIBLE, 1);
    60. value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
    61. value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
    62. value.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
    63. value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID());
    64. value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
    65. value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);
    66. Uri calendarUri = Uri.parse(CALENDER_URL);
    67. calendarUri = calendarUri.buildUpon()
    68. .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
    69. .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
    70. .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
    71. .build();
    72. Uri result = context.getContentResolver().insert(calendarUri, value);
    73. return result == null ? -1 : ContentUris.parseId(result);
    74. }

    四、增加日历事件

    先创建日历事件,再将事件加入日历提醒,代码如下:

    1. private static final String CALENDER_EVENT_URL = "content://com.android.calendar/events";
    2. private static final String CALENDER_REMINDER_URL = "content://com.android.calendar/reminders";
    3. private static final String[] PERMISSION_LIST = {Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR};
    4. /**
    5. * 真正添加日历事件
    6. *
    7. * @param context:上下文
    8. * @param map:日历事件的信息
    9. * @return 返回事件id
    10. */
    11. private static long addCalendarEvent(Context context, @NonNull Map map) {
    12. if (context == null) {
    13. return 0;
    14. }
    15. if (!XXPermissions.isGranted(context, PERMISSION_LIST)) {
    16. return 0;
    17. }
    18. int calId = checkAndAddCalendarAccount(context); //获取日历账户的id
    19. if (calId < 0) { //获取账户id失败直接返回,添加日历事件失败
    20. return 0;
    21. }
    22. String title = (String) map.get("title");
    23. String description = (String) map.get("description");
    24. long start = 0;
    25. Object originStartTime = map.get("start_time");
    26. if (originStartTime instanceof Long) {
    27. start = (Long) originStartTime;
    28. }
    29. String rule = (String) map.get("rule");
    30. ContentValues event = new ContentValues();
    31. event.put(CalendarContract.Events.TITLE, title);
    32. event.put(CalendarContract.Events.DESCRIPTION, description);
    33. event.put(CalendarContract.Events.CALENDAR_ID, calId); //插入账户的id
    34. event.put(CalendarContract.Events.DTSTART, start);
    35. //event.put(CalendarContract.Events.DTEND, end);// 与DURATION不能同时设置
    36. event.put(CalendarContract.Events.HAS_ALARM, 1);//设置有闹钟提醒
    37. event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());//这个是时区,必须有
    38. event.put(CalendarContract.Events.DURATION, "P0S");// 重复设置必须设置,否则日期有问题
    39. if (!StringUtils.isEmpty(rule)) {
    40. event.put(CalendarContract.Events.RRULE, rule);// 重复规则 rrule(Recurrence Rule)
    41. }
    42. Uri newEvent = context.getContentResolver().insert(Uri.parse(CALENDER_EVENT_URL), event); //添加事件
    43. if (newEvent == null) { //添加日历事件失败直接返回
    44. LogUtils.d("addCalendarEvent2 newEvent 添加日历事件失败直接返回");
    45. return 0;
    46. }
    47. //事件提醒的设定
    48. ContentValues values = new ContentValues();
    49. values.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(newEvent));
    50. values.put(CalendarContract.Reminders.MINUTES, 0);// 提前0分钟提醒
    51. values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
    52. Uri reminderEvent = context.getContentResolver().insert(Uri.parse(CALENDER_REMINDER_URL), values);
    53. if (reminderEvent == null) {
    54. LogUtils.d("addCalendarEvent2 reminderEvent 添加日历事件失败直接返回");
    55. }
    56. return Long.parseLong(newEvent.getLastPathSegment());
    57. }

    总结下增加事件的规则:

    • 您必须加入 CALENDAR_ID 和 DTSTART。
    • 您必须加入 EVENT_TIMEZONE。如需获取系统中已安装时区 ID 的列表,请使用 getAvailableIDs()。请注意,如果您按使用 Intent 插入事件中所述通过 INSERT Intent 插入事件,则此规则不适用 — 在该情形下,系统会提供默认时区。
    • 对于非重复事件,您必须加入 DTEND。
    • 对于重复事件,您必须加入 DURATION,以及 RRULE 或 RDATE。请注意,如果您按使用 Intent 插入事件中所述通过 INSERT Intent 插入事件,则此规则不适用 — 在该情形下,您可以将 RRULE 与 DTSTART 和 DTEND 结合使用,日历应用会自动将其转换为持续时间。
    • RRULE规则可参考:iCalendar Recurrence Rule 规范翻译 - 简书 (jianshu.com)

    碎碎念:

    1、之前添加重复事件,只设置 DTEND ,导致添加的天数有问题,改成DURATION就好了。

    2、_ID(事件ID)非常重要,增加日历提醒后需要保存起来,后续的删改查都需要这个信息。

    五、查找日历事件

    查找比较简单了,这里使用事件ID(_ID),代码如下:

    1. /**
    2. * 检查日历事件
    3. *
    4. * @param context:
    5. * @param eventId:
    6. * @return 返回事件是否存在。true-事件存在,false-事件不存在
    7. */
    8. public static boolean checkCalendarEvent(Context context, long eventId) {
    9. if (context == null || eventId <= 0) {
    10. return false;
    11. }
    12. if (!XXPermissions.isGranted(context, PERMISSION_LIST)) {
    13. return false;
    14. }
    15. Uri uri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), eventId);
    16. Cursor eventCursor = context.getContentResolver().query(uri, null, null, null, null);
    17. if (eventCursor == null) {
    18. return false;
    19. }
    20. boolean result = eventCursor.getCount() > 0;
    21. eventCursor.close();
    22. return result;
    23. }

    六、修改日历事件 

    1. public static void updateCalendarEvent(Context context, long eventId) {
    2. if (context == null || eventId <= 0) {
    3. return;
    4. }
    5. if (!XXPermissions.isGranted(context, PERMISSION_LIST)) {
    6. return;
    7. }
    8. if (!checkCalendarEvent(context, eventId)) {
    9. return;
    10. }
    11. try {
    12. Uri uri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), eventId);
    13. ContentValues values = new ContentValues();
    14. values.put(CalendarContract.Events.TITLE, "XXXX");
    15. int rows = context.getContentResolver().update(uri, values, null, null);
    16. LogUtils.d("updateCalendarEvent rows=" + rows);
    17. } catch (Exception e) {
    18. e.printStackTrace();
    19. }
    20. }

     七、删除日历事件

    1. /**
    2. * 删除日历事件
    3. */
    4. public static void deleteCalendarEvent(Context context, long eventId) {
    5. if (context == null || eventId <= 0) {
    6. return;
    7. }
    8. if (!XXPermissions.isGranted(context, PERMISSION_LIST)) {
    9. return;
    10. }
    11. if (!checkCalendarEvent(context, eventId)) {
    12. return;
    13. }
    14. try {
    15. Uri uri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), eventId);
    16. int rows = context.getContentResolver().delete(uri, null, null);
    17. LogUtils.d("deleteCalendarEventById rows=" + rows);
    18. } catch (Exception e) {
    19. e.printStackTrace();
    20. }
    21. }

    八、完整代码

    1. import android.Manifest;
    2. import android.content.ContentUris;
    3. import android.content.ContentValues;
    4. import android.content.Context;
    5. import android.database.Cursor;
    6. import android.graphics.Color;
    7. import android.net.Uri;
    8. import android.provider.CalendarContract;
    9. import android.text.TextUtils;
    10. import android.util.ArrayMap;
    11. import androidx.annotation.NonNull;
    12. import androidx.annotation.Nullable;
    13. import com.blankj.utilcode.util.LogUtils;
    14. import com.blankj.utilcode.util.StringUtils;
    15. import com.hjq.permissions.XXPermissions;
    16. import java.util.ArrayList;
    17. import java.util.Calendar;
    18. import java.util.List;
    19. import java.util.Map;
    20. import java.util.TimeZone;
    21. /**
    22. * 日历提醒工具类
    23. */
    24. public class CalendarReminderUtils {
    25. private static final String CALENDER_URL = "content://com.android.calendar/calendars";
    26. private static final String CALENDER_EVENT_URL = "content://com.android.calendar/events";
    27. private static final String CALENDER_REMINDER_URL = "content://com.android.calendar/reminders";
    28. private static final String CALENDARS_NAME = "XXX";
    29. private static final String CALENDARS_ACCOUNT_NAME = "XXX";
    30. private static final String CALENDARS_ACCOUNT_TYPE = CalendarContract.ACCOUNT_TYPE_LOCAL;
    31. private static final String CALENDARS_DISPLAY_NAME = StringUtils.getString(R.string.app_name) + "账户";
    32. private static final String[] PERMISSION_LIST = {Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR};
    33. /**
    34. * 检查是否已经添加了日历账户,如果没有添加先添加一个日历账户再查询
    35. * @return 获取账户成功返回账户id,否则返回-1
    36. */
    37. private static int checkAndAddCalendarAccount(Context context) {
    38. int oldId = checkCalendarAccount(context);
    39. if (oldId >= 0) {
    40. return oldId;
    41. } else {
    42. long addId = addCalendarAccount(context);
    43. if (addId >= 0) {
    44. return checkCalendarAccount(context);
    45. } else {
    46. return -1;
    47. }
    48. }
    49. }
    50. /**
    51. * @return 检查是否存在现有账户,存在则返回账户id,否则返回-1
    52. */
    53. private static int checkCalendarAccount(Context context) {
    54. Cursor userCursor = context.getContentResolver().query(Uri.parse(CALENDER_URL), null, null, null, null);
    55. try {
    56. if (userCursor == null) { //查询返回空值
    57. return -1;
    58. }
    59. int columnIndex = userCursor.getColumnIndex(CalendarContract.Calendars._ID);
    60. int count = userCursor.getCount();
    61. if (count > 0) { //存在现有账户,取第一个账户的id返回
    62. userCursor.moveToFirst();
    63. return userCursor.getInt(columnIndex);
    64. } else {
    65. return -1;
    66. }
    67. } catch (Exception ex) {
    68. // do nothing
    69. return -1;
    70. } finally {
    71. if (userCursor != null) {
    72. userCursor.close();
    73. }
    74. }
    75. }
    76. /**
    77. * @return 添加日历账户,账户创建成功则返回账户id,否则返回-1
    78. */
    79. private static long addCalendarAccount(Context context) {
    80. TimeZone timeZone = TimeZone.getDefault();
    81. ContentValues value = new ContentValues();
    82. value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME);
    83. value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
    84. value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
    85. value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
    86. value.put(CalendarContract.Calendars.VISIBLE, 1);
    87. value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
    88. value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
    89. value.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
    90. value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID());
    91. value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
    92. value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);
    93. Uri calendarUri = Uri.parse(CALENDER_URL);
    94. calendarUri = calendarUri.buildUpon()
    95. .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
    96. .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
    97. .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
    98. .build();
    99. Uri result = context.getContentResolver().insert(calendarUri, value);
    100. return result == null ? -1 : ContentUris.parseId(result);
    101. }
    102. /**
    103. * 添加日历事件--就寝提醒
    104. *
    105. * @param context 上下文
    106. * @param title 提醒标题
    107. * @param description 提醒描述
    108. * @param reminderTime 就寝时间,格式HH:mm
    109. */
    110. public static long addCalendarFromSleepAlarm(Context context, String title, String description, @Nullable String reminderTime) {
    111. Map map = new ArrayMap<>();
    112. map.put("title", title);
    113. map.put("description", description);
    114. map.put("rule", "FREQ=DAILY;COUNT=365");
    115. if (reminderTime == null) {
    116. reminderTime = "22:00";
    117. }
    118. String[] split = reminderTime.split(":");
    119. if (split.length != 2) {
    120. return 0;
    121. }
    122. Calendar calendar = Calendar.getInstance();
    123. calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(split[0]));
    124. calendar.set(Calendar.MINUTE, Integer.parseInt(split[1]));
    125. calendar.set(Calendar.SECOND, 0);
    126. long start = calendar.getTime().getTime();
    127. map.put("start_time", start);
    128. try {
    129. return addCalendarEvent(context, map);
    130. } catch (Exception e) {
    131. ExceptionManager.get().report(e);
    132. }
    133. return 0;
    134. }
    135. /**
    136. * 真正添加日历事件
    137. *
    138. * @param context:上下文
    139. * @param map:日历事件的信息
    140. * @return 返回事件id
    141. */
    142. private static long addCalendarEvent(Context context, @NonNull Map map) {
    143. if (context == null) {
    144. return 0;
    145. }
    146. if (!XXPermissions.isGranted(context, PERMISSION_LIST)) {
    147. return 0;
    148. }
    149. int calId = checkAndAddCalendarAccount(context); //获取日历账户的id
    150. LogUtils.d("addCalendarEvent checkAndAddCalendarAccount calId=" + calId);
    151. if (calId < 0) { //获取账户id失败直接返回,添加日历事件失败
    152. return 0;
    153. }
    154. String title = (String) map.get("title");
    155. String description = (String) map.get("description");
    156. long start = 0;
    157. Object originStartTime = map.get("start_time");
    158. if (originStartTime instanceof Long) {
    159. start = (Long) originStartTime;
    160. }
    161. String rule = (String) map.get("rule");
    162. ContentValues event = new ContentValues();
    163. event.put(CalendarContract.Events.TITLE, title);
    164. event.put(CalendarContract.Events.DESCRIPTION, description);
    165. event.put(CalendarContract.Events.CALENDAR_ID, calId); //插入账户的id
    166. event.put(CalendarContract.Events.DTSTART, start);
    167. //event.put(CalendarContract.Events.DTEND, end);// 与DURATION不能同时设置
    168. event.put(CalendarContract.Events.HAS_ALARM, 1);//设置有闹钟提醒
    169. event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());//这个是时区,必须有
    170. event.put(CalendarContract.Events.DURATION, "P0S");// 重复设置必须设置,否则日期有问题
    171. if (!StringUtils.isEmpty(rule)) {
    172. event.put(CalendarContract.Events.RRULE, rule);// 重复规则 rrule(Recurrence Rule)
    173. }
    174. Uri newEvent = context.getContentResolver().insert(Uri.parse(CALENDER_EVENT_URL), event); //添加事件
    175. if (newEvent == null) { //添加日历事件失败直接返回
    176. LogUtils.d("addCalendarEvent2 newEvent 添加日历事件失败直接返回");
    177. return 0;
    178. }
    179. //事件提醒的设定
    180. ContentValues values = new ContentValues();
    181. values.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(newEvent));
    182. values.put(CalendarContract.Reminders.MINUTES, 0);// 提前0分钟提醒
    183. values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
    184. Uri reminderEvent = context.getContentResolver().insert(Uri.parse(CALENDER_REMINDER_URL), values);
    185. if (reminderEvent == null) {
    186. LogUtils.d("addCalendarEvent2 reminderEvent 添加日历事件失败直接返回");
    187. }
    188. LogUtils.d("addCalendarEvent 事件id=" + Long.parseLong(newEvent.getLastPathSegment()));
    189. return Long.parseLong(newEvent.getLastPathSegment());
    190. }
    191. /**
    192. * 检查日历事件
    193. *
    194. * @param context:
    195. * @param eventId:
    196. * @return 返回事件是否存在。true-事件存在,false-事件不存在
    197. */
    198. public static boolean checkCalendarEvent(Context context, long eventId) {
    199. if (context == null || eventId <= 0) {
    200. return false;
    201. }
    202. if (!XXPermissions.isGranted(context, PERMISSION_LIST)) {
    203. return false;
    204. }
    205. Uri uri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), eventId);
    206. Cursor eventCursor = context.getContentResolver().query(uri, null, null, null, null);
    207. if (eventCursor == null) {
    208. return false;
    209. }
    210. boolean result = eventCursor.getCount() > 0;
    211. LogUtils.d("checkCalendarEvent eventCursor=" + eventCursor.getCount() + ",result=" + result);
    212. eventCursor.close();
    213. return result;
    214. }
    215. /**
    216. * 删除日历事件
    217. */
    218. public static void deleteCalendarEvent(Context context, long eventId) {
    219. if (context == null || eventId <= 0) {
    220. return;
    221. }
    222. if (!XXPermissions.isGranted(context, PERMISSION_LIST)) {
    223. return;
    224. }
    225. if (!checkCalendarEvent(context, eventId)) {
    226. return;
    227. }
    228. try {
    229. Uri uri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), eventId);
    230. int rows = context.getContentResolver().delete(uri, null, null);
    231. LogUtils.d("deleteCalendarEventById rows=" + rows);
    232. } catch (Exception e) {
    233. e.printStackTrace();
    234. }
    235. }
    236. public static void updateCalendarEvent(Context context, long eventId) {
    237. if (context == null || eventId <= 0) {
    238. return;
    239. }
    240. if (!XXPermissions.isGranted(context, PERMISSION_LIST)) {
    241. return;
    242. }
    243. if (!checkCalendarEvent(context, eventId)) {
    244. return;
    245. }
    246. try {
    247. Uri uri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), eventId);
    248. ContentValues values = new ContentValues();
    249. values.put(CalendarContract.Events.TITLE, "XXXX");
    250. int rows = context.getContentResolver().update(uri, values, null, null);
    251. LogUtils.d("updateCalendarEvent rows=" + rows);
    252. } catch (Exception e) {
    253. e.printStackTrace();
    254. }
    255. }
    256. }

    参考文章:

    Android 日历表事件表操作_android 读写系统日历 删除-CSDN博客

    iCalendar Recurrence Rule 规范翻译 - 简书 (jianshu.com)

  • 相关阅读:
    旋转的指示牌
    检测登革热NS1蛋白分子/银纳米颗粒/金纳米颗粒/铂纳米颗粒修饰二氧化硅微球
    Vue props实现父组件给子组件传递数据
    请问一下出现这种错误怎么解决呢(标签-xml)
    Android设计模式--工厂模式
    【Sqoop】解决 “Sqooq从Hive中导出数据到MySQL中出现乱码” 的问题
    【npm run dev 报错:error:0308010C:digital envelope routines::unsupported】
    归并排序精讲
    持续集成交付CICD:Jenkins Sharedlibrary 共享库
    腾讯云网站建设服务有哪些优势?适用于哪些场景?
  • 原文地址:https://blog.csdn.net/zhangrgg/article/details/136322037