Search code examples
androidandroid-contentproviderandroid-calendar

Android Calendar Content Provider: allDay is true but sec, min, hour are not 0


I'm querying the content provider for appointments.

    Uri.Builder builder = CalendarContract.Instances.CONTENT_URI.buildUpon();
    ContentUris.appendId(builder, startMillis);
    ContentUris.appendId(builder, endMillis);
    Uri uri = builder.build();

    String[] event_projection= new String[] {
        Instances.TITLE,               
        Instances.ALL_DAY,              
        Instances.CALENDAR_COLOR,       
        Instances.EVENT_ID,            
        Instances.BEGIN,               
        Instances.END,                 
        };

    String selection = CalendarContract.Instances.VISIBLE + "='1'";

    String sortBy = CalendarContract.Instances.BEGIN + " ASC, " +
                    CalendarContract.Instances.TITLE + " ASC";

    Cursor mCursor = cr.query(uri, event_projection, selection, null, sortBy);

Some users send the following crash report:

java.lang.IllegalArgumentException: allDay is true but sec, min, hour are not 0.
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
    at android.content.ContentProviderProxy.query(ContentProviderNative.java:384)
    at android.content.ContentResolver.query(ContentResolver.java:372)
    at android.content.ContentResolver.query(ContentResolver.java:315)

This happens mostly on Sony Xperia devices, but also happened on Google Nexus10. How is it possible to get this exception when querying the data? Shouldn't this have been avoided when inserting the data in the first place?

Does it mean that I have to surround the query with try/catch? Doesn't this slow down the query?


Solution

  • Yes, it does sound like the data is inserted badly. If it shortcuts the query processing the exception could speed up the query actually, but wont return the data you are looking for.

    The exception appears to be from Time.compare http://developer.android.com/reference/android/text/format/Time.html#compare(android.text.format.Time,%20android.text.format.Time)

    This would probably result from the sortBy argument of the query. Try it with null and see if it stops using the comparator. If that works then maybe when ALL_DAY is true, it is incompatible with sorting by BEGIN on your data set.

    You could either sort in a collection after reading the rows from the cursor and updating the values in memory to make the comparator happy or use your own comparator, or you could fix the data (set sec, min, hour to 0 where ALL_DAY is true) before running your query.

    Maybe a good practice would be to repair the data upon exception and retry.