无需用户确认即可向日历添加事件

时间:2014-01-27 02:57:13

标签: android calendar

我正在尝试编写一个类来在后台向用户的日历添加事件(不使用意图)。我需要最终能够在一个循环中添加多达7个事件,所以我无法通过将控制权交给日历以供用户确认的方法来实现。

不幸的是,我没有到达任何地方。我从logcat获得的唯一反馈是警告:Cursor finalized without prior close()

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class AddToCalendar {

    Context context;

    // Projection array. Creating indices for this array instead of doing
    // dynamic lookups improves performance.
    public static final String[] EVENT_PROJECTION = new String[] {
        Calendars._ID,                           // 0
        Calendars.ACCOUNT_NAME,                  // 1
        Calendars.CALENDAR_DISPLAY_NAME,         // 2
        Calendars.OWNER_ACCOUNT                  // 3
    };

    // The indices for the projection array above.
    private static final int PROJECTION_ID_INDEX = 0;
    private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
    private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
    private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;

    public AddToCalendar (Context context) {
        this.context = context;
    }

    public Cursor getCalendars() {  
        Cursor cursor = null;
        ContentResolver cr = context.getContentResolver();
        Uri uri = Calendars.CONTENT_URI;   
        String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" 
                                + Calendars.ACCOUNT_TYPE + " = ?) AND ("
                                + Calendars.OWNER_ACCOUNT + " = ?))";
        String[] selectionArgs = new String[] {"sampleuser@gmail.com", "com.google",
                "sampleuser@gmail.com"}; 
        // Submit the query and get a Cursor object back. 
        cursor = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);

        return cursor;
    }

    public void addEvent(Cursor cursor, String type, String location, String description, Date workout_date) {

        System.err.println("adding event");

        while (cursor.moveToNext()) {

            String displayName = null;
            String accountName = null;
            String ownerName = null;

            // Get the field values
            long calID = 0;
            calID = cursor.getLong(PROJECTION_ID_INDEX);
            displayName = cursor.getString(PROJECTION_DISPLAY_NAME_INDEX);
            accountName = cursor.getString(PROJECTION_ACCOUNT_NAME_INDEX);
            ownerName = cursor.getString(PROJECTION_OWNER_ACCOUNT_INDEX);

            System.err.printf("Calendar: %s\n", displayName);

            long startMillis = 0; 
            long endMillis = 0;     
            Calendar beginTime = Calendar.getInstance();
            beginTime.set(2014, 1, 26, 7, 30);
            startMillis = beginTime.getTimeInMillis();
            Calendar endTime = Calendar.getInstance();
            endTime.set(2014, 1, 26, 8, 45);
            endMillis = endTime.getTimeInMillis();

            ContentResolver cr = context.getContentResolver();
            ContentValues values = new ContentValues();
            values.put(Events.DTSTART, startMillis);
            values.put(Events.DTEND, endMillis);
            values.put(Events.TITLE, type);
            values.put(Events.EVENT_LOCATION, location);
            values.put(Events.DESCRIPTION, description);
            values.put(Events.CALENDAR_ID, calID);
            values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");

            cr.insert(Events.CONTENT_URI, values);
        }
    }
}

大部分内容都是从http://developer.android.com/guide/topics/providers/calendar-provider.html汇总而来的,但它不起作用。除了我提到的警告之外,除了日历上没有显示的细微细节之外,所有这些都“显示”起作用。

如何以一般方式编写getCalendars()查询以获取可能位于用户设备上的所有日历?现在,你可以看到我仍然有Android网站的语言。

感谢任何帮助。谢谢。

编辑:Andrew T指出我有一个一个一个错误,因为月份是从零开始的,所以我把我的硬编码日期改为0个月。我还在我的后面添加了一个cursor.close() while循环。但是,我的日程表上仍然没有任何内容。

我注意到的一件事是我没有进入while循环。所以我拿出了循环。当我将calID变量硬编码为1时,我终于得到一个日历条目,但这引起了我的注意。我认为获取日历的重点是用户可能在其设备上使用多个日历,而光标是迭代这些日历的一种方式。我错了吗?

如果将calID硬编码为1将解决我的问题,我很好,但我想确保我理解这一点并且不依赖于临时解决方案。再次感谢!

1 个答案:

答案 0 :(得分:1)

警告是由插入事件后未关闭日历Cursor引起的。致电cursor.close()关闭它。

另外,你有没有在2月检查过这些事件?我担心你有一个关于月份在Java Calendar中如何工作的问题。 (月份从0开始,即Calendar.JANUARY

编辑:

getCalendars()似乎存在问题,特别是在String selection = ...上会返回空Cursor。此外,通过这种方法,可能会将事件添加到多个日历中,这可能是不可取的。

我的想法是创建一个ListActivity来列出所有日历,让用户选择他想要使用的日历。这样,您还可以将日历ID保存到SharedPreference并在方便地创建活动时使用它。

我认为您可以使用cursor = cr.query(uri, EVENT_PROJECTION, null, null, null);列出设备上的所有日历。