从日历中获取事件
Posted
技术标签:
【中文标题】从日历中获取事件【英文标题】:Getting events from calendar 【发布时间】:2011-08-18 13:01:32 【问题描述】:我的问题是,我必须制作一个演示应用程序,我想在其中读取 Google 日历的事件,因为我手动插入了事件标题、事件时间和详细信息等事件整个事件。现在我需要从该日历中读取这些事件。 为此,我尝试使用提供日历 API 类的 gcode(google code) API。但我还是看不懂那些事件。
【问题讨论】:
我写了一篇关于直接从当前同步到手机的日历中阅读的文章。 jimblackler.net/blog/?p=151 我已经尝试过了,但代码不起作用,,, 我也试过jimblackler.net/blog/?p=151这个代码。调试时遇到错误。谁能告诉我如何在android中获取谷歌日历事件。我只能获取Android日历事件,不能获取谷歌日历事件。 @user2841300 您在此处发布了与评论相同的问题以及 3 个不同的答案。这样做你可能不会得到任何答案。我认为您应该创建自己的问题,并对您的问题进行更详细的解释 【参考方案1】:上面的代码非常糟糕(而且它似乎在 ICS 中不起作用 - 列名肯定不同)
这里的页面: http://developer.android.com/guide/topics/providers/calendar-provider.html
提供了更好的概览。 检索日历的(更)简单的代码:
public class CalendarContentResolver
public static final String[] FIELDS =
CalendarContract.Calendars.NAME,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
CalendarContract.Calendars.CALENDAR_COLOR,
CalendarContract.Calendars.VISIBLE
;
public static final Uri CALENDAR_URI = Uri.parse("content://com.android.calendar/calendars");
ContentResolver contentResolver;
Set<String> calendars = new HashSet<String>();
public CalendarContentResolver(Context ctx)
contentResolver = ctx.getContentResolver();
public Set<String> getCalendars()
// Fetch a list of all calendars sync'd with the device and their display names
Cursor cursor = contentResolver.query(CALENDAR_URI, FIELDS, null, null, null);
try
if (cursor.getCount() > 0)
while (cursor.moveToNext())
String name = cursor.getString(0);
String displayName = cursor.getString(1);
// This is actually a better pattern:
String color = cursor.getString(cursor.getColumnIndex(CalendarContract.Calendars.CALENDAR_COLOR));
Boolean selected = !cursor.getString(3).equals("0");
calendars.add(displayName);
catch (AssertionError ex) /*TODO: log exception and bail*/
return calendars;
希望这会有所帮助!
【讨论】:
截至今天,CalendarContract
仅适用于 API 级别 14 及更高级别。因此,如果任何人的目标 API 级别等于或低于 Honeycomb 系列,则此代码将毫无用处。
谁能告诉我如何在android中获取谷歌日历事件。我只能获取Android日历事件,不能获取谷歌日历事件。
是的,您的示例比上面凌乱但非常健壮且实用的示例更简单。您提供的示例仅显示了可用的日历名称,并且不处理(最重要的)事件。它基本上是无用的,但代码很干净。
别忘了 cursor.close()【参考方案2】:
好的,我找到了如何使用谷歌日历应用程序与安卓手机集成的整个概念的答案。
代码:--
首先,您设置这一行,它将从另一个类中读取日历事件,而您当前的类是 ApplicationSettings.java。
ReadCalendar.readCalendar(ApplicationSettings.this);
package com.mycalendarevents.android;
import java.util.Date;
import java.util.HashSet;
import java.util.regex.Pattern;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.text.format.DateUtils;
public class ReadCalendar
static Cursor cursor;
public static void readCalendar(Context context)
ContentResolver contentResolver = context.getContentResolver();
// Fetch a list of all calendars synced with the device, their display names and whether the
cursor = contentResolver.query(Uri.parse("content://com.android.calendar/calendars"),
(new String[] "_id", "displayName", "selected"), null, null, null);
HashSet<String> calendarIds = new HashSet<String>();
try
System.out.println("Count="+cursor.getCount());
if(cursor.getCount() > 0)
System.out.println("the control is just inside of the cursor.count loop");
while (cursor.moveToNext())
String _id = cursor.getString(0);
String displayName = cursor.getString(1);
Boolean selected = !cursor.getString(2).equals("0");
System.out.println("Id: " + _id + " Display Name: " + displayName + " Selected: " + selected);
calendarIds.add(_id);
catch(AssertionError ex)
ex.printStackTrace();
catch(Exception e)
e.printStackTrace();
// For each calendar, display all the events from the previous week to the end of next week.
for (String id : calendarIds)
Uri.Builder builder = Uri.parse("content://com.android.calendar/instances/when").buildUpon();
//Uri.Builder builder = Uri.parse("content://com.android.calendar/calendars").buildUpon();
long now = new Date().getTime();
ContentUris.appendId(builder, now - DateUtils.DAY_IN_MILLIS * 10000);
ContentUris.appendId(builder, now + DateUtils.DAY_IN_MILLIS * 10000);
Cursor eventCursor = contentResolver.query(builder.build(),
new String[] "title", "begin", "end", "allDay", "Calendars._id=" + 1,
null, "startDay ASC, startMinute ASC");
System.out.println("eventCursor count="+eventCursor.getCount());
if(eventCursor.getCount()>0)
if(eventCursor.moveToFirst())
do
Object mbeg_date,beg_date,beg_time,end_date,end_time;
final String title = eventCursor.getString(0);
final Date begin = new Date(eventCursor.getLong(1));
final Date end = new Date(eventCursor.getLong(2));
final Boolean allDay = !eventCursor.getString(3).equals("0");
/* System.out.println("Title: " + title + " Begin: " + begin + " End: " + end +
" All Day: " + allDay);
*/
System.out.println("Title:"+title);
System.out.println("Begin:"+begin);
System.out.println("End:"+end);
System.out.println("All Day:"+allDay);
/* the calendar control metting-begin events Respose sub-string (starts....hare) */
Pattern p = Pattern.compile(" ");
String[] items = p.split(begin.toString());
String scalendar_metting_beginday,scalendar_metting_beginmonth,scalendar_metting_beginyear,scalendar_metting_begindate,scalendar_metting_begintime,scalendar_metting_begingmt;
scalendar_metting_beginday = items[0];
scalendar_metting_beginmonth = items[1];
scalendar_metting_begindate = items[2];
scalendar_metting_begintime = items[3];
scalendar_metting_begingmt = items[4];
scalendar_metting_beginyear = items[5];
String calendar_metting_beginday = scalendar_metting_beginday;
String calendar_metting_beginmonth = scalendar_metting_beginmonth.toString().trim();
int calendar_metting_begindate = Integer.parseInt(scalendar_metting_begindate.trim());
String calendar_metting_begintime = scalendar_metting_begintime.toString().trim();
String calendar_metting_begingmt = scalendar_metting_begingmt;
int calendar_metting_beginyear = Integer.parseInt(scalendar_metting_beginyear.trim());
System.out.println("calendar_metting_beginday="+calendar_metting_beginday);
System.out.println("calendar_metting_beginmonth ="+calendar_metting_beginmonth);
System.out.println("calendar_metting_begindate ="+calendar_metting_begindate);
System.out.println("calendar_metting_begintime="+calendar_metting_begintime);
System.out.println("calendar_metting_begingmt ="+calendar_metting_begingmt);
System.out.println("calendar_metting_beginyear ="+calendar_metting_beginyear);
/* the calendar control metting-begin events Respose sub-string (starts....ends) */
/* the calendar control metting-end events Respose sub-string (starts....hare) */
Pattern p1 = Pattern.compile(" ");
String[] enditems = p.split(end.toString());
String scalendar_metting_endday,scalendar_metting_endmonth,scalendar_metting_endyear,scalendar_metting_enddate,scalendar_metting_endtime,scalendar_metting_endgmt;
scalendar_metting_endday = enditems[0];
scalendar_metting_endmonth = enditems[1];
scalendar_metting_enddate = enditems[2];
scalendar_metting_endtime = enditems[3];
scalendar_metting_endgmt = enditems[4];
scalendar_metting_endyear = enditems[5];
String calendar_metting_endday = scalendar_metting_endday;
String calendar_metting_endmonth = scalendar_metting_endmonth.toString().trim();
int calendar_metting_enddate = Integer.parseInt(scalendar_metting_enddate.trim());
String calendar_metting_endtime = scalendar_metting_endtime.toString().trim();
String calendar_metting_endgmt = scalendar_metting_endgmt;
int calendar_metting_endyear = Integer.parseInt(scalendar_metting_endyear.trim());
System.out.println("calendar_metting_beginday="+calendar_metting_endday);
System.out.println("calendar_metting_beginmonth ="+calendar_metting_endmonth);
System.out.println("calendar_metting_begindate ="+calendar_metting_enddate);
System.out.println("calendar_metting_begintime="+calendar_metting_endtime);
System.out.println("calendar_metting_begingmt ="+calendar_metting_endgmt);
System.out.println("calendar_metting_beginyear ="+calendar_metting_endyear);
/* the calendar control metting-end events Respose sub-string (starts....ends) */
System.out.println("only date begin of events="+begin.getDate());
System.out.println("only begin time of events="+begin.getHours() + ":" +begin.getMinutes() + ":" +begin.getSeconds());
System.out.println("only date begin of events="+end.getDate());
System.out.println("only begin time of events="+end.getHours() + ":" +end.getMinutes() + ":" +end.getSeconds());
beg_date = begin.getDate();
mbeg_date = begin.getDate()+"/"+calendar_metting_beginmonth+"/"+calendar_metting_beginyear;
beg_time = begin.getHours();
System.out.println("the vaule of mbeg_date="+mbeg_date.toString().trim());
end_date = end.getDate();
end_time = end.getHours();
CallHandlerUI.metting_begin_date.add(beg_date.toString());
CallHandlerUI.metting_begin_mdate.add(mbeg_date.toString());
CallHandlerUI.metting_begin_mtime.add(calendar_metting_begintime.toString());
CallHandlerUI.metting_end_date.add(end_date.toString());
CallHandlerUI.metting_end_time.add(end_time.toString());
CallHandlerUI.metting_end_mtime.add(calendar_metting_endtime.toString());
while(eventCursor.moveToNext());
break;
这里是要发布的全部代码,它将在 2.2 及更高版本的回发 URL 的帮助下简单地读取日历中的每个事件:
Uri.parse("content://com.android.calendar/instances/when").buildUpon();
请在 android 中找到低于 2.2 的版本,并根据需要使用这些事件...
【讨论】:
谁能告诉我如何在android中获取谷歌日历事件。我只能获取Android日历事件,不能获取谷歌日历事件。 很好的例子!不过,第二个查询中有一个小错误:"Calendars._id=" + 1
应该是"calendar_id=" + id
。或者更好CalendarContract.Instances.CALENDAR_ID + "=" + id
刚刚发现另一个问题:它实际上显示了今天周围 20000 天范围内的所有事件 :-p 。最好用* 7
替换事件for循环中的* 10000
。
@RonenFestinger 你有解决办法吗?
@farhana 是的。 ***.com/questions/27783610/…【参考方案3】:
我知道这是一篇旧帖子,但如果有人在不久的将来需要解决方案,我在 Akash Takkar 给出的答案中找到了优化解决方案的灵感。
问题
具体来说,我在原代码中发现了几个问题:
-
检索日历事件的循环未成熟中断
因此,仅检索了第一个日历中的事件
使用 eventCursor.moveToFirst() 跳过了每个日历中的第一个事件;然后直接移动到while循环中的下一个事件
在 eventCursor 中没有正确设置日历的 ID
“Calendars._id=" + 1, 应该是 "Calendars._id=" + id,
其他人很难指定自己的时间范围
当前的解决方案不是面向对象的,它具有许多优点
可读性和文档不是最好的
解决方案
我特此创建了一个 Github 库,它返回指定时间范围内的事件对象列表,可以在以下位置找到:
https://github.com/david-laundav/CalendarService
源文件可以在“CalendarService/src/dk/CalendarService”下找到。
用例
解决方案本身包含两种用于不同目的的不同方法。
第一个用例:
CalendarService.readCalendar(class.this)
// where class.this is either your class or the context
此方法将返回 +/- 1 天的事件列表
第二个用例:
您也可以指定自己的时间范围:
CalendarService.readCalendar(class.this, int days, int hours)
一个例子可能是:
CalendarService.readCalendar(class.this, 2, 5)
这样做将返回 +/-2 天和 +/-5 小时的事件列表。
该服务已经过测试,但如果您遇到任何问题,请告诉我。
【讨论】:
此代码不适用于 ICS 4.1.2(至少在 Galaxy Note GT-N7000 上) 它已经被其他人在 ICS 4.2 上测试成功。你看过第 59 行的“CalendarService.java”吗?:使用下面的光标用于 Android API 4.0+(感谢 SLEEPLisNight) 谁能告诉我如何在android中获取谷歌日历事件。我只能获取Android日历事件,不能获取谷歌日历事件。 得到错误 no such collumn calendar_id android 4.1 samsung galaxy grand 另请查看:***.com/questions/26844770/…【参考方案4】:这篇文章有点老了,但这里有另一个简单的解决方案,用于在 Android 中获取与 Calendar
内容提供者相关的数据:
使用这个库:https://github.com/EverythingMe/easy-content-providers
现在,获取所有日历:
CalendarProvider calendarProvider = new CalendarProvider(context);
List<Calendar> calendars = calendarProvider.getCalendars().getList();
每个日历都有所有字段,因此您可以获得所需的任何信息: id, name, calendarColor, ownerAccount, accountName, calendarAccessLevel, ...
或者,获取特定日历的所有事件:
List<Event> calendars = calendarProvider.getEvents(calendar.id).getList();
还有获取提醒、与会者、实例的选项。
它适用于列表或光标,还有一个示例应用程序可以查看它的外观和工作方式。 事实上,它支持所有 Android 内容提供程序,例如:联系人、短信、通话...... 包含所有选项的完整文档:https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers
希望它有所帮助:)
【讨论】:
【参考方案5】:使用此代码获取一天的日历事件。
public static void readCalendarEvent(Context context) throws ParseException
ContentResolver contentResolver = context.getContentResolver();
Calendar calendar = Calendar.getInstance();
String dtstart = "dtstart";
String dtend = "dtend";
SimpleDateFormat displayFormatter = new SimpleDateFormat("MMMM dd, yyyy (EEEE)");
stime=displayFormatter.format(calendar.getTime());
SimpleDateFormat startFormatter = new SimpleDateFormat("MM/dd/yy");
String dateString = startFormatter.format(calendar.getTime());
long after = calendar.getTimeInMillis();
SimpleDateFormat formatterr = new SimpleDateFormat("hh:mm:ss MM/dd/yy");
Calendar endOfDay = Calendar.getInstance();
Date dateCCC = formatterr.parse("23:59:59 " + dateString);
endOfDay.setTime(dateCCC);
cursor = contentResolver.query(Uri.parse("content://com.android.calendar/events"), (new String[] "calendar_id", "title", "description", "dtstart", "dtend","eventTimezone", "eventLocation" ), "(" + dtstart + ">" + after + " and " + dtend + "<" + endOfDay.getTimeInMillis() + ")", null, "dtstart ASC");
/*String[] COLS="calendar_id", "title", "description", "dtstart", "dtend","eventTimezone", "eventLocation";
cursor = contentResolver.query(
CalendarContract.Events.CONTENT_URI, COLS,null, null, null);*/
gCalendar = new ArrayList<GoogleCalendar>();
try
if (cursor.getCount() > 0)
while (cursor.moveToNext())
GoogleCalendar googleCalendar = new GoogleCalendar();
gCalendar.add(googleCalendar);
int calendar_id = cursor.getInt(0);
googleCalendar.setCalendar_id(calendar_id);
String title = cursor.getString(1);
googleCalendar.setTitle(title);
String description = cursor.getString(2);
googleCalendar.setDescription(description);
String dtstart1 = cursor.getString(3);
dt=convertDate(dtstart1,"hh:mm:ss");
googleCalendar.setDtstart(dt);
String dtend1 = cursor.getString(4);
googleCalendar.setDtend(dtend1);
String eventTimeZone=cursor.getString(5);
googleCalendar.setEventTimeZone(eventTimeZone);
String eventlocation = cursor.getString(6);
googleCalendar.setEventlocation(eventlocation);
catch (AssertionError ex)
ex.printStackTrace();
catch (Exception e)
e.printStackTrace();
【讨论】:
检查:***.com/questions/26844770/…以上是关于从日历中获取事件的主要内容,如果未能解决你的问题,请参考以下文章