gdata-java-client を使用せずにカレンダーのエントリにアクセスする方法はありますか?
-
21-08-2019 - |
質問
オフラインで電話からカレンダーのエントリを取得することはできますか?を使用する唯一の方法のようです gdata-java-クライアント.
解決
これらの答えは良いですが、それらはすべて(私は別のAndroidデバイス間で三つの異なる化身で見てきた)Calendar URI
をハードコーディング伴います。
(クラス、代わりにフィールドの名前はどのハードコード)このようなものになるだろうという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コンテンツ」に:Googleは「//カレンダーコンテンツ」から2.2に基本コンテンツURIを変更しました。この変更は、古いベースURIを使用してカーソルを取得しようとすることで、返されたカーソルがnullの場合、新しいベースURIを試す最善のアプローチを意味します。
私はhref="http://code.google.com/p/android-calendar-provider-tests/">オープンソースのテストコードがあることを作業を提供します>記事ます。
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.
}
編集:これをラッパーに入れるとよいでしょう (「 アイザックさんの投稿)現在はプライベート API であるため。
ここからCalendarContractを使用することができます: https://github.com/dschuermann/android-カレンダー互換の
これは、Android上で4として利用できる同じAPIのクラスですが、アンドロイドで動作するように作られた> = 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);
}
のように。この方法は、あなたが唯一のAPIの変更の場合にはCalendarEventオブジェクトと、このサービスを更新する必要があります。
ニックのソリューションは、Contextクラスで定義されていないmanagedQueryを伴います。あなたはコンテキストオブジェクトを使用したいバックグラウンドで物事を実行している多くの回。ここで修正されたバージョンがあります:
公共ストリングgetCalendarUriBase(){
リターン(android.os.Build.VERSION.SDK_INT> = 8)? "コンテンツ://com.android.calendar": 「コンテンツ://カレンダー」。 }
ヌルのための漁獲量はmanagedQueryは、以前成功した場合でも、複数の例外があるかもしれないので、ここで行われてはなりません。