WearableCalendarContract returns some null fields

2019-08-03 16:24发布

问题:

I have made an Android Wear watch face which has a function that retrieves calendar events using WearableCalendarContract. Starting a few days ago it now returns null data in fields concerning start/stop minutes and start/stop days and I cannot make it work again.

The code looks like this:

private final String[] PROJECTION = {
                CalendarContract.Calendars._ID,         // 0
                CalendarContract.Instances.TITLE,       // 1
                CalendarContract.Instances.START_MINUTE,// 2
                CalendarContract.Instances.END_MINUTE,  // 3
                CalendarContract.Instances.ALL_DAY,     // 4
                CalendarContract.Instances.START_DAY,   // 5
                CalendarContract.Instances.END_DAY,     // 6
                CalendarContract.Events.DISPLAY_COLOR,  // 7
                CalendarContract.Instances.DESCRIPTION, // 8debug
                CalendarContract.Instances.DTSTART,
                CalendarContract.Instances.DTEND,
                CalendarContract.Instances.CALENDAR_TIME_ZONE,
                CalendarContract.Instances.DURATION
        };

private List<CalEvent> queryEvents() {
            List<CalEvent> events = new ArrayList<>();
            long begin = currentTimeMillis();
            Log.d(TAG, "********** In queryEvents **********");
            Uri.Builder builder = WearableCalendarContract.Instances.CONTENT_URI.buildUpon();
            ContentUris.appendId(builder, begin);
            ContentUris.appendId(builder, begin + DateUtils.DAY_IN_MILLIS / 2); // 12 hours ahead

            final Cursor cursor = getContentResolver()
                    .query(builder.build(),
                            PROJECTION,
                            null, // selection (all)
                            null, // selection args
                            null);


            // get the start and end time, and the color
            while (cursor != null && cursor.moveToNext()) {
                String title = cursor.getString(1);
                int startMinute = cursor.getInt(2);
                int endMinute = cursor.getInt(3);
                int allDay = cursor.getInt(4);
                int startDay = cursor.getInt(5);
                int endDay = cursor.getInt(6);
                int color = cursor.getInt(7);
                Log.d(TAG, "********** Title: " + title + ", start: " + startMinute + ", end: " + endMinute);
                for (int i = 0; i < cursor.getColumnCount(); i++) {
                    Log.d(TAG, "********** cursor.isNull(" + i + ") = " + cursor.isNull(i));
                }
                events.add(new CalEvent(title, startMinute, endMinute, allDay, startDay, endDay, color));
            }

            cursor.close();
            Log.d(TAG, "********** QueryEvents: Read " + events.size() + " events");
            Collections.sort(events);
            return events;
        }

Result for first event (exactly the same pattern for null fields for the rest), why are the important time related fields all null?

********** In queryEvents **********
********** Title: Test event, start: 0, end: 0
********** cursor.isNull(0) = false
********** cursor.isNull(1) = false
********** cursor.isNull(2) = true
********** cursor.isNull(3) = true
********** cursor.isNull(4) = false
********** cursor.isNull(5) = true
********** cursor.isNull(6) = true
********** cursor.isNull(7) = true
********** cursor.isNull(8) = false
********** cursor.isNull(9) = true
********** cursor.isNull(10) = true
********** cursor.isNull(11) = true
********** cursor.isNull(12) = true

In the manifest file I have <uses-permission android:name="android.permission.READ_CALENDAR" /> and it is also granted on the watch. This function has been working flawlessly since 2 months and the current release definitely worked when I released it May 6th. I suspect the latest Android Wear update 4 days ago but since I haven't found anyone else that have reported this problem it's probably my own fault... Very thankful for any input!

Thank you Torkel

回答1:

I got an answer from the Wear team about this:

Hi Torkel! Thanks for the clear bug report. This change was made recently to cut down the amount of data being synced between the devices. The fields being copied across from the latest version of Wear Companion are:

CalendarContract.Instances._ID
CalendarContract.Instances.EVENT_ID
CalendarContract.Instances.TITLE
CalendarContract.Instances.BEGIN
CalendarContract.Instances.END
CalendarContract.Instances.ALL_DAY
CalendarContract.Instances.DESCRIPTION
CalendarContract.Instances.EVENT_LOCATION
CalendarContract.Instances.EVENT_COLOR
CalendarContract.Instances.CALENDAR_COLOR
CalendarContract.Instances.OWNER_ACCOUNT
CalendarContract.Instances.VISIBLE
CalendarContract.Instances.CALENDAR_ID
CalendarContract.Reminders.EVENT_ID
CalendarContract.Reminders.MINUTES
CalendarContract.Reminders.METHOD
CalendarContract.Attendees.EVENT_ID
CalendarContract.Attendees.ATTENDEE_EMAIL
CalendarContract.Attendees.ATTENDEE_NAME
CalendarContract.Attendees.ATTENDEE_STATUS
CalendarContract.Attendees.ATTENDEE_RELATIONSHIP

It should be possible to infer the data you need from this subset, but do reply if that isn't the case.

I'm going to see if we can get this documentation of what fields to expect more explicitly specified on our public documentation.

Link to issue: https://issuetracker.google.com/issues/38476499



回答2:

As stated in the blog - WearableCalendarContract vs. CalendarContract:

WearableCalendarContract only gives you AUTHORITY and CONTENT_URI, because all other constants you can get from original CalendarContract. We waned to keep changes in the use of CalendarContract as small as possible.

Try using CalendarContract instead of WearableCalendarContract, to get details other than the Authority and Content Uri (The content:// style URL for the top-level wearable calendar authority.)

Hope this helps.