Get events from all accounts of the device and onl

2019-06-05 06:47发布

问题:

I need to get the number of events on the calendars for today. Only the number of events of all calendars, do not need anything more. I found several threads about it, but I can not get the number of events for today.

using this code, the variable "events" gives me the number of all events in the first calendar.

int events=0;

    public void read() {

        Context context = getApplicationContext();    
        ContentResolver contentResolver = context.getContentResolver();  

        long ntime = System.currentTimeMillis();  

        Cursor cursr = contentResolver.query(Uri.parse("content://com.android.calendar/events"), new String[]{ "calendar_id", "title", "description", "dtstart", "dtend", "eventLocation" }, "calendar_id=1", null, null);       
        cursr.moveToFirst();  
        String[] CalNames = new String[cursr.getCount()];  
        int[] CalIds = new int[cursr.getCount()];  
        for (int i = 0; i < CalNames.length; i++) {  
            CalIds[i] = cursr.getInt(0);             
            CalNames[i] = "Event"+cursr.getInt(0)+": \nTitle: "+ cursr.getString(1)+"\nDescription: "+cursr.getString(2)+"\nStart Date: "+cursr.getLong(3)+"\nEnd Date : "+cursr.getLong(4)+"\nLocation : "+cursr.getString(5);  
            long StartTime = cursr.getLong(3);  
            long EndTime = cursr.getLong(4);  

            if ((StartTime<ntime)&&(ntime<EndTime)) {  
                System.out.println("In the middle of something");  
                break;  
            }                  
            cursr.moveToNext();  
            events++;
        }  
        cursr.close(); 
        Log.i("control","vueltas:"+events);
        events=0;
    }

I need to modify the code to read events from all calendars of the device, and only events for today. several days looking for how to do it, but the solutions I've found (including this page) do not know how to apply my code... There is a very similar to my question, but has no answer https://stackoverflow.com/questions/18301870/get-todays-calendar-events

I appreciate your help.

回答1:

What you need to do is query the calendars, and for each of them, query the events instances and just count them. Something like that

// Projection array. Creating indices for this array instead of doing
// dynamic lookups improves performance.
private static final String[] CALENDAR_PROJECTION = new String[] { Calendars.ACCOUNT_NAME };
private static final String[] INSTANCE_PROJECTION = new String[] { Instances._ID };

// The indices for the projection array above.
private static final int PROJECTION_ACCOUNT_NAME_INDEX = 0;

// this is the method that returns the count of all events for all the calendars
public static int getAllEventsCount(final Context context)
{
    int eventsCount = 0;

    // queries the calendars
    final Cursor calendarCursor = context.getContentResolver().query(Calendars.CONTENT_URI, CALENDAR_PROJECTION, null, null, null);
    while (calendarCursor.moveToNext())
    {
        // gets the calendar name - you need that to query the instances for each calendar
        final String accountName = calendarCursor.getString(PROJECTION_ACCOUNT_NAME_INDEX);
        eventsCount = eventsCount + getCalendarEventsCount(context, accountName);
    }
    calendarCursor.close();
    return eventsCount;
}

// this method gets a count of the events in a given calendar
private static int getCalendarEventsCount(final Context context, final String accountName)
{
    final Calendar beginTime = Calendar.getInstance();
    final Calendar endTime = Calendar.getInstance();

    // get events from the start of the day until the same evening.
    beginTime.set(beginTime.get(Calendar.YEAR), beginTime.get(Calendar.MONTH), beginTime.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
    endTime.set(beginTime.get(Calendar.YEAR), beginTime.get(Calendar.MONTH), beginTime.get(Calendar.DAY_OF_MONTH), 23, 59, 59);

    final long startMillis = beginTime.getTimeInMillis();
    final long endMillis = endTime.getTimeInMillis();

    // Construct the query with the desired date range.
    final Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
    ContentUris.appendId(builder, startMillis);
    ContentUris.appendId(builder, endMillis);

    final String selection = "(" + Calendars.ACCOUNT_NAME + " = ?)";
    final String[] selectionArgs = new String[] { accountName };
    final Cursor cursor = context.getContentResolver().query(builder.build(), INSTANCE_PROJECTION, selection, selectionArgs, Instances.BEGIN + " ASC");
    int count = cursor.getCount();
    cursor.close();
    return count;
}

This has been tested and it works. Hope it helps.



回答2:

Use Instances.CONTENT_BY_DAY_URI to get events of specific day. You can find an example of such query here - https://github.com/CyanogenMod/android_packages_apps_Calendar/blob/cm-12.0/src/com/android/calendar/Event.java#L307



回答3:

Did you look at Reading all of today's events using CalendarContract - Android 4.0+ ? But you would still need to query each calendar separately. You code is querying all events and post-processing whereas you should filter the start and end times in the query.

A content resolver is designed to return content, and is not a general purpose SQL that can return only a count. To make it more efficient, you would want to query just the id column and get the cursor row count.

Cursor.getCount()