Der Kalenderanbieter ist ein Repository für die Kalendertermine eines Nutzers. Mit der Calendar Provider API können Sie Kalender, Termine, Teilnehmer, Erinnerungen usw. abfragen, einfügen, aktualisieren und löschen.
Die Kalenderanbieter-API kann von Anwendungen und Synchronisierungsadaptern verwendet werden. Die Regeln variieren je nach Art des Programms, das die Aufrufe ausführt. In diesem Dokument geht es hauptsächlich um die Verwendung der Calendar Provider API als Anwendung. Informationen zu den Unterschieden zwischen Synchronisatoren finden Sie unter Synchronisatoren.
Normalerweise muss das Manifest einer App die entsprechenden Berechtigungen enthalten, die unter Nutzerberechtigungen beschrieben sind, um Kalenderdaten lesen oder schreiben zu können. Der Kalenderanbieter bietet eine Reihe von Intents, um häufige Vorgänge zu vereinfachen, wie unter Kalender-Intents beschrieben. Über diese Intents werden Nutzer zur Kalenderanwendung weitergeleitet, um Termine einzugeben, anzusehen und zu bearbeiten. Der Nutzer interagiert mit der Kalenderanwendung und kehrt dann zur ursprünglichen Anwendung zurück. Ihre Anwendung muss daher keine Berechtigungen anfordern und auch keine Benutzeroberfläche zum Anzeigen oder Erstellen von Ereignissen bereitstellen.
Grundlegende Informationen
Inhaltsanbieter speichern Daten und stellen sie für Anwendungen zur Verfügung. Die auf der Android-Plattform angebotenen Contentanbieter (einschließlich des Kalenderanbieters) stellen Daten in der Regel als eine Reihe von Tabellen auf der Grundlage eines relationalen Datenbankmodells bereit, wobei jede Zeile ein Datensatz und jede Spalte Daten eines bestimmten Typs und einer bestimmten Bedeutung enthält. Über die Kalenderanbieter-API können Anwendungen und Synchronadapter Lese-/Schreibzugriff auf die Datenbanktabellen erhalten, die die Kalenderdaten eines Nutzers enthalten.
Jeder Inhaltsanbieter stellt einen öffentlichen URI bereit (als Uri
-Objekt verpackt), der seinen Datensatz eindeutig identifiziert. Ein Contentanbieter, der mehrere Datensätze (mehrere Tabellen) verwaltet, stellt für jeden einen separaten URI bereit. Alle URIs für Anbieter beginnen mit dem String „content://“. Damit wird angegeben, dass die Daten von einem Contentanbieter verwaltet werden. Der Calendar Provider definiert Konstanten für die URIs für jede seiner Klassen (Tabellen). Diese URIs haben das Format <class>.CONTENT_URI
. Beispiel: Events.CONTENT_URI
.
Abbildung 1 zeigt eine grafische Darstellung des Datenmodells des Kalenderanbieters. Es werden die Haupttabellen und die Felder angezeigt, die sie miteinander verknüpfen.
Ein Nutzer kann mehrere Kalender haben und verschiedene Kalender können mit verschiedenen Kontotypen verknüpft sein (z. B. Google Kalender, Exchange usw.).
Mit CalendarContract
wird das Datenmodell von kalender- und terminbezogenen Informationen definiert. Diese Daten werden in einer Reihe von Tabellen gespeichert, die unten aufgeführt sind.
Table (Class) | Beschreibung |
---|---|
Diese Tabelle enthält die kalenderspezifischen Informationen. Jede Zeile in dieser Tabelle enthält die Details für einen einzelnen Kalender, z. B. den Namen, die Farbe und die Synchronisierungsinformationen. | |
CalendarContract.Events |
Diese Tabelle enthält die ereignisspezifischen Informationen. Jede Zeile in dieser Tabelle enthält die Informationen zu einem einzelnen Ereignis, z. B. den Titel, den Ort, die Start- und Endzeit usw. Das Ereignis kann einmalig oder mehrmals stattfinden. Teilnehmer, Erinnerungen und erweiterte Properties werden in separaten Tabellen gespeichert.
Sie haben jeweils ein EVENT_ID , das auf das _ID in der Ereignistabelle verweist. |
CalendarContract.Instances |
Diese Tabelle enthält die Start- und Endzeit für jedes Auftreten eines Ereignisses. Jede Zeile in dieser Tabelle steht für ein einzelnes Ereignis. Für einmalige Ereignisse gibt es eine 1:1-Zuordnung von Instanzen zu Ereignissen. Für wiederkehrende Termine werden automatisch mehrere Zeilen generiert, die mehreren Vorkommen des Termins entsprechen. |
CalendarContract.Attendees |
Diese Tabelle enthält die Informationen zu den Veranstaltungsteilnehmern (Gast). Jede Zeile steht für einen einzelnen Gast einer Veranstaltung. Hier werden die Art des Gastes und die Antwort des Gastes auf die Einladung zur Veranstaltung angegeben. |
CalendarContract.Reminders |
Diese Tabelle enthält die Daten zu Benachrichtigungen. Jede Zeile steht für eine einzelne Benachrichtigung für ein Ereignis. Ein Ereignis kann mehrere Erinnerungen haben. Die maximale Anzahl von Erinnerungen pro Termin wird in MAX_REMINDERS angegeben und durch den Synchronisierungsadapter festgelegt, der Inhaber des jeweiligen Kalenders ist. Erinnerungen werden in Minuten vor dem Ereignis angegeben und haben eine Methode, die bestimmt, wie der Nutzer benachrichtigt wird. |
Die Calendar Provider API ist flexibel und leistungsfähig. Gleichzeitig ist es wichtig, eine gute Nutzererfahrung zu bieten und die Integrität des Kalenders und seiner Daten zu schützen. Beachten Sie daher bei der Verwendung der API Folgendes:
- Kalendertermine einfügen, aktualisieren und ansehen Wenn Sie Termine direkt im Kalenderanbieter einfügen, ändern und lesen möchten, benötigen Sie die entsprechenden Berechtigungen. Wenn Sie jedoch keine vollwertige Kalenderanwendung oder keinen Synchronadapter entwickeln, ist es nicht erforderlich, diese Berechtigungen anzufordern. Sie können stattdessen Intents verwenden, die von der Kalender-App von Android unterstützt werden, um Lese- und Schreibvorgänge an diese App weiterzuleiten. Wenn Sie die Intents verwenden, werden Nutzer von Ihrer App an die Kalender-App weitergeleitet, um den gewünschten Vorgang in einem vorausgefüllten Formular auszuführen. Danach werden sie zu Ihrer Anwendung zurückgeleitet. Wenn Sie Ihre Anwendung so entwerfen, dass sie gängige Vorgänge über Google Kalender ausführt, bieten Sie Ihren Nutzern eine einheitliche, robuste Benutzeroberfläche. Dies ist der empfohlene Ansatz. Weitere Informationen finden Sie unter Kalender-Intents.
- Synchronisieren Sie die Adapter. Ein Synchronisierungsadapter synchronisiert die Kalenderdaten auf dem Gerät eines Nutzers mit einem anderen Server oder einer anderen Datenquelle. Die Tabellen
CalendarContract.Calendars
undCalendarContract.Events
enthalten Spalten, die für die zu verwendenden Synchronisierungsadapter reserviert sind. Anbieter und Anwendungen dürfen sie nicht ändern. Sie sind nur dann sichtbar, wenn auf sie als Synchronadapter zugegriffen wird. Weitere Informationen zu Synchronisatoren finden Sie unter Synchronisatoren.
Nutzerberechtigungen
Zum Lesen von Kalenderdaten muss eine App die Berechtigung READ_CALENDAR
in die Manifestdatei aufnehmen. Sie muss die Berechtigung WRITE_CALENDAR
zum Löschen, Einfügen oder Aktualisieren von Kalenderdaten enthalten:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"...> <uses-sdk android:minSdkVersion="14" /> <uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.permission.WRITE_CALENDAR" /> ... </manifest>
Tabelle „Kalender“
Die Tabelle CalendarContract.Calendars
enthält Details für einzelne Kalender. Die folgenden Kalenderspalten können sowohl von einer Anwendung als auch von einem Synchronisierungsadapter geschrieben werden.
Eine vollständige Liste der unterstützten Felder finden Sie in der CalendarContract.Calendars
-Referenz.
Konstante | Beschreibung |
---|---|
NAME |
Der Name des Kalenders. |
CALENDAR_DISPLAY_NAME |
Der Name dieses Kalenders, der dem Nutzer angezeigt wird. |
VISIBLE |
Ein boolescher Wert, der angibt, ob der Kalender angezeigt werden soll. Ein Wert von 0 gibt an, dass Termine, die mit diesem Kalender verknüpft sind, nicht angezeigt werden sollen. Ein Wert von 1 gibt an, dass Termine, die mit diesem Kalender verknüpft sind, angezeigt werden sollen. Dieser Wert wirkt sich auf die Generierung von Zeilen in der Tabelle CalendarContract.Instances aus. |
SYNC_EVENTS |
Ein boolescher Wert, der angibt, ob der Kalender synchronisiert und seine Termine auf dem Gerät gespeichert werden sollen. Bei einem Wert von 0 wird festgelegt, dass dieser Kalender nicht synchronisiert und keine Termine auf dem Gerät gespeichert werden sollen. Der Wert „1“ besagt, dass Termine für diesen Kalender synchronisiert und die Termine auf dem Gerät gespeichert werden. |
Kontotyp für alle Vorgänge angeben
Wenn Sie eine Abfrage für eine Calendars.ACCOUNT_NAME
stellen, muss Calendars.ACCOUNT_TYPE
auch in der Auswahl enthalten sein. Das liegt daran, dass ein bestimmtes Konto nur dann als eindeutig betrachtet wird, wenn sowohl sein ACCOUNT_NAME
als auch sein ACCOUNT_TYPE
eindeutig sind. ACCOUNT_TYPE
ist der String, der dem Konto-Authenticator entspricht, der verwendet wurde, als das Konto mit der AccountManager
registriert wurde. Es gibt auch einen speziellen Kontotyp namens ACCOUNT_TYPE_LOCAL
für Kalender, die nicht mit einem Gerätekonto verknüpft sind.
ACCOUNT_TYPE_LOCAL
-Konten werden nicht synchronisiert.
Kalender abfragen
Das folgende Beispiel zeigt, wie Sie die Kalender eines bestimmten Nutzers abrufen. Der Abfragevorgang wird in diesem Beispiel der Einfachheit halber im Benutzeroberflächen-Thread („Hauptthread“) dargestellt. In der Praxis sollte dies in einem asynchronen Thread statt im Hauptthread erfolgen. Weitere Informationen finden Sie unter Ladeprogramme. Wenn Sie Daten nicht nur lesen, sondern auch ändern, lesen Sie den Hilfeartikel AsyncQueryHandler
.
Kotlin
// Projection array. Creating indices for this array instead of doing // dynamic lookups improves performance. private val EVENT_PROJECTION: Array<String> = arrayOf( CalendarContract.Calendars._ID, // 0 CalendarContract.Calendars.ACCOUNT_NAME, // 1 CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, // 2 CalendarContract.Calendars.OWNER_ACCOUNT // 3 ) // The indices for the projection array above. private const val PROJECTION_ID_INDEX: Int = 0 private const val PROJECTION_ACCOUNT_NAME_INDEX: Int = 1 private const val PROJECTION_DISPLAY_NAME_INDEX: Int = 2 private const val PROJECTION_OWNER_ACCOUNT_INDEX: Int = 3
Java
// Projection array. Creating indices for this array instead of doing // dynamic lookups improves performance. public static final String[] EVENT_PROJECTION = new String[] { Calendars._ID, // 0 Calendars.ACCOUNT_NAME, // 1 Calendars.CALENDAR_DISPLAY_NAME, // 2 Calendars.OWNER_ACCOUNT // 3 }; // The indices for the projection array above. private static final int PROJECTION_ID_INDEX = 0; private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1; private static final int PROJECTION_DISPLAY_NAME_INDEX = 2; private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;
Im nächsten Teil des Beispiels erstellen Sie die Abfrage. Durch die Auswahl werden die Kriterien für die Abfrage festgelegt. In diesem Beispiel wird in der Abfrage nach Kalendern gesucht, die die ACCOUNT_NAME
„hera@beispiel.de“, die ACCOUNT_TYPE
„beispiel.de“ und die OWNER_ACCOUNT
„hera@beispiel.de“ enthalten. Wenn Sie alle Kalender sehen möchten, die ein Nutzer aufgerufen hat, nicht nur die Kalender, die ihm gehören, lassen Sie OWNER_ACCOUNT
weg.
Die Abfrage gibt ein Cursor
-Objekt zurück, mit dem Sie den von der Datenbankabfrage zurückgegebenen Ergebnissatz durchsuchen können. Weitere Informationen zur Verwendung von Abfragen bei Contentanbietern finden Sie unter Contentanbieter.
Kotlin
// Run query val uri: Uri = CalendarContract.Calendars.CONTENT_URI val selection: String = "((${CalendarContract.Calendars.ACCOUNT_NAME} = ?) AND (" + "${CalendarContract.Calendars.ACCOUNT_TYPE} = ?) AND (" + "${CalendarContract.Calendars.OWNER_ACCOUNT} = ?))" val selectionArgs: Array<String> = arrayOf("hera@example.com", "com.example", "hera@example.com") val cur: Cursor = contentResolver.query(uri, EVENT_PROJECTION, selection, selectionArgs, null)
Java
// Run query Cursor cur = null; ContentResolver cr = getContentResolver(); Uri uri = Calendars.CONTENT_URI; String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" + Calendars.ACCOUNT_TYPE + " = ?) AND (" + Calendars.OWNER_ACCOUNT + " = ?))"; String[] selectionArgs = new String[] {"hera@example.com", "com.example", "hera@example.com"}; // Submit the query and get a Cursor object back. cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);
Im nächsten Abschnitt wird der Cursor verwendet, um den Ergebnissatz durchzugehen. Dabei werden die Konstanten verwendet, die zu Beginn des Beispiels festgelegt wurden, um die Werte für jedes Feld zurückzugeben.
Kotlin
// Use the cursor to step through the returned records while (cur.moveToNext()) { // Get the field values val calID: Long = cur.getLong(PROJECTION_ID_INDEX) val displayName: String = cur.getString(PROJECTION_DISPLAY_NAME_INDEX) val accountName: String = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX) val ownerName: String = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX) // Do something with the values... }
Java
// Use the cursor to step through the returned records while (cur.moveToNext()) { long calID = 0; String displayName = null; String accountName = null; String ownerName = null; // Get the field values calID = cur.getLong(PROJECTION_ID_INDEX); displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX); accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX); ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX); // Do something with the values... ... }
Kalender ändern
Wenn Sie einen Kalender aktualisieren möchten, können Sie die _ID
des Kalenders entweder als angehängte ID an den Uri (withAppendedId()
) oder als erstes Auswahlelement angeben. Die Auswahl sollte mit "_id=?"
beginnen und die erste selectionArg
sollte die _ID
des Kalenders sein.
Du kannst Aktualisierungen auch vornehmen, indem du die ID im URI codierst. In diesem Beispiel wird der Anzeigename eines Kalenders mithilfe des (withAppendedId()
)-Ansatzes geändert:
Kotlin
const val DEBUG_TAG: String = "MyActivity" ... val calID: Long = 2 val values = ContentValues().apply { // The new display name for the calendar put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar") } val updateUri: Uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, calID) val rows: Int = contentResolver.update(updateUri, values, null, null) Log.i(DEBUG_TAG, "Rows updated: $rows")
Java
private static final String DEBUG_TAG = "MyActivity"; ... long calID = 2; ContentValues values = new ContentValues(); // The new display name for the calendar values.put(Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar"); Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID); int rows = getContentResolver().update(updateUri, values, null, null); Log.i(DEBUG_TAG, "Rows updated: " + rows);
Kalender einfügen
Kalender sollten hauptsächlich über einen Synchronisierungsadapter verwaltet werden. Daher sollten Sie neue Kalender nur als Synchronisierungsadapter einfügen. In der Regel können Anwendungen nur oberflächliche Änderungen an Kalendern vornehmen, z. B. den Anzeigenamen ändern. Wenn eine Anwendung einen lokalen Kalender erstellen muss, kann sie die Kalendereinfügung als Synchronisierungsadapter mit einer ACCOUNT_TYPE
von ACCOUNT_TYPE_LOCAL
ausführen.
ACCOUNT_TYPE_LOCAL
ist ein spezieller Kontotyp für Kalender, die nicht mit einem Gerätekonto verknüpft sind. Kalender dieses Typs werden nicht mit einem Server synchronisiert. Weitere Informationen zu Synchronisatoren finden Sie unter Synchronisatoren.
Tabelle mit Ereignissen
Die Tabelle CalendarContract.Events
enthält Details zu einzelnen Ereignissen. Wenn eine Anwendung Ereignisse hinzufügen, aktualisieren oder löschen möchte, muss sie die Berechtigung WRITE_CALENDAR
in ihrer Manifestdatei angeben.
Die folgenden Ereignisspalten können sowohl von einer Anwendung als auch von einem Synchronisierungsadapter geschrieben werden. Eine vollständige Liste der unterstützten Felder findest du in der CalendarContract.Events
-Referenz.
Konstante | Beschreibung |
---|---|
CALENDAR_ID |
Die _ID des Kalenders, zu dem der Termin gehört. |
ORGANIZER |
E-Mail-Adresse des Organisators (Eigentümers) des Termins. |
TITLE |
Der Titel der Veranstaltung. |
EVENT_LOCATION |
Der Ort, an dem die Veranstaltung stattfindet. |
DESCRIPTION |
Die Beschreibung des Ereignisses. |
DTSTART |
Der Beginn des Ereignisses in UTC-Millisekunden seit der Epoche. |
DTEND |
Die Zeit, zu der das Ereignis endet, in Millisekunden nach der Epoche (UTC). |
EVENT_TIMEZONE |
Die Zeitzone für das Ereignis. |
EVENT_END_TIMEZONE |
Die Zeitzone für das Ende des Termins. |
DURATION |
Die Dauer des Ereignisses im RFC5545-Format.
Ein Wert von "PT1H" gibt beispielsweise an, dass das Ereignis eine Stunde dauern soll, und ein Wert von "P2W" eine Dauer von zwei Wochen. |
ALL_DAY |
Ein Wert von 1 gibt an, dass dieses Ereignis den ganzen Tag dauert, wie in der lokalen Zeitzone definiert. Ein Wert von 0 gibt an, dass es sich um ein regelmäßiges Ereignis handelt, das zu jeder Tageszeit beginnen und enden kann. |
RRULE |
Die Wiederholungsregel für das Ereignisformat. Beispiel: "FREQ=WEEKLY;COUNT=10;WKST=SU" . Weitere Beispiele finden Sie hier. |
RDATE |
Die Wiederholungsdaten des Ereignisses.
Normalerweise wird RDATE in Kombination mit RRULE verwendet, um eine Gesamtheit sich wiederholender Vorkommen zu definieren. Weitere Informationen finden Sie in der RFC 5545-Spezifikation. |
AVAILABILITY |
Ob dieses Ereignis als geschäftige Zeit gilt oder als verfügbare Zeit, die überplant werden kann. |
GUESTS_CAN_MODIFY |
Ob Gäste den Termin bearbeiten können. |
GUESTS_CAN_INVITE_OTHERS |
Ob Gäste andere Gäste einladen können. |
GUESTS_CAN_SEE_GUESTS |
Ob Gäste die Teilnehmerliste sehen können. |
Hinzufügen von Terminen
Wenn Ihre Anwendung ein neues Ereignis einfügt, empfehlen wir die Verwendung eines INSERT
-Intents, wie unter Ereignisse mithilfe eines Intents einfügen beschrieben. Sie können Ereignisse aber auch direkt einfügen. In diesem Abschnitt wird beschrieben, wie das geht.
Beachten Sie beim Einfügen eines neuen Ereignisses die folgenden Regeln:
- Sie müssen
CALENDAR_ID
undDTSTART
angeben. - Sie müssen eine
EVENT_TIMEZONE
angeben. MitgetAvailableIDs()
können Sie eine Liste der installierten Zeitzonen-IDs des Systems abrufen. Diese Regel gilt nicht, wenn Sie ein Ereignis über denINSERT
-Intent einfügen, wie unter Ereignisse über einen Intent einfügen beschrieben. In diesem Fall wird eine Standardzeitzone angegeben. - Bei einmaligen Ereignissen muss
DTEND
angegeben werden. - Bei wiederkehrenden Ereignissen müssen Sie zusätzlich zu
RRULE
oderRDATE
einenDURATION
angeben. Diese Regel gilt nicht, wenn Sie ein Ereignis über denINSERT
-Intent einfügen, der unter Ereignisse über einen Intent einfügen beschrieben wird. In diesem Fall können SieRRULE
in Verbindung mitDTSTART
undDTEND
verwenden. Die Kalenderanwendung wandelt den Wert dann automatisch in eine Dauer um.
Hier ist ein Beispiel für das Einfügen eines Ereignisses. Dies wird der Einfachheit halber im UI-Thread ausgeführt. In der Praxis sollten Einfügungen und Aktualisierungen in einem asynchronen Thread erfolgen, um die Aktion in einen Hintergrundthread zu verschieben. Weitere Informationen finden Sie unter AsyncQueryHandler
.
Kotlin
val calID: Long = 3 val startMillis: Long = Calendar.getInstance().run { set(2012, 9, 14, 7, 30) timeInMillis } val endMillis: Long = Calendar.getInstance().run { set(2012, 9, 14, 8, 45) timeInMillis } ... val values = ContentValues().apply { put(CalendarContract.Events.DTSTART, startMillis) put(CalendarContract.Events.DTEND, endMillis) put(CalendarContract.Events.TITLE, "Jazzercise") put(CalendarContract.Events.DESCRIPTION, "Group workout") put(CalendarContract.Events.CALENDAR_ID, calID) put(CalendarContract.Events.EVENT_TIMEZONE, "America/Los_Angeles") } val uri: Uri = contentResolver.insert(CalendarContract.Events.CONTENT_URI, values) // get the event ID that is the last element in the Uri val eventID: Long = uri.lastPathSegment.toLong() // // ... do something with event ID // //
Java
long calID = 3; long startMillis = 0; long endMillis = 0; Calendar beginTime = Calendar.getInstance(); beginTime.set(2012, 9, 14, 7, 30); startMillis = beginTime.getTimeInMillis(); Calendar endTime = Calendar.getInstance(); endTime.set(2012, 9, 14, 8, 45); endMillis = endTime.getTimeInMillis(); ... ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); values.put(Events.DTSTART, startMillis); values.put(Events.DTEND, endMillis); values.put(Events.TITLE, "Jazzercise"); values.put(Events.DESCRIPTION, "Group workout"); values.put(Events.CALENDAR_ID, calID); values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles"); Uri uri = cr.insert(Events.CONTENT_URI, values); // get the event ID that is the last element in the Uri long eventID = Long.parseLong(uri.getLastPathSegment()); // // ... do something with event ID // //
Hinweis:In diesem Beispiel wird die Ereignis-ID nach dem Erstellen des Ereignisses erfasst. Das ist die einfachste Möglichkeit, eine Ereignis-ID zu erhalten. Sie benötigen die Ereignis-ID häufig, um andere Kalenderaktionen auszuführen, z. B. um einem Termin Teilnehmer oder Erinnerungen hinzuzufügen.
Updates
Wenn Nutzer in Ihrer App ein Ereignis bearbeiten sollen, empfehlen wir die Verwendung eines EDIT
-Intents, wie unter Ereignisse mit einem Intent bearbeiten beschrieben.
Bei Bedarf können Sie Termine aber auch direkt bearbeiten. Wenn Sie ein Ereignis aktualisieren möchten, können Sie die _ID
des Ereignisses entweder als angehängte ID an den URI (withAppendedId()
) oder als erstes Auswahlelement angeben.
Die Auswahl sollte mit "_id=?"
beginnen und die erste selectionArg
sollte die _ID
des Ereignisses sein. Sie können Aktualisierungen auch mit einer Auswahl ohne ID vornehmen. Hier ist ein Beispiel für die Aktualisierung eines Ereignisses: Dabei wird der Titel des Termins mit dem withAppendedId()
-Ansatz geändert:
Kotlin
val DEBUG_TAG = "MyActivity" ... val eventID: Long = 188 ... val values = ContentValues().apply { // The new title for the event put(CalendarContract.Events.TITLE, "Kickboxing") } val updateUri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val rows: Int = contentResolver.update(updateUri, values, null, null) Log.i(DEBUG_TAG, "Rows updated: $rows")
Java
private static final String DEBUG_TAG = "MyActivity"; ... long eventID = 188; ... ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); Uri updateUri = null; // The new title for the event values.put(Events.TITLE, "Kickboxing"); updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); int rows = cr.update(updateUri, values, null, null); Log.i(DEBUG_TAG, "Rows updated: " + rows);
Termine löschen
Sie können ein Ereignis entweder anhand seiner _ID
als angehängte ID im URI oder mithilfe der Standardauswahl löschen. Wenn Sie eine angehängte ID verwenden, können Sie keine Auswahl treffen.
Es gibt zwei Versionen von „delete“: als Anwendung und als Synchronisierungsadapter. Beim Löschen einer Anwendung wird in der Spalte deleted der Wert 1 festgelegt. Dieses Flag teilt dem Synchronisierungsadapter mit, dass die Zeile gelöscht wurde und dass diese Löschung an den Server weitergegeben werden soll. Wenn ein Synchronisierungsadapter gelöscht wird, werden das Ereignis und alle zugehörigen Daten aus der Datenbank entfernt. Hier ist ein Beispiel für eine Anwendung, die ein Ereignis über seine _ID
löscht:
Kotlin
val DEBUG_TAG = "MyActivity" ... val eventID: Long = 201 ... val deleteUri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val rows: Int = contentResolver.delete(deleteUri, null, null) Log.i(DEBUG_TAG, "Rows deleted: $rows")
Java
private static final String DEBUG_TAG = "MyActivity"; ... long eventID = 201; ... ContentResolver cr = getContentResolver(); Uri deleteUri = null; deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); int rows = cr.delete(deleteUri, null, null); Log.i(DEBUG_TAG, "Rows deleted: " + rows);
Tabelle „Teilnehmer“
Jede Zeile der Tabelle CalendarContract.Attendees
steht für einen einzelnen Teilnehmer oder Gast einer Veranstaltung. Wenn du query()
aufrufst, wird eine Liste der Teilnehmer für die Veranstaltung mit der angegebenen EVENT_ID
zurückgegeben.
Diese EVENT_ID
muss mit der _ID
eines bestimmten Ereignisses übereinstimmen.
In der folgenden Tabelle sind die beschreibbaren Felder aufgeführt. Wenn Sie einen neuen Teilnehmer einfügen, müssen Sie alle Teilnehmer mit Ausnahme von ATTENDEE_NAME
angeben.
Konstante | Beschreibung |
---|---|
EVENT_ID |
Die ID des Ereignisses. |
ATTENDEE_NAME |
Der Name des Teilnehmers. |
ATTENDEE_EMAIL |
Die E-Mail-Adresse des Teilnehmers. |
ATTENDEE_RELATIONSHIP |
Die Beziehung des Teilnehmers zur Veranstaltung. Eine der folgenden Optionen: |
ATTENDEE_TYPE |
Der Teilnehmertyp. Eine der folgenden Optionen: |
ATTENDEE_STATUS |
Der Teilnahmestatus des Gasts. Eine der folgenden Optionen: |
Teilnehmer hinzufügen
In diesem Beispiel wird einem Termin ein einzelner Teilnehmer hinzugefügt. Beachten Sie, dass EVENT_ID
erforderlich ist:
Kotlin
val eventID: Long = 202 ... val values = ContentValues().apply { put(CalendarContract.Attendees.ATTENDEE_NAME, "Trevor") put(CalendarContract.Attendees.ATTENDEE_EMAIL, "trevor@example.com") put( CalendarContract.Attendees.ATTENDEE_RELATIONSHIP, CalendarContract.Attendees.RELATIONSHIP_ATTENDEE ) put(CalendarContract.Attendees.ATTENDEE_TYPE, CalendarContract.Attendees.TYPE_OPTIONAL) put( CalendarContract.Attendees.ATTENDEE_STATUS, CalendarContract.Attendees.ATTENDEE_STATUS_INVITED ) put(CalendarContract.Attendees.EVENT_ID, eventID) } val uri: Uri = contentResolver.insert(CalendarContract.Attendees.CONTENT_URI, values)
Java
long eventID = 202; ... ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); values.put(Attendees.ATTENDEE_NAME, "Trevor"); values.put(Attendees.ATTENDEE_EMAIL, "trevor@example.com"); values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE); values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL); values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED); values.put(Attendees.EVENT_ID, eventID); Uri uri = cr.insert(Attendees.CONTENT_URI, values);
Tabelle „Erinnerungen“
Jede Zeile der Tabelle CalendarContract.Reminders
steht für eine einzelne Erinnerung für ein Ereignis. Wenn Sie query()
aufrufen, wird eine Liste von Erinnerungen für das Ereignis mit dem angegebenen EVENT_ID
zurückgegeben.
In der folgenden Tabelle sind die beschreibbaren Felder für Erinnerungen aufgeführt. Sie müssen alle angegeben werden, wenn Sie eine neue Erinnerung einfügen. Synchronadapter geben die von ihnen unterstützten Arten von Erinnerungen in der Tabelle CalendarContract.Calendars
an. Weitere Informationen finden Sie unter ALLOWED_REMINDERS
.
Konstante | Beschreibung |
---|---|
EVENT_ID |
Die ID des Ereignisses. |
MINUTES |
Die Minuten vor dem Ereignis, zu dem die Erinnerung ausgelöst werden soll. |
METHOD |
Die Weckmethode, die auf dem Server festgelegt ist. Eine der folgenden Optionen: |
Erinnerungen erstellen
In diesem Beispiel wird einem Termin eine Erinnerung hinzugefügt. Die Erinnerung wird 15 Minuten vor dem Termin ausgelöst.
Kotlin
val eventID: Long = 221 ... val values = ContentValues().apply { put(CalendarContract.Reminders.MINUTES, 15) put(CalendarContract.Reminders.EVENT_ID, eventID) put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT) } val uri: Uri = contentResolver.insert(CalendarContract.Reminders.CONTENT_URI, values)
Java
long eventID = 221; ... ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); values.put(Reminders.MINUTES, 15); values.put(Reminders.EVENT_ID, eventID); values.put(Reminders.METHOD, Reminders.METHOD_ALERT); Uri uri = cr.insert(Reminders.CONTENT_URI, values);
Tabelle „Instanzen“
Die Tabelle CalendarContract.Instances
enthält die Start- und Endzeit für die Vorkommnisse eines Ereignisses. Jede Zeile in dieser Tabelle steht für ein einzelnes Ereignis. Die Tabelle „instances“ ist nicht beschreibbar und bietet nur eine Möglichkeit, Ereignisvorkommnisse abzufragen.
In der folgenden Tabelle sind einige der Felder aufgeführt, die Sie für eine Instanz abfragen können. Die Zeitzone wird durch KEY_TIMEZONE_TYPE
und KEY_TIMEZONE_INSTANCES
definiert.
Konstante | Beschreibung |
---|---|
BEGIN |
Der Beginn der Instanz in Millisekunden nach UTC. |
END |
Die Endzeit der Instanz in Millisekunden (UTC). |
END_DAY |
Der julianische Endtag der Instanz, bezogen auf die Zeitzone des Kalenders. |
END_MINUTE |
Die Endzeit der Instanz, gemessen ab Mitternacht in der Zeitzone von Google Kalender. |
EVENT_ID |
Der _ID des Ereignisses für diese Instanz. |
START_DAY |
Der Julianische Starttag der Instanz bezogen auf die Zeitzone des Kalenders. |
START_MINUTE |
Die Minute des Beginns der Instanz, gemessen ab Mitternacht, bezogen auf die Zeitzone des Kalenders. |
Tabelle „instances“ abfragen
Wenn Sie die Tabelle „Instances“ abfragen möchten, müssen Sie im URI einen Zeitraum für die Abfrage angeben. In diesem Beispiel erhält CalendarContract.Instances
über die Implementierung der CalendarContract.EventsColumns
-Oberfläche Zugriff auf das Feld TITLE
.
Mit anderen Worten: TITLE
wird über eine Datenbankansicht zurückgegeben, nicht durch Abfragen der Rohtabelle CalendarContract.Instances
.
Kotlin
const val DEBUG_TAG: String = "MyActivity" val INSTANCE_PROJECTION: Array<String> = arrayOf( CalendarContract.Instances.EVENT_ID, // 0 CalendarContract.Instances.BEGIN, // 1 CalendarContract.Instances.TITLE // 2 ) // The indices for the projection array above. const val PROJECTION_ID_INDEX: Int = 0 const val PROJECTION_BEGIN_INDEX: Int = 1 const val PROJECTION_TITLE_INDEX: Int = 2 // Specify the date range you want to search for recurring // event instances val startMillis: Long = Calendar.getInstance().run { set(2011, 9, 23, 8, 0) timeInMillis } val endMillis: Long = Calendar.getInstance().run { set(2011, 10, 24, 8, 0) timeInMillis } // The ID of the recurring event whose instances you are searching // for in the Instances table val selection: String = "${CalendarContract.Instances.EVENT_ID} = ?" val selectionArgs: Array<String> = arrayOf("207") // Construct the query with the desired date range. val builder: Uri.Builder = CalendarContract.Instances.CONTENT_URI.buildUpon() ContentUris.appendId(builder, startMillis) ContentUris.appendId(builder, endMillis) // Submit the query val cur: Cursor = contentResolver.query( builder.build(), INSTANCE_PROJECTION, selection, selectionArgs, null ) while (cur.moveToNext()) { // Get the field values val eventID: Long = cur.getLong(PROJECTION_ID_INDEX) val beginVal: Long = cur.getLong(PROJECTION_BEGIN_INDEX) val title: String = cur.getString(PROJECTION_TITLE_INDEX) // Do something with the values. Log.i(DEBUG_TAG, "Event: $title") val calendar = Calendar.getInstance().apply { timeInMillis = beginVal } val formatter = SimpleDateFormat("MM/dd/yyyy") Log.i(DEBUG_TAG, "Date: ${formatter.format(calendar.time)}") }
Java
private static final String DEBUG_TAG = "MyActivity"; public static final String[] INSTANCE_PROJECTION = new String[] { Instances.EVENT_ID, // 0 Instances.BEGIN, // 1 Instances.TITLE // 2 }; // The indices for the projection array above. private static final int PROJECTION_ID_INDEX = 0; private static final int PROJECTION_BEGIN_INDEX = 1; private static final int PROJECTION_TITLE_INDEX = 2; ... // Specify the date range you want to search for recurring // event instances Calendar beginTime = Calendar.getInstance(); beginTime.set(2011, 9, 23, 8, 0); long startMillis = beginTime.getTimeInMillis(); Calendar endTime = Calendar.getInstance(); endTime.set(2011, 10, 24, 8, 0); long endMillis = endTime.getTimeInMillis(); Cursor cur = null; ContentResolver cr = getContentResolver(); // The ID of the recurring event whose instances you are searching // for in the Instances table String selection = Instances.EVENT_ID + " = ?"; String[] selectionArgs = new String[] {"207"}; // Construct the query with the desired date range. Uri.Builder builder = Instances.CONTENT_URI.buildUpon(); ContentUris.appendId(builder, startMillis); ContentUris.appendId(builder, endMillis); // Submit the query cur = cr.query(builder.build(), INSTANCE_PROJECTION, selection, selectionArgs, null); while (cur.moveToNext()) { String title = null; long eventID = 0; long beginVal = 0; // Get the field values eventID = cur.getLong(PROJECTION_ID_INDEX); beginVal = cur.getLong(PROJECTION_BEGIN_INDEX); title = cur.getString(PROJECTION_TITLE_INDEX); // Do something with the values. Log.i(DEBUG_TAG, "Event: " + title); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(beginVal); DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy"); Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime())); } }
Kalender-Intents
Ihre Anwendung benötigt keine Berechtigungen zum Lesen und Schreiben von Kalenderdaten. Stattdessen kann sie Intents verwenden, die von der Kalender-App von Android unterstützt werden, um Lese- und Schreibvorgänge an diese App weiterzuleiten. In der folgenden Tabelle sind die vom Kalenderanbieter unterstützten Intents aufgeführt:
Aktion | URI | Beschreibung | Extras |
---|---|---|---|
VIEW |
CalendarContract.CONTENT_URI referenzieren.
Ein Beispiel für die Verwendung dieses Intents finden Sie unter Intents zum Ansehen von Kalenderdaten verwenden.
|
Kalender für die in <ms_since_epoch> angegebene Zeit öffnen. |
Keine. |
Events.CONTENT_URI referenzieren.
Ein Beispiel für die Verwendung dieses Intents finden Sie unter Intents zum Ansehen von Kalenderdaten verwenden.
|
Rufen Sie das Ereignis auf, das durch <event_id> angegeben ist. |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
|
EDIT |
Events.CONTENT_URI referenzieren.
Ein Beispiel für die Verwendung dieses Intents finden Sie unter Ereignisse mit einem Intent bearbeiten.
|
Bearbeiten Sie das Ereignis, das durch <event_id> angegeben ist. |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
EDIT INSERT |
Events.CONTENT_URI referenzieren.
Ein Beispiel für die Verwendung dieses Intents finden Sie unter Intent zum Einfügen eines Ereignisses verwenden.
|
Erstellen Sie einen Termin. | Alle in der folgenden Tabelle aufgeführten Extras. |
In der folgenden Tabelle sind die vom Kalenderanbieter unterstützten Intent-Extras aufgeführt:
Intent Extra | Beschreibung |
---|---|
Events.TITLE |
Name für das Ereignis. |
CalendarContract.EXTRA_EVENT_BEGIN_TIME |
Beginn des Ereignisses in Millisekunden ab der Epoche. |
CalendarContract.EXTRA_EVENT_END_TIME |
Endzeit des Ereignisses in Millisekunden seit der Epoche. |
CalendarContract.EXTRA_EVENT_ALL_DAY |
Ein boolescher Wert, der angibt, dass ein Ereignis den ganzen Tag dauert. Der Wert kann true oder false sein. |
Events.EVENT_LOCATION |
Ort des Ereignisses |
Events.DESCRIPTION |
Beschreibung der Veranstaltung. |
Intent.EXTRA_EMAIL |
E-Mail-Adressen der einzuladenden Personen als durch Kommas getrennte Liste. |
Events.RRULE |
Die Wiederholungsregel für den Termin. |
Events.ACCESS_LEVEL |
Ob es sich um eine private oder öffentliche Veranstaltung handelt. |
Events.AVAILABILITY |
Ob dieses Ereignis als belegte Zeit gilt oder als verfügbare Zeit, die überplant werden kann. |
In den folgenden Abschnitten wird beschrieben, wie Sie diese Intents verwenden.
Intent verwenden, um ein Ereignis einzufügen
Mit der INSERT
-Intent kann Ihre Anwendung die Aufgabe zum Einfügen von Terminen an den Kalender selbst weitergeben.
Bei diesem Ansatz muss die Berechtigung WRITE_CALENDAR
nicht einmal in der Manifestdatei Ihrer Anwendung enthalten sein.
Wenn Nutzer eine Anwendung ausführen, die diesen Ansatz verwendet, werden sie von der Anwendung zum Kalender weitergeleitet, um den Termin fertig hinzuzufügen. Bei der INSERT
-Intention werden zusätzliche Felder verwendet, um ein Formular vorab mit den Details des Termins im Kalender auszufüllen. Nutzer können den Termin dann absagen, das Formular bei Bedarf bearbeiten oder den Termin in ihrem Kalender speichern.
Hier ist ein Code-Snippet, mit dem ein Ereignis für den 19. Januar 2012 von 7:30 bis 8:30 Uhr geplant wird. Beachten Sie bei diesem Code-Snippet Folgendes:
Events.CONTENT_URI
wird als URI angegeben.- Die zusätzlichen Felder
CalendarContract.EXTRA_EVENT_BEGIN_TIME
undCalendarContract.EXTRA_EVENT_END_TIME
werden verwendet, um das Formular mit der Uhrzeit des Ereignisses vorab auszufüllen. Die Werte für diese Zeiten müssen in UTC-Millisekunden ab der Epoche angegeben werden. - Im zusätzlichen Feld
Intent.EXTRA_EMAIL
wird eine durch Kommas getrennte Liste der eingeladenen Personen angegeben, die anhand der E-Mail-Adressen festgelegt wird.
Kotlin
val startMillis: Long = Calendar.getInstance().run { set(2012, 0, 19, 7, 30) timeInMillis } val endMillis: Long = Calendar.getInstance().run { set(2012, 0, 19, 8, 30) timeInMillis } val intent = Intent(Intent.ACTION_INSERT) .setData(CalendarContract.Events.CONTENT_URI) .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis) .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis) .putExtra(CalendarContract.Events.TITLE, "Yoga") .putExtra(CalendarContract.Events.DESCRIPTION, "Group class") .putExtra(CalendarContract.Events.EVENT_LOCATION, "The gym") .putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY) .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com") startActivity(intent)
Java
Calendar beginTime = Calendar.getInstance(); beginTime.set(2012, 0, 19, 7, 30); Calendar endTime = Calendar.getInstance(); endTime.set(2012, 0, 19, 8, 30); Intent intent = new Intent(Intent.ACTION_INSERT) .setData(Events.CONTENT_URI) .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()) .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()) .putExtra(Events.TITLE, "Yoga") .putExtra(Events.DESCRIPTION, "Group class") .putExtra(Events.EVENT_LOCATION, "The gym") .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY) .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com"); startActivity(intent);
Ereignis mit einem Intent bearbeiten
Sie können ein Ereignis direkt aktualisieren, wie unter Ereignisse aktualisieren beschrieben. Wenn Sie den Intent EDIT
verwenden, kann eine Anwendung, die keine Berechtigung hat, jedoch die Bearbeitung von Terminen an die Kalenderanwendung übergeben.
Wenn Nutzer die Bearbeitung des Termins im Kalender abgeschlossen haben, werden sie zur ursprünglichen Anwendung zurückgeleitet.
Hier ist ein Beispiel für einen Intent, der einen neuen Titel für ein bestimmtes Ereignis festlegt und Nutzer den Termin im Kalender bearbeiten können.
Kotlin
val eventID: Long = 208 val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val intent = Intent(Intent.ACTION_EDIT) .setData(uri) .putExtra(CalendarContract.Events.TITLE, "My New Title") startActivity(intent)
Java
long eventID = 208; Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); Intent intent = new Intent(Intent.ACTION_EDIT) .setData(uri) .putExtra(Events.TITLE, "My New Title"); startActivity(intent);
Intents zum Ansehen von Kalenderdaten verwenden
Der Kalenderanbieter bietet zwei Möglichkeiten, die VIEW
-Intention zu verwenden:
- Öffnen Sie den Kalender auf ein bestimmtes Datum.
- So rufen Sie ein Ereignis auf:
Hier ein Beispiel, wie Sie den Kalender auf ein bestimmtes Datum öffnen:
Kotlin
val startMillis: Long ... val builder: Uri.Builder = CalendarContract.CONTENT_URI.buildUpon() .appendPath("time") ContentUris.appendId(builder, startMillis) val intent = Intent(Intent.ACTION_VIEW) .setData(builder.build()) startActivity(intent)
Java
// A date-time specified in milliseconds since the epoch. long startMillis; ... Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon(); builder.appendPath("time"); ContentUris.appendId(builder, startMillis); Intent intent = new Intent(Intent.ACTION_VIEW) .setData(builder.build()); startActivity(intent);
Hier ein Beispiel für das Öffnen eines Ereignisses zur Ansicht:
Kotlin
val eventID: Long = 208 ... val uri: Uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID) val intent = Intent(Intent.ACTION_VIEW).setData(uri) startActivity(intent)
Java
long eventID = 208; ... Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); Intent intent = new Intent(Intent.ACTION_VIEW) .setData(uri); startActivity(intent);
Synchronisierungsadapter
Es gibt nur geringfügige Unterschiede bei der Art und Weise, wie eine Anwendung und ein Synchronisierungsadapter auf den Kalenderanbieter zugreifen:
- Ein Synchronisierungsadapter muss angeben, dass es sich um einen Synchronisierungsadapter handelt, indem
CALLER_IS_SYNCADAPTER
auftrue
festgelegt wird. - Ein Synchronisierungsadapter muss
ACCOUNT_NAME
undACCOUNT_TYPE
als Abfrageparameter im URI angeben. - Ein Synchronisierungsadapter hat Schreibzugriff auf mehr Spalten als eine Anwendung oder ein Widget.
Eine Anwendung kann beispielsweise nur einige Eigenschaften eines Kalenders ändern, z. B. seinen Namen, seinen Anzeigenamen, die Sichtbarkeitseinstellung und ob der Kalender synchronisiert wird. Ein Synchronisierungsadapter kann dagegen nicht nur auf diese Spalten, sondern auch auf viele andere zugreifen, z. B. auf Kalenderfarbe, Zeitzone, Zugriffsebene und Standort.
Ein Synchronisierungsadapter ist jedoch auf die angegebenen
ACCOUNT_NAME
undACCOUNT_TYPE
beschränkt.
Hier ist eine Hilfsmethode, mit der Sie einen URI für die Verwendung mit einem Synchronisierungsadapter zurückgeben können:
Kotlin
fun asSyncAdapter(uri: Uri, account: String, accountType: String): Uri { return uri.buildUpon() .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true") .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, account) .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, accountType).build() }
Java
static Uri asSyncAdapter(Uri uri, String account, String accountType) { return uri.buildUpon() .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true") .appendQueryParameter(Calendars.ACCOUNT_NAME, account) .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build(); }