是否可以通过手机离线获取日历的条目?似乎唯一的方法是使用gdata-java-client。
答案 0 :(得分:9)
Josef和Isaac用于访问日历的解决方案仅适用于Android 2.1及更早版本。 Google已将2.2中的基本内容URI从“content:// calendar”更改为“content://com.android.calendar”。此更改意味着最好的方法是尝试使用旧的基本URI获取游标,如果返回的游标为null,则尝试新的基本URI。
请注意,我从Shane Conder和Lauren Darcey提供的open source test code Working With The Android Calendar文章中获得了这种方法。
private final static String BASE_CALENDAR_URI_PRE_2_2 = "content://calendar";
private final static String BASE_CALENDAR_URI_2_2 = "content://com.android.calendar";
/*
* Determines if we need to use a pre 2.2 calendar Uri, or a 2.2 calendar Uri, and returns the base Uri
*/
private String getCalendarUriBase() {
Uri calendars = Uri.parse(BASE_CALENDAR_URI_PRE_2_2 + "/calendars");
try {
Cursor managedCursor = managedQuery(calendars, null, null, null, null);
if (managedCursor != null) {
return BASE_CALENDAR_URI_PRE_2_2;
}
else {
calendars = Uri.parse(BASE_CALENDAR_URI_2_2 + "/calendars");
managedCursor = managedQuery(calendars, null, null, null, null);
if (managedCursor != null) {
return BASE_CALENDAR_URI_2_2;
}
}
} catch (Exception e) { /* eat any exceptions */ }
return null; // No working calendar URI found
}
答案 1 :(得分:8)
这些答案很好,但它们都涉及对Calendar URI
进行硬编码(我在不同的Android设备上看到了三种不同的版本)。
更好的方法来获得URI
(硬编码类和字段的名称)将是这样的:
Class<?> calendarProviderClass = Class.forName("android.provider.Calendar");
Field uriField = calendarProviderClass.getField("CONTENT_URI");
Uri calendarUri = (Uri) uriField.get(null);
这并不完美(如果删除android.provider.Calendar
类或CONTENT_URI
字段,它会中断)但它可以在比任何单个URI硬编码更多的平台上运行。
请注意,这些反射方法将抛出需要被调用方法捕获或重新抛出的exceptions
。
答案 2 :(得分:3)
您可以使用日历内容提供商(com.android.providers.calendar.CalendarProvider
)。例如:
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse("content://calendar/events"), null, null, null, null);
while(cursor.moveToNext()) {
String eventTitle = cursor.getString(cursor.getColumnIndex("title"));
Date eventStart = new Date(cursor.getLong(cursor.getColumnIndex("dtstart")));
// etc.
}
编辑:您可能希望将其放在包装器中(请参阅Isaac's post),因为它目前是私有API。
答案 3 :(得分:3)
目前,如果不使用私有API,这是不可能的(请参阅Josef的帖子。)有一个日历提供程序,但它尚未公开。它可以随时更改并破坏您的应用程序 虽然,它可能不会改变(我认为它们不会从“日历”改变它),所以你可以使用它。但我的建议是使用这样一个单独的类:
public class CalendarProvider {
public static final Uri CONTENT_URI = Uri.parse("content://calendar");
public static final String TITLE = "title";
public static final String ....
直接使用它们代替字符串。如果/当API发生变化或公开时,这将使您可以非常轻松地进行更改。
答案 4 :(得分:2)
您可以从此处使用CalendarContract:https://github.com/dschuermann/android-calendar-compatibility
它与Android 4上提供的API类相同,但适用于Android&gt; = 2.2。
答案 5 :(得分:1)
关于可以更改的API ...整个ContentProvider方法不会快速更改,因此只需更新字符串就可以克服许多问题。因此,创建在整个项目中重复使用的常量。
public static final String URI_CONTENT_CALENDAR_EVENTS = "content://calendar/events";
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse(URI_CONTENT_CALENDAR_EVENTS), null, null, null, null);
//etc
如果你想要一个合适的私人API,你必须创建一个pojo和一些像这样的服务:
public class CalendarEvent {
private long id;
private long date;
//etc...
}
public interface CalendarService {
public Set<CalendarEvent> getAllCalendarEvents();
public CalendarEvent findCalendarEventById(long id);
public CalendarEvent findCalendarEventByDate(long date);
}
等等。这样,您只需更新CalendarEvent对象和此服务,以防API发生变化。
答案 6 :(得分:1)
Nick的解决方案涉及managedQuery,它没有在Context类中定义。很多时候,当您在后台运行时,您会想要使用上下文对象。这是修改后的版本:
public String getCalendarUriBase(){
return(android.os.Build.VERSION.SDK_INT&gt; = 8)? “内容://com.android.calendar”: “内容://历”; }
不应在此处执行null的catch,因为即使managedQuery成功提前,也可能存在更多异常。