El Proveedor de calendario es un repositorio de los eventos de calendario de un usuario. El La API del Proveedor de calendario te permite consultar, insertar, actualizar y borrar las operaciones en calendarios, eventos, asistentes, recordatorios, etc.
Tanto las aplicaciones como los adaptadores de sincronización pueden usar la API. El varían según el tipo de programa que realice las llamadas. Este documento se enfoca principalmente en el uso de la API de Calendar Provider como aplicación. Para obtener información sobre las diferencias entre los adaptadores de sincronización, consulta Adaptadores de sincronización.
Normalmente, para leer o escribir datos en un calendario, el manifiesto de una aplicación debe incluir los permisos adecuados, que se describen en Permisos del usuario. Para facilitar la realización de operaciones comunes, el Calendario El proveedor ofrece un conjunto de intents, como se describe en Calendario Intents Estos intents llevan a los usuarios a la aplicación de Calendario para insertar, ver y editar eventos. El usuario interactúa con la aplicación de Calendario y, luego, regresa a la aplicación original. De esta manera, tu aplicación no necesita solicitar permisos ni proporcionar una interfaz de usuario para ver o crear eventos.
Conceptos básicos
Los proveedores de contenido almacenan datos y permiten que aplicaciones. Los proveedores de contenido que ofrece la plataforma Android (incluido el Proveedor de calendario) generalmente exponen datos como un conjunto de tablas basadas en un modelo de base de datos relacional en el que cada fila es un registro y cada columna son datos de un tipo y un significado específicos. A través de la API de Calendar Provider, las aplicaciones y los adaptadores de sincronización pueden obtener acceso de lectura/escritura a las tablas de la base de datos que contienen una datos de calendario del usuario.
Cada proveedor de contenido exhibe un URI público (empaquetado como un objeto Uri
) que identifica de forma exclusiva su conjunto de datos. Un proveedor de contenido que controla
varios conjuntos de datos (varias tablas) expone un URI independiente para cada uno. Todas
Los URI de los proveedores comienzan con la cadena “content://”. Esto identifica que los datos son controlados por un proveedor de contenido. El calendario
El proveedor define constantes para los URI de cada una de sus clases (tablas). Estos
Los URI tienen el formato <class>.CONTENT_URI
. Para
por ejemplo, Events.CONTENT_URI
.
La figura 1 muestra una representación gráfica del modelo de datos del Proveedor de calendario. Muestra las tablas principales y los campos que las vinculan entre sí.
Un usuario puede tener varios calendarios, y es posible asociar diferentes calendarios con distintos tipos de cuenta (Calendario de Google, Exchange, etc.).
CalendarContract
define el modelo de datos de la información relacionada con calendarios y eventos. Esos datos se almacenan en una variedad de tablas que se indican a continuación.
Tabla (clase) | Descripción |
---|---|
Esta tabla contiene la información específica del calendario. Cada fila de esta tabla contiene los detalles de un solo calendario, como el nombre, el color, la información de sincronización, etc. | |
CalendarContract.Events |
Esta tabla contiene las
específica del evento. Cada fila de esta tabla tiene la información de un solo
evento, por ejemplo, título, ubicación, hora de inicio, finalización
tiempo, etcétera. El evento puede ocurrir una sola vez o repetirse varias veces. Los asistentes, los recordatorios y las propiedades extendidas se almacenan en tablas independientes.
Cada uno tiene un elemento EVENT_ID
que hace referencia a _ID en la tabla Eventos. |
CalendarContract.Instances |
Esta tabla contiene las las horas de inicio y finalización de cada caso de un evento. Cada fila de esta tabla representa un solo caso de un evento. Para los eventos que solo ocurren una vez, hay una asignación de instancias a eventos en una proporción de 1:1. Para los eventos recurrentes, se generan automáticamente varias filas que corresponden a los diferentes casos de ese evento. |
CalendarContract.Attendees |
Esta tabla contiene las información del asistente al evento (invitado). Cada fila representa un solo invitado de una evento. Especifica el tipo de invitado y su respuesta a la asistencia para el evento. |
CalendarContract.Reminders |
Esta tabla contiene los datos de alerta y notificación. Cada fila representa una sola alerta para un evento. Los
evento puede tener varios recordatorios. La cantidad máxima de recordatorios por evento se especifica en MAX_REMINDERS , que se configura a través del adaptador de sincronización al cual pertenece el calendario en cuestión. Los recordatorios se especifican en minutos antes del evento.
y tienen un método que determina
cómo se alertará al usuario. |
La API del Proveedor de calendario fue diseñada para ser flexible y eficaz. En el al mismo tiempo, es importante ofrecer una buena experiencia del usuario final la integridad del calendario y sus datos. Con ese objetivo, aquí te mostramos algunas cosas que debes recordar al usar la API:
- Insertar, actualizar y visualizar eventos de calendario Para insertar, modificar y leer eventos directamente desde el Proveedor de calendario, necesitas los permisos adecuados. Sin embargo, si no estás compilando una aplicación de calendario completa o un adaptador de sincronización, no es necesario solicitar estos permisos. En su lugar, puedes usar intents compatibles con la aplicación de Calendario de Android para entregar operaciones de lectura y escritura a esa aplicación. Cuando usas las intents, tu aplicación envía a los usuarios a la aplicación de Calendario para que realicen la operación deseada en un formulario precompletado. Cuando terminen, regresarán a tu aplicación. Diseñando tu aplicación para que realice operaciones comunes a través del Calendario les ofreces a los usuarios una interfaz de usuario coherente y sólida. Este es el enfoque recomendado. Para obtener más información, consulta Calendario Intents
- Adaptadores de sincronización. Un adaptador de sincronización sincroniza los datos del calendario que se encuentran en el dispositivo de un usuario con otro servidor u origen de datos. En las tablas
CalendarContract.Calendars
yCalendarContract.Events
, hay columnas que se reservan para que las usen los adaptadores de sincronización. Ni el proveedor ni las aplicaciones deben modificarlas. De hecho, no están visibles a menos que se acceda a ellas como un adaptador de sincronización. Para obtener más información adaptadores de sincronización, consulta Adaptadores de sincronización.
Permisos del usuario
Para leer datos del calendario, una aplicación debe incluir el permiso READ_CALENDAR
en su archivo de manifiesto. Debe incluir el permiso WRITE_CALENDAR
para borrar, insertar o actualizar datos del calendario:
<?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>
Tabla de calendarios
La tabla CalendarContract.Calendars
contiene detalles para calendarios individuales. Las siguientes columnas de Calendario admiten la escritura de una aplicación y un adaptador de sincronización.
Para obtener una lista completa de los campos admitidos, consulta la
CalendarContract.Calendars
.
Constante | Descripción |
---|---|
NAME |
El nombre del calendario. |
CALENDAR_DISPLAY_NAME |
El nombre del calendario que se le muestra al usuario. |
VISIBLE |
Un valor booleano que indica si se seleccionó el calendario para exhibirlo. Un valor de 0 indica que no deben mostrarse los eventos asociados con ese calendario. El valor 1 indica que los eventos asociados con este calendario deben
mostrar. Este valor afecta la generación de filas en la tabla CalendarContract.Instances . |
SYNC_EVENTS |
Es un valor booleano que indica si se debe sincronizar el calendario y si se deben guardar sus eventos en el dispositivo. El valor 0 indica que no debes sincronizar este calendario. almacenar sus eventos en el dispositivo. El valor 1 indica que hay eventos de sincronización para este calendario y almacenar sus eventos en el dispositivo. |
Incluir un tipo de cuenta para todas las operaciones
Si realizas una consulta en un Calendars.ACCOUNT_NAME
, también debes incluir
Calendars.ACCOUNT_TYPE
de la selección. Esto se debe a que una cuenta determinada está
solo se considera único dado tanto su ACCOUNT_NAME
como su
ACCOUNT_TYPE
ACCOUNT_TYPE
es la cadena que corresponde al
autenticador de cuenta que se usó cuando se registró la cuenta en
AccountManager
También hay un tipo especial de cuenta
se llamó a ACCOUNT_TYPE_LOCAL
para
no están asociados con una cuenta del dispositivo.
ACCOUNT_TYPE_LOCAL
cuentas no obtienen
sincronizada.
Consulta de un calendario
Aquí hay un ejemplo que muestra cómo obtener los calendarios que son propiedad de un usuario
usuario. Para simplificar, en este ejemplo, la operación de consulta se muestra en el
de interfaz de usuario ("subproceso principal"). En la práctica, esto se debe realizar en un subproceso asíncrono en lugar del subproceso principal. Para obtener más información, consulta Cargadores. Si no eres solo
leer datos, pero modificarlos, consulta 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;
En la siguiente parte del ejemplo, construyes tu consulta. La selección especifica los criterios para la consulta. En este ejemplo, la consulta busca
calendarios que tienen la ACCOUNT_NAME
"hera@example.com", el ACCOUNT_TYPE
"com.example" y OWNER_ACCOUNT
“hera@example.com”. Si quieres ver todos los calendarios que vio un usuario, no solo los de su propiedad, omite OWNER_ACCOUNT
.
La consulta devuelve un Cursor
.
que puedes usar para recorrer el conjunto de resultados que devuelve la base de datos
para cada búsqueda. Para obtener más información acerca del uso de consultas en proveedores de contenido, consulta Proveedores de contenido.
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);
La siguiente sección usa el cursor para recorrer el conjunto de resultados. Utiliza el las constantes que se configuraron al comienzo del ejemplo para devolver los valores para cada campo.
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... ... }
Modificación de un calendario
Para actualizar un calendario, puedes proporcionar el _ID
del calendario como un ID agregado al
el URI
(withAppendedId()
)
o como el primer elemento de la selección. La selección
debe comenzar con "_id=?"
, y el primer
selectionArg
debe ser el _ID
del calendario.
También puedes realizar actualizaciones codificando el ID en el URI. En este ejemplo, se cambia el nombre visible de un calendario con el enfoque (withAppendedId()
):
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);
Insertar un calendario
Los calendarios están diseñados para ser administrados principalmente por un adaptador de sincronización, por lo que solo debes insertar nuevos calendarios como un adaptador de sincronización. En general,
Las aplicaciones solo pueden realizar cambios superficiales, como cambiar el nombre para mostrar. Si
una aplicación necesita crear un calendario local, puede hacerlo realizando
la inserción del calendario como un adaptador de sincronización mediante un ACCOUNT_TYPE
de ACCOUNT_TYPE_LOCAL
.
ACCOUNT_TYPE_LOCAL
es un tipo de cuenta especial para los calendarios
asociada con una cuenta de dispositivo. Los calendarios de este tipo no se sincronizan con un servidor. Para un
sobre los adaptadores de sincronización, consulta Adaptadores de sincronización.
Tabla de eventos
La tabla CalendarContract.Events
contiene detalles para eventos individuales. Para agregar, actualizar o borrar eventos, una aplicación debe
incluye el permiso WRITE_CALENDAR
en su
archivo de manifiesto.
Las siguientes columnas de eventos admiten la escritura de una aplicación y un adaptador de sincronización. Para obtener una lista completa de los campos admitidos, consulta la referencia de CalendarContract.Events
.
Constante | Descripción |
---|---|
CALENDAR_ID |
El objeto _ID del calendario al que pertenece el evento. |
ORGANIZER |
Correo electrónico del organizador (propietario) del evento. |
TITLE |
Título del evento. |
EVENT_LOCATION |
Lugar donde se realiza el evento. |
DESCRIPTION |
Descripción del evento. |
DTSTART |
Hora de inicio del evento en milisegundos de UTC desde el epoch. |
DTEND |
Hora de finalización del evento en milisegundos de UTC desde el epoch. |
EVENT_TIMEZONE |
Zona horaria del evento. |
EVENT_END_TIMEZONE |
Zona horaria para la hora de finalización del evento. |
DURATION |
Es la duración del evento en formato RFC5545.
Por ejemplo, un valor de "PT1H" indica que el evento
debe durar una hora, y un valor de "P2W" indica una
de 2 semanas. |
ALL_DAY |
El valor igual a 1 indica que el evento transcurre durante un día completo, como lo define la zona horaria local. El valor 0 indica que es un evento normal que puede empezar y finalizan en cualquier momento del día. |
RRULE |
La regla de recurrencia para el formato del evento. Por ejemplo, "FREQ=WEEKLY;COUNT=10;WKST=SU" . Puedes encontrar más ejemplos aquí. |
RDATE |
Las fechas de recurrencia del evento.
Sueles usar RDATE
en conjunto con RRULE
para definir un conjunto agregado
repeticiones. Para obtener más información, consulta la especificación de RFC5545. |
AVAILABILITY |
Indica si este evento cuenta como tiempo ocupado o tiempo libre que puede reprogramarse. |
GUESTS_CAN_MODIFY |
Indica si los invitados pueden modificar el evento. |
GUESTS_CAN_INVITE_OTHERS |
Indica si los invitados pueden invitar a otras personas. |
GUESTS_CAN_SEE_GUESTS |
Indica si los invitados pueden ver la lista de asistentes. |
Agregar eventos
Cuando tu aplicación inserte un evento nuevo, te recomendamos usar un
INSERT
, como se describe en Cómo usar un intent para insertar un evento. Sin embargo, si lo necesitas, puedes insertar eventos directamente. En esta sección, se describe cómo hacerlo.
Aquí te damos las reglas para insertar un nuevo evento:
- Debes incluir
CALENDAR_ID
yDTSTART
. - Debes incluir un
EVENT_TIMEZONE
. Cómo obtener una lista de los IDs de zona horaria instalados del sistema, usagetAvailableIDs()
. Ten en cuenta que esta regla no se aplica si Cuando insertas un evento a través del intentINSERT
, que se describe en Cómo usar un intent para insertar un evento, en el que se proporciona una zona horaria predeterminada. - Para los eventos no recurrentes, debes incluir
DTEND
. - Para eventos recurrentes, debes incluir un
DURATION
además deRRULE
oRDATE
. Ten en cuenta que esta regla no se aplica si Cuando insertas un evento a través del intentINSERT
, que se describe en Cómo usar un intent para insertar un evento, en el que puedes usar unRRULE
junto conDTSTART
yDTEND
, y la aplicación de Calendario lo convierte automáticamente en una duración.
Aquí te mostramos un ejemplo de cómo insertar un evento. Esta acción se realiza en la IU
para que sea más simple. En la práctica, las inserciones y actualizaciones deben realizarse en un
subproceso asíncrono para mover la acción a un subproceso en segundo plano. Para obtener más información, consulta 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 // //
Nota: Observa cómo este ejemplo captura el ID del evento después de la creación del evento. Esta es la forma más fácil de capturar el ID de un evento. A menudo, necesitarás el ID del evento para realizar otras operaciones en el calendario, por ejemplo, para agregar asistentes o recordatorios a un evento.
Eventos de actualización
Si tu aplicación quiere permitir que el usuario edite un evento, te recomendamos
que uses un intent EDIT
, ya que
que se describe en Cómo usar un intent para editar un evento.
Sin embargo, si lo necesitas, puedes editar eventos directamente. Para realizar una actualización de
un evento, puedes proporcionar el _ID
de la
como un ID agregado al URI (withAppendedId()
)
o como el primer elemento de la selección.
La selección debe comenzar con "_id=?"
, y el primer selectionArg
debe ser el _ID
del evento. Puedes
realiza actualizaciones
con una selección sin ID. Este es un ejemplo de cómo actualizar un
evento. Cambia el título del evento con el botón
withAppendedId()
enfoque:
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);
Borrar eventos
Puedes borrar un evento por su _ID
como un ID anexado al URI o mediante
la selección estándar. Si usas un ID agregado, no podrás realizar una selección.
Existen dos versiones de eliminación: como aplicación y como adaptador de sincronización. Los
application delete establece la columna deleted en 1. Esta marca que indica
el adaptador de sincronización que se borró la fila y que esta eliminación debería
propagado al servidor. Eliminar un adaptador de sincronización quita el evento del
base de datos en la nube
junto con todos los datos asociados. Aquí te mostramos un ejemplo de una aplicación que borra un evento a través de su _ID
:
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);
Tabla de asistentes
Cada fila de la tabla CalendarContract.Attendees
representa a un asistente o invitado único a un evento. Al llamar a query()
, se muestra una lista de asistentes al evento con el EVENT_ID
determinado.
Este/a EVENT_ID
debe coincidir con el _ID
de un evento en particular.
En la siguiente tabla, se incluyen los campos que admiten escritura. Cuando insertes un asistente nuevo, debes incluirlos a todos.
excepto ATTENDEE_NAME
.
Constante | Descripción |
---|---|
EVENT_ID |
El ID del evento. |
ATTENDEE_NAME |
El nombre del asistente. |
ATTENDEE_EMAIL |
La dirección de correo electrónico del asistente. |
ATTENDEE_RELATIONSHIP |
La relación del asistente con el evento. Una de las siguientes opciones: |
ATTENDEE_TYPE |
El tipo de asistente. Una de las siguientes opciones: |
ATTENDEE_STATUS |
El estado de asistencia del asistente. Una de las siguientes opciones: |
Agregar asistentes
Aquí te mostramos un ejemplo de cómo agregar un asistente a un evento. Ten en cuenta que se necesita EVENT_ID
:
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);
Tabla de recordatorios
Cada fila de la tabla CalendarContract.Reminders
representa un recordatorio único de un evento. Al llamar a query()
, se muestra una lista de recordatorios para el evento con el EVENT_ID
determinado.
La siguiente tabla incluye los campos de los recordatorios que admiten escritura. Al insertar un nuevo recordatorio, se deben incluir todos. Recuerda que los adaptadores de sincronización especifican los tipos de recordatorios que admiten en la tabla CalendarContract.Calendars
. Consulta
ALLOWED_REMINDERS
para conocer los detalles.
Constante | Descripción |
---|---|
EVENT_ID |
El ID del evento. |
MINUTES |
Cuántos minutos antes del evento se debe enviar el recordatorio. |
METHOD |
El método de alarma, tal como esté configurado en el servidor. Una de las siguientes opciones: |
Agregar recordatorio
Este ejemplo agrega un recordatorio a un evento. El recordatorio se envía 15 minutos antes del evento.
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);
Tabla de instancias
La tabla CalendarContract.Instances
contiene la hora de inicio y finalización de los casos de un evento. Cada fila de esta tabla representa un solo caso de un evento. La tabla de instancias no admite escritura y solo
proporciona una forma de consultar
casos de eventos.
La siguiente tabla incluye algunos de los campos que puedes consultar para una instancia. Ten en cuenta que la zona horaria se define mediante KEY_TIMEZONE_TYPE
y KEY_TIMEZONE_INSTANCES
.
Constante | Descripción |
---|---|
BEGIN |
El horario de inicio de la instancia en milisegundos (UTC). |
END |
El horario de finalización de la instancia en milisegundos (UTC). |
END_DAY |
El día de finalización de la instancia, según el calendario Juliano, en relación con la hora del calendario zona. |
END_MINUTE |
El minuto final de la instancia medido a partir de la media noche, en la zona horaria del calendario. |
EVENT_ID |
El _ID del evento para esta instancia. |
START_DAY |
El día inicial de la instancia, según el calendario juliano, según la zona horaria del calendario. |
START_MINUTE |
El minuto inicial de la instancia medido a partir de la media noche, en relación con la Zona horaria del calendario. |
Consulta de la tabla de instancias
Para consultar la tabla de instancias, debes especificar un intervalo para la consulta en el URI. En este ejemplo, CalendarContract.Instances
obtiene acceso al campo TITLE
a través de su implementación de la interfaz CalendarContract.EventsColumns
.
En otras palabras, TITLE
se muestra a través de una vista de base de datos, no a través de la consulta de la tabla CalendarContract.Instances
sin procesar.
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())); } }
Intents de calendario
Tu aplicación no necesita permisos para leer y escribir datos del calendario. En su lugar, puede usar intents compatibles con la aplicación Calendario de Android para entregar operaciones de lectura y escritura a esa aplicación. La siguiente tabla incluye las intents admitidas por el proveedor de calendario:
Acción | URI | Descripción | Adicionales |
---|---|---|---|
VIEW |
CalendarContract.CONTENT_URI .
Para obtener un ejemplo de cómo usar esta intent, consulta Cómo usar intents para ver datos del calendario.
|
Abre el calendario en la hora especificada por <ms_since_epoch> . |
Ninguno |
Events.CONTENT_URI .
Para ver un ejemplo de cómo usar este intent, consulta Cómo usar intents para ver datos del calendario.
|
Visualiza el evento especificado por <event_id> . |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
|
EDIT |
Events.CONTENT_URI .
Para ver un ejemplo sobre cómo usar este intent, consulta Cómo usar un intent para editar un evento.
|
Edita el evento especificado por <event_id> . |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
EDIT INSERT |
Events.CONTENT_URI
Para ver un ejemplo sobre cómo usar este intent, consulta Cómo usar un intent para insertar un evento.
|
Crea un evento. | Cualquiera de los extras que se indican en la tabla a continuación. |
La siguiente tabla incluye los extras de intents admitidos por el proveedor de calendario:
Extra de intents | Descripción |
---|---|
Events.TITLE |
El nombre del evento. |
CalendarContract.EXTRA_EVENT_BEGIN_TIME |
El horario de inicio del evento en milisegundos desde el epoch. |
CalendarContract.EXTRA_EVENT_END_TIME |
El horario de finalización del evento en milisegundos desde el epoch. |
CalendarContract.EXTRA_EVENT_ALL_DAY |
Valor booleano que indica que un evento transcurre durante todo el día. El valor puede ser
true o false . |
Events.EVENT_LOCATION |
El lugar del evento. |
Events.DESCRIPTION |
La descripción del evento. |
Intent.EXTRA_EMAIL |
Las direcciones de correo electrónico de las personas a las que se invitará, en forma de lista separada por comas. |
Events.RRULE |
La regla de recurrencia para el evento. |
Events.ACCESS_LEVEL |
Indica si el evento es privado o público. |
Events.AVAILABILITY |
Indica si este evento cuenta como tiempo ocupado o tiempo libre que puede reprogramarse. |
Las siguientes secciones describen cómo usar estas intents.
Cómo usar una intent para insertar un evento
Usar la intent INSERT
le permite a tu aplicación asignar la tarea de inserción del evento al calendario mismo.
Con este enfoque, la aplicación no necesita tener el permiso WRITE_CALENDAR
incluido en su archivo de manifiesto.
Cuando los usuarios ejecutan una aplicación que usa este enfoque, la aplicación envía
al Calendario para terminar de agregar el evento. El intent INSERT
usa campos adicionales para
prepropagar un formulario con los detalles del evento en el Calendario Los usuarios pueden
Luego, cancela el evento, edita el formulario según sea necesario o guárdalo en su
calendarios.
Aquí hay un fragmento de código que programa un evento para el 19 de enero de 2012 que se ejecuta de 7:30 a.m. a 8:30 a.m. Observe lo siguiente sobre este fragmento de código:
- Especifica
Events.CONTENT_URI
como el URI. - Usa los campos adicionales
CalendarContract.EXTRA_EVENT_BEGIN_TIME
yCalendarContract.EXTRA_EVENT_END_TIME
para completar previamente el formulario. con la hora del evento. Los valores para estos horarios deben estar en milisegundos de UTC. a partir del ciclo de entrenamiento. - Usa el
Intent.EXTRA_EMAIL
campo adicional para proporcionar una lista de invitados separada por comas, especificada por dirección de correo electrónico.
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);
Cómo usar una intent para editar un evento
Puedes actualizar un evento directamente, como se describe en Actualización de eventos. Pero usar el intent EDIT
permite que una aplicación que
no tiene permiso para transferir la edición del evento a la aplicación Calendario.
Cuando los usuarios terminen de editar el evento en el Calendario, regresarán al
aplicación original.
Aquí te mostramos un ejemplo de una intent que define un nuevo título para un evento especificado y permite a los usuarios editar el evento en el Calendario.
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);
Cómo usar intents para ver datos del calendario
El Proveedor de calendario permite usar la intent VIEW
de dos formas diferentes:
- Para abrir el calendario en una fecha determinada.
- Para ver un evento.
Este es un ejemplo que muestra cómo abrir el calendario en una fecha determinada:
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);
Este es un ejemplo que muestra cómo abrir un evento para visualizarlo:
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);
Adaptadores de sincronización
Existen diferencias mínimas entre cómo una aplicación y un adaptador de sincronización. accede al Proveedor de calendario:
- Un adaptador de sincronización debe especificar que es un adaptador de sincronización estableciendo
CALLER_IS_SYNCADAPTER
entrue
. - Un adaptador de sincronización debe proporcionar un
ACCOUNT_NAME
y unACCOUNT_TYPE
como parámetros de consulta en el URI. - Un adaptador de sincronización tiene acceso de escritura a más columnas que una aplicación o un widget.
Por ejemplo, una aplicación solo puede modificar algunas características de un calendario, como el nombre, el nombre para mostrar, la configuración de visibilidad y si el calendario está sincronizado. En comparación, un adaptador de sincronización puede acceder no solo a esas columnas, sino a muchas otras
como el color del calendario, la zona horaria, el nivel de acceso, la ubicación, etc.
Sin embargo, el adaptador de sincronización se limita a los objetos
ACCOUNT_NAME
yACCOUNT_TYPE
que especificó.
Aquí te mostramos un método de ayuda que puedes usar para mostrar un URI para usar con un adaptador de sincronización:
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(); }