3

電話からカレンダーのエントリをオフラインで取得することは可能ですか?gdata-java-clientを使用するのが唯一の方法のようです。

4

7 に答える 7

9

Josef and Isaac's solutions for accessing the calendar only work in Android 2.1 and earlier. Google have changed the base content URI in 2.2 from "content://calendar" to "content://com.android.calendar". This change means the best approach is to attempt to obtain a cursor using the old base URI, and if the returned cursor is null, then try the new base URI.

Please note that I got this approach from the open source test code that Shane Conder and Lauren Darcey provide with their Working With The Android Calendar article.

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
}
于 2010-10-18T12:07:37.657 に答える
8

これらの答えは良いですが、それらはすべてハードコーディングを伴いますCalendar URI(これは、異なるAndroidデバイスの3つの異なる化身で見られました)。

これを取得するためのより良い方法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され、呼び出し元のメソッドによってキャッチまたは再スローされる必要があることに注意してください。

于 2011-02-27T22:43:57.493 に答える
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.
}

編集:これは現在プライベートAPIであるため、ラッパー(Isaacの投稿を参照)に配置することをお勧めします。

于 2009-05-13T12:47:38.910 に答える
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が変更された場合、またはAPIが公開された場合に、非常に簡単に変更できます。

于 2009-05-20T00:20:22.747 に答える
2

ここからCalendarContractを使用できます:https ://github.com/dschuermann/android-calendar-compatibility

これはAndroid4で利用可能なものと同じAPIクラスですが、Android>=2.2で動作するように作られています。

于 2013-02-03T04:19:33.877 に答える
1

Nickのソリューションには、Contextクラスで定義されていないmanagedQueryが含まれます。多くの場合、バックグラウンドで物事を実行しているときは、コンテキストオブジェクトを使用する必要があります。変更されたバージョンは次のとおりです。

public String getCalendarUriBase(){

return(android.os.Build.VERSION.SDK_INT> = 8)?"content://com.android.calendar": "content:// calendar"; }

managedQueryが以前に成功した場合でも例外が増える可能性があるため、ここではnullのキャッチを実行しないでください。

于 2011-03-13T03:43:45.873 に答える
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);

}

等々。このように、APIが変更された場合に備えて、CalendarEventオブジェクトとこのサービスを更新するだけで済みます。

于 2010-07-10T17:24:29.720 に答える