Gibt es eine Möglichkeit die Kalender des Eintrag zugreifen, ohne gdata-java-Client zu verwenden?

StackOverflow https://stackoverflow.com/questions/846942

  •  21-08-2019
  •  | 
  •  

Frage

Ist es möglich, den Kalender des Einträge aus dem Telefon offline zu bekommen? Es scheint die einzige Möglichkeit, gdata-java-client zu verwenden ist.

War es hilfreich?

Lösung

Diese Antworten sind gut, aber sie alle beinhalten Hartcodierung der Calendar URI (die ich in drei verschiedenen Inkarnationen in verschiedenen Android-Geräten gesehen haben).

Eine bessere Art und Weise, dass URI zu bekommen (was schwer Codes der Name einer Klasse und ein Feld statt) so etwas wie dies wäre:

Class<?> calendarProviderClass = Class.forName("android.provider.Calendar");
Field uriField = calendarProviderClass.getField("CONTENT_URI");
Uri calendarUri = (Uri) uriField.get(null);

Dies ist nicht perfekt (es wird brechen, wenn sie jemals die android.provider.Calendar Klasse oder das CONTENT_URI Feld entfernen), aber es funktioniert auf mehr Plattformen als jedes einzelne URI fest einprogrammieren.

Beachten Sie, dass diese Reflexionsmethoden exceptions werfen, die durch die Rufmethode gefangen oder erneut geworfen werden müssen.

Andere Tipps

Josef und Isaacs Lösungen für den Zugriff auf den Kalender nur in Android 2.1 und früher arbeiten. auf „Inhalt: //com.android.calendar“: Google hat die Basis Inhalt URI in 2.2 von „// Kalender Inhalt“ geändert. Diese Änderung bedeutet, dass der beste Ansatz, um zu versuchen, einen Cursor mit dem alten Basis-URI zu erhalten, und wenn die zurück Cursor null sind, dann versuchen, die neue Basis-URI.

Bitte beachten Sie, dass ich aus der Open-Source-Test-Code dass Shane Conder und Lauren Darcey bietet mit ihrer Arbeiten mit dem Android-Kalender Artikel.

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
}

Derzeit ist dies möglich, nicht ohne private APIs (Josefs Beitrag sehen.) Es ist ein Kalender-Provider, aber es ist noch nicht öffentlich. Es könnte jederzeit ändern und Ihre App brechen.
Obwohl, wird es wahrscheinlich nicht ändern (Ich glaube nicht, dass sie es ändern werden von „Kalender“), so könnten Sie in der Lage sein, es zu benutzen. Aber meine Empfehlung ist, eine separate Klasse wie folgt zu verwenden:

public class CalendarProvider {
     public static final Uri CONTENT_URI = Uri.parse("content://calendar");
     public static final String TITLE = "title";
     public static final String ....

Und direkt diejenigen anstelle der Saiten verwenden. So können Sie es sehr leicht ändern, wenn / wenn die API-Änderungen oder es wird die Öffentlichkeit zugänglich gemacht.

Sie können den Kalender Content-Provider (com.android.providers.calendar.CalendarProvider) verwenden. Beispiel:


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.
}

Bearbeiten : Sie könnte dies wollen in eine Hülle setzen (siehe Isaacs Post ), wie es zur Zeit eine private API.

Sie können die CalendarContract von hier verwenden: https://github.com/dschuermann/android- Kalender-Kompatibilität

Es ist die gleiche API-Klasse als auf Android 4, machte aber mit Android arbeiten> = 2.2.

Über die API, die sich ändern können ... Die ganze Content Ansatz wird es nicht so schon schnell ändern viele Probleme nur durch die Aktualisierung der Saiten überwinden. Dafür erstellen Konstanten, die Sie über das gesamte Projekt wiederverwendet werden.

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

Wenn Sie eine richtige private API möchten, müssen Sie einen pojo und einige Dienstleistungen wie diese erstellen müssen:

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);

}

und so weiter. Auf diese Weise werden Sie nur das CalendarEvent Objekt zu aktualisieren und diesen Service falls die API-Änderungen.

Nicks Lösung beinhaltet managedQuery, die nicht im Kontext Klasse definiert ist. Viele Male, wenn Sie die Dinge im Hintergrund laufen würden Sie wollen ein Kontextobjekt verwenden. Hier ist eine modifizierte Version:

public String getCalendarUriBase () {

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

Der Haken für null sollte hier nicht durchgeführt werden, da es könnte mehr Ausnahmen, auch wenn der managedQuery früher gelungen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top