【问题标题】:Android Calendar - Deleted Events Not Deleted or Even FlaggedAndroid 日历 - 已删除事件未删除甚至标记
【发布时间】:2022-02-23 11:42:30
【问题描述】:

因此,我在 Android 10 手机上遇到了一个问题,当我查询用户的日历时,已删除的事件仍然存在。问题持续了几个小时(撰写本文时为 3 个)

我已经查看了以下帖子,试图找到解决方案,但似乎没有一个对我有用,我不确定我是否只是错误地实施了他们的解决方案,如果有什么问题电话,或其他任何东西。

这是我上面提到的帖子:

Calendar deleted event exists in cursor

Deleting events from Calendar not being deleted

Android CalendarContract, deleting a recurring event causes all events to disappear on calendar?

Querying android calendar retrieves even deleted events

我知道当用户从他们的日历中删除某些内容时,它可能会挂在任何数据库或结构中,Android 将事件存储在带有dirtydeleted 标志集的位置。我的问题是事件仍然存在,并且没有设置前面提到的标志。

此外,我知道这可能是 Google 的日历与存储事件的任何本地数据存储之间的同步问题,但即使在从用户的日历,这让我觉得本地数据存储和日历应该同步。

这是我遇到此问题的文件的完整代码 - 有些事情可能与问题无关,但我将所有内容都包括在内以防万一。

package com.example.plumbingreportgenerator.util.calendar;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CalendarContract;
import android.provider.CalendarContract.*;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class EventReader {
    // the context of the application this is being used in
    private Context applicationContext;

    public static final String[] EVENT_PROJECTION = new String[] {
            Events.CALENDAR_ID, // 0
            Events.TITLE, // 1
            Events.DTSTART, // 2
            Events.DELETED,
            Events.DIRTY
    };

    // The indices for the projection array above.
    private static final int PROJECTION_CALENDAR_ID_INDEX = 0;
    private static final int PROJECTION_TITLE_INDEX = 1;
    private static final int PROJECTION_DTSTART_INDEX = 2;
    private static final int PROJECTION_DELETED_INDEX = 3;
    private static final int PROJECTION_DIRTY_INDEX = 4;


    public EventReader(Context context){
        applicationContext = context;
    }

    // use android and java date libraries to determine the start of the month given by year and month
    private static long getStartOfMonth(int year, int month){
        java.util.Calendar cal = java.util.Calendar.getInstance();
        cal.set(java.util.Calendar.YEAR, year);
        cal.set(java.util.Calendar.MONTH, month);
        cal.set(java.util.Calendar.DAY_OF_MONTH, 1);
        cal.set(java.util.Calendar.HOUR_OF_DAY, 0);
        cal.set(java.util.Calendar.MINUTE, 0);
        cal.set(java.util.Calendar.SECOND, 0);
        cal.set(java.util.Calendar.MILLISECOND, 0);

        return cal.getTimeInMillis();
    }

    private static long getEndOfMonth(int year, int month){
        java.util.Calendar cal = java.util.Calendar.getInstance();
        cal.set(java.util.Calendar.YEAR, year);
        cal.set(java.util.Calendar.MONTH, month);
        cal.set(java.util.Calendar.DAY_OF_MONTH, cal.getActualMaximum(java.util.Calendar.DAY_OF_MONTH));
        cal.set(java.util.Calendar.HOUR_OF_DAY, 23);
        cal.set(java.util.Calendar.MINUTE, 59);
        cal.set(java.util.Calendar.SECOND, 59);
        cal.set(java.util.Calendar.MILLISECOND, 999);

        return cal.getTimeInMillis();
    }


    // gets event titles for the given calendar from the given month
    public ArrayList<EventTitleDateTuple> getEventDetailsForMonth(long calendarId, int year, int month){
        // get the millisecond values for the start and end of the month given by year and month
        long startOfMonth = getStartOfMonth(year, month);
        long endOfMonth = getEndOfMonth(year, month);

        // Create cursor and query for the events table
        Cursor cur = null;
        ContentResolver cr = applicationContext.getContentResolver();
        Uri uri = Events.CONTENT_URI;
        String selection = "((" + Events.CALENDAR_ID + " = ?) AND (" + Events.DELETED + " != 1) AND (" + Events.DIRTY  + " != 1 ))";
        String[] selectionArgs = new String[] {Long.toString(calendarId)};

        // Submit the query and get a Cursor object back.
        cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);

        ArrayList<EventTitleDateTuple> eventDetails = new ArrayList<EventTitleDateTuple>();

        while (cur.moveToNext()) {
            long calID = 0;
            String title = null;
            long dtStart = 0;

            // Get the field values
            calID = cur.getLong(PROJECTION_CALENDAR_ID_INDEX);
            title = cur.getString(PROJECTION_TITLE_INDEX);

            int deleted = cur.getInt(PROJECTION_DELETED_INDEX);
            int dirty = cur.getInt(PROJECTION_DIRTY_INDEX);

            dtStart = cur.getLong(PROJECTION_DTSTART_INDEX);

            // if the start date of the event is after this month and before the end of this month
            if(dtStart >= startOfMonth && dtStart <= endOfMonth && title != null && title.length() > 0 && deleted != 1 && dirty != 1 && !title.contains("testy mates face")){
                // the deleted events still make it through to here
        eventDetails.add(new EventTitleDateTuple(title, dtStart));
            }
        }

        cur.close();

        return eventDetails;
    }
}

【问题讨论】:

    标签: java android android-10.0 android-calendar


    【解决方案1】:

    这不是删除事件的问题,而是同步的问题。有时在 2020/2021 年,Google 会以某种令人讨厌的缓存的形式添加“功能”(或错误)。

    实际上,这意味着,从现在开始(与以前不同),您将永远不知道您的缓存中是否有新数据或过时数据。强制他们的缓存定期更新的唯一方法是一直不断地打开所有日历的自动同步。

    这种方式只需几秒钟即可完成更改,而且 Google 日历缓存始终在更新。如果仅关闭 1 个日历的自动同步,由于未知原因,缓存未按时更新,并且通常需要数小时才能反映更改...

    可以在这些链接中找到类似的问题:

    Android CalendarContract.Instances table returns old values

    Android Calendar Provider does not return latest data

    甚至在 Google 支持页面上:

    https://support.google.com/calendar/thread/47536340?hl=en

    我很想知道 Google 中谁提出了这个天才的想法……唉

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多