是否有访问日历条目,而不使用GDATA-Java的客户端的方法吗?
-
21-08-2019 - |
题
是否有可能从手机下线的日历条目?这似乎是唯一的方法是使用 GDATA-Java的客户端。
解决方案
这些回答都不错,但它们都涉及硬编码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
这将需要被捕获或者通过调用方法重新抛出。
其他提示
约瑟夫和以撒访问日历的解决方案只能在Android 2.1及更早的工作。到“内容://com.android.calendar”:谷歌已经从“//日历内容”改变基本内容的URI 2.2。这一变化意味着最好的办法是尝试获得使用旧基URI光标,如果返回的指针为空,则尝试新的基础URI。
请注意,我从开源测试代码的肖恩康德和劳伦Darcey提供与他们的工作与Android日历一>制品。
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
}
目前,这是不可能的,而无需使用专用的API(见约瑟夫的职位。)有一个日历供应商,但它是不公开呢。它可以随时更改,打破您的应用程序。点击 虽然,它可能不会改变(我不认为他们会从“日历”改变),所以你可能能够使用它。但我的建议是使用这样一个单独的类:
public class CalendarProvider {
public static final Uri CONTENT_URI = Uri.parse("content://calendar");
public static final String TITLE = "title";
public static final String ....
和使用这些而不是直接的字符串。这将让你很容易,如果/更改时,API的变化,或者是公开的。
可以使用日历内容提供商(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的帖子),因为它是目前一个私有API。
您可以从这里使用CalendarContract: https://github.com/dschuermann/android-日历的兼容性
有在Android 4为可用相同的API类,但由与Android工作> = 2.2。
关于可以改变......整个ContentProvider的做法不会很快改变这样已经可以通过只更新串克服了很多问题的API。为此创建常量你重用了整个项目。
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的变化。
尼克的解决方案涉及managedQuery,这没有在上下文类中定义。很多时候,当你在后台运行的东西,你可能需要使用一个上下文对象。这里的一个修改的版本:
公共字符串getCalendarUriBase(){
返回(android.os.Build.VERSION.SDK_INT> = 8)? “内容://com.android.calendar”: “内容://历”; }
对于空渔获不应在此进行,因为有可能是即使managedQuery早期成功更多的异常。