Agenda y calendario. Índice

Documentos relacionados
Servicios de la plataforma Android

Ficheros y acceso a datos - Ejercicios

Ejercicios de fragmentos y compatibilidad

Android y Java para Dispositivos Móviles

Persistencia Android. Índice

Introducción a Python Qué es Python?

LA CLASE VECTOR DEL API JAVA. MÉTODOS TRIMTOSIZE Y ENSURECAPACITY EJEMPLO Y EJERCICIOS RESUELTOS. (CU00922C)

DESARROLLO DE APLICACIONES EN ANDROID

Cómo visualizar la información detallada de un material (desde el trabajar con materiales del SAP ERP)

Servicios de la plataforma Android

Manual de Peticiones a Sistemas. Departamento: Tecnología y Desarrollo. Responsable: Javier Recio

IsoWise - Manual de usuario. Calendario. Página 1

Guía rápida del uso de la planilla en GSIR 3.0

DESARROLLO DE APLICACIONES II

Android. Content Providers

Ejercicios - Aspectos avanzados de Sencha Touch

Cómo realizar y modificar un pedido de libros de texto en

Preguntas frecuentes

Herramientas Google Aplicadas a Educación. Primera parte

PERSISTE Y CAMPUS VIRTUAL

Durante este tema se van a tratar de 2 tipos de errores: los de ejecución y los lógicos. Ignoramos los errores de compilación.

TALLER IOT SOFIA2 Noviembre 2016

Utilizar el calendario (I)

Curso PUDE. Desarrollo de Aplicaciones Móviles en Android

Persistencia en Android: proveedores de contenidos y SharedPreferences

Para comenzar nos dirigiremos a la web:

Manejo de eventos en JavaScript WEB-TECHNOLOGIES

APLICACIÓN: CALIFICACIONES Y FALTAS DE ASISTENCIA

UNIDAD 10. LAS CONSULTAS DE ACCIÓN

Manual de Uso Crono v4.5.11

Todas las actividades de Moodle con fecha límite serán eventos del calendario automáticamente.

Writer (Procesador de textos). Una vez arrancado el programa nos aparecerá la ventana del procesador de textos Writer.

CALENDARIO OUTLOOK Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

Bases de datos en Android LSUB, GYSC, URJC

LISTAS CIRCULARES. // Métodos private CElemento() {} // constructor. ultimo

HERRAMIENTAS AHORA FREEWARE

Variantes en Documentos de Venta WhitePaper Febrero de 2007

Uso de blogs. Creación y administración de blogs. Pedro A. Castillo Valdivieso Depto. Arquitectura y Tecnología de Computadores

Creando CRUD en PHP: operaciones básicas para la gestión de bases de datos

Programación de presostato diferencial de aceite

Flash Fabricación. (Un ejemplo paso a paso)

Curso Android. ADT Bundle. Android Developer Tools. Entorno de trabajo Toolbar principal SDK Manager. Emulador de Android. Crear proyecto Android

Al comenzar un nuevo documento, el primer paso es determinar el formato y características de página.

Estos márgenes se definen en el menú Archivo, Configurar página... se nos muestra un cuadro de dialogo como este con tres pestañas:

ViewFlow es un objeto que sirve para presentar listas de registros de un modo gráfico, a modo de presentación de diapositivas.

MOODLE 1.9 CALENDARIO

Ejercicios de geolocalización y mapas

Guía básica sobre algunas utilidades de Google. Juan Carlos Martínez Modia

Bueno, lo primero que tenemos que hacer es crearnos un nuevo proyecto como ya vimos en anteriores tutoriales, pero por si acaso lo voy a repetir.

Microsoft Word. Microsoft Word 2013 SALOMÓN CCANCE. Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

GUÍA DEL CAMPUS VIRTUAL

Calificaciones de Moodle

Ayuda Gestión Techni-web

De esta manera, cuando el usuario rellena un campo cómo el siguiente... <input type="text" name="telefono"> </form>

Hasta el momento hemos visto ejemplos de aplicación de Data Provider que requieren acceder a la base de datos para recuperar información.

Guía rápida para la creación de eventos. Gestiona y promociona tus eventos forma fácil y eficaz.

Grabación de audio/vídeo y gráficos avanzados en Android - Ejercicios

Tipos Recursivos de Datos

Sensores y eventos - Ejercicios

Planteamiento de situaciones didácticas y socialización de las preguntas, Clase magistral, Taller, Actividad práctica DURACION Dos (4) horas.

Manual comercial. Funcionalidad, acceso y contenidos. Clientes potenciales Listado Ficha del cliente Crear o modificar un cliente

Para poder comenzar a trabajar con Excel, es necesario considerar los siguientes términos:

Unidad 2 Configurar Pagina Encabezados y pies de página Configurar página

UNIDAD 6 TEMA 4: OFIMÁTICA AVANZADA. CLASE 05: Combinar correspondencia.

Índice. Calendario... 3

EJERCICIO 33 DE EXCEL

Unidad N 9. Insertar y eliminar elementos.

Microsoft Word. Microsoft Word 2013 SALOMÓN CCANCE. Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

UNIDAD 2. writer USANDO TABLAS. CURSO: LibreOffice

CAPÍTULO 1. INTRODUCCIÓN. CONCEPTOS BÁSICOS

Manual de uso básico de la aplicación

Para el siguiente trabajo utilizamos IBM Data Studio Version Un ABM completo de una tabla. 1.a) Alta de una sucursal.

MANUAL DE USUARIO PORTAL DE PROVEEDORES

Envió de Mails Personalizados con el paquete Microsoft Office

Unidad Didáctica 9. Comportamientos

GUÍA MODULO VERSIÓN 1 CÓDIGO: EC/001 VIRTUALIZACION FORMACION POR PROYECTOS SOCIEDAD SALESIANA CENTRO DE CAPACITACIÓN Y DE PROMOCIÓN POPULAR

UNIDAD 4. MODIFICAR TABLAS DE DATOS

INTERFACE LIST. CLASE LINKEDLIST DEL API JAVA. EJERCICIO RESUELTO Y DIFERENCIAS ENTRE ARRAYLIST Y LINKEDLIST (CU00921C)

INTERFACES MAP Y SORTEDMAP DEL API JAVA. CLASES HASHMAP Y TREEMAP. EJEMPLO. DIFERENCIAS ENTRE ELLAS. (CU00922C)

SERVIDOR DNS. Mikel Xabier Marturet Urtiaga

Manual Gran Hotel. En principio, una estacionalidad no tiene el fin marcado, puede ser válida para siempre.

Unidad IV. Aplicaciones sobre Base de Datos

Componentes de datos. 4. Construcción de la tabla de datos (GridView) (Forma manual. 5. Construcción de los mantenimientos (paquetes). automática).

Guía rápida para la creación de eventos. Gestiona y promociona tus eventos forma fácil y eficaz.

Configuración del SPAM de Outlook

Manual Página Futura Biometría

TUTORIAL PARA EL PROFESORADO DEL PROGRAMA DE BIBLIOGRAFÍA RECOMENDADA. Al programa se accede desde UACloud a través de la etiqueta Otros servicios.

Programación de Videojuegos Tema 15 Tipos de Dato I. 15. Tipos de Dato I

Android y Java para Dispositivos Móviles

GNS PERSONAL MANUAL DE SOLICITUD DE TICKETS

SCREENCAST Y EDICIÓN DE VIDEO CON DISPOSITIVOS MÓVILES (PARA ANDROID)

TUTORIAL PARA INSERTAR EL HORARIO PERSONAL EN SÉNECA

Sensores y eventos - Ejercicios

MICROSOFT POWERPOINT MICROSOFT POWERPOINT Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

Transcripción:

Índice 1 Agenda de contactos...2 1.1 Carga de contactos... 3 1.2 Acceso a datos de los contactos...4 1.3 Inserción de contactos...5 2 Calendario... 6 2.1 Selección del calendario... 7 2.2 Añadir eventos al calendario...9 2.3 Eventos recurrentes...9 2.4 Añadir recordatorios a los eventos...11

En esta sesión vamos a ver cómo utilizar proveedores de contenidos que nos den acceso a información personal del usuario manejada por el dispositivo, como es el caso de su agenda de contactos y sus calendarios. La forma de acceder a esta información ha ido variando a lo largo de las diferentes versiones de Android, hasta estandarizarse completamente en ICS (Ice Cream Sandwich, Android 4.0). Veremos cómo mantener la compatibilidad con versiones anteriores. 1. Agenda de contactos El proveedor de la agenda de contactos se encuentra estructurado en tres tablas de datos: Contacts: Contiene la lista de contactos únicos. Un contacto puede tener varias cuentas (Google, Twitter, etc). Esta tabla unifica todas esas cuentas en una única entrada. RawContacts: En esta tabla tenemos entradas para cada cuenta concreta de un contacto. Una única entrada en Contacts puede estar relacionada con varias entradas en RawContacts, para cada cuenta diferente del usuario. Data: Esta es la tabla donde realmente están almacenados los datos de cada cuenta de usuario. Para cada cuenta (almacenada en RawContacts) tendremos un conjunto de datos almacenados en la tabla Data. Tablas de contactos 2

El acceso al proveedor de la agenda de contactos se hace mediante una serie de constantes definidas en las siguientes subclases de ContactsContract, cada una de ellas referida a una de las tablas anteriores: ContactsContract.Contacts ContactsContract.RawContacts ContactsContract.Data En primer lugar, para que nuestra aplicación pueda acceder a los contactos (leerlos y/o modificarlos) deberemos solicitar el permiso correspondiente en el AndroidManifest.xml: <uses-permission android:name="android.permission.read_contacts"> <uses-permission android:name="android.permission.write_contacts"> 1.1. Carga de contactos Para leer los contactos almacenados en el dispositivos utilizaremos la clase ContentsResolver, al igual que para cualquier otro tipo de contenidos. Por ejemplo, podríamos leer todos los contactos de la siguiente forma: ContentResolver cr = getcontentresolver(); Cursor cursor = cr.query(contactscontract.contacts.content_uri, null, null, null, null); En lugar de seleccionar todos los datos podemos indicar la proyección o selección que nos interese mediante constantes de ContactsContract.Contacts. mprojection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY }; mprofilecursor = getcontentresolver().query(contactscontract.contacts.content_uri, mprojection, null, null, null); En lugar de cargar el cursor directamente, también podríamos utilizar un loader con un CursorAdapter para cargar los datos del proveedor de contenidos. @Override public Loader<Cursor> oncreateloader(int id, Bundle args) { String[] projection = { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY }; String sortorder = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " ASC"; } return new CursorLoader(getApplicationContext(), ContactsContract.Contacts.CONTENT_URI, projection, null, null, sortorder); 3

El loader CursorLoader se encarga de cargar los datos de un proveedor de contenidos de forma asíncrona (internamente utilizará ContentResolver). Nota En versiones anteriores a Android 2.0 (API 5) el acceso al proveedor de contenidos de la agenda de contactos se hacía mediante constantes de la clase Contacts.People. Si queremos hacer una aplicación compatible deberemos tener esto en cuenta y utilizar una u otra en función de la versión actual. 1.2. Acceso a datos de los contactos Una vez tenemos el identificador de un contacto, podríamos obtener todas sus cuentas asociadas (raw contacts). Utilizaremos para ello las constantes definidas en ContactsContract.RawContacts: Cursor c = getcontentresolver().query( ContactsContract.RawContacts.CONTENT_URI, new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.ACCOUNT_TYPE, ContactsContract.RawContacts.ACCOUNT_NAME }, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] { String.valueOf(contactId) }, null); Podemos obtener los datos un contacto utilizando constantes de ContactsContract.Data para el acceso a la URI y a datos genéricos, y a constantes de clases internas de ContactsContract.CommonDataKinds para acceder a tipos de datos comunes. Por ejemplo, podemos leer los números de teléfono asociados a una cuenta dada: Cursor c = getcontentresolver().query( ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data._ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.LABEL}, ContactsContract.Data.RAW_CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'", new String[] { String.valueOf(rawContactId) }, null); También podemos obtener los teléfonos de todas las cuentas de un contacto dado: Cursor c = getcontentresolver().query( ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data._ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.LABEL}, ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'", 4

new String[] { String.valueOf(contactId) }, null); 1.3. Inserción de contactos No podemos añadir un contacto directamente, sino que deberemos añadir una cuenta (raw contact). Si al añadir la cuenta ya existe un contacto con el identificador proporcionado, la cuenta quedará asociada a dicho contacto. En caso de no ser así, el contacto se creará de forma automática. Podemos añadir una cuenta de la siguiente forma: values.put(contactscontract.rawcontacts.account_type, tipo); values.put(contactscontract.rawcontacts.account_name, nombre); Uri rawcontacturi = getcontentresolver().insert(contactscontract.rawcontacts.content_uri, values); Tras crear la cuenta, obtendremos una URI que nos dará acceso a ella. Podemos extraer de ella el identificador de la cuenta que se acaba de insertar: long rawcontactid = ContentUris.parseId(rawContactUri); Tras insertar la cuenta, podremos añadir a ella distintos elementos de datos: values.clear(); values.put(contactscontract.data.raw_contact_id, rawcontactid); values.put( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); values.put( ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "Pepe García"); getcontentresolver().insert(contactscontract.data.content_uri, values); Sin embargo, la forma recomendada de realizar las inserciones es metiante una operación en batch que realice todas las operaciones de forma conjunta. Para ello crearemos una lista de objetos ContentProviderOperation, que definirán las operaciones que vamos a realizar en batch: ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); ops.add(contentprovideroperation.newinsert(contactscontract.rawcontacts.content_uri).withvalue(contactscontract.rawcontacts.account_type, accounttype).withvalue(contactscontract.rawcontacts.account_name, accountname).build()); ops.add(contentprovideroperation.newinsert(contactscontract.data.content_uri).withvaluebackreference(contactscontract.data.raw_contact_id, 0).withValue( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE).withValue( 5

ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "Pepe García").build()); getcontentresolver().applybatch(contactscontract.authority, ops); Podemos ver que como la segunda operación depende del identificador generado por la primera (RAW_CONTACT_ID), este valor se lo pasamos con el método withvaluebackreference. Con ello le indicamos que como valor tome el generado por una operación anterior. Para indicar de qué operación queremos obtener el valor generado le proporcionamos como segundo parámetro el índice de dicha operación en la lista (en el caso anterior se le proporciona 0 porque nos interesa el resultado de la primera operación). En versiones anteriores a la 2.0 (API 5) la inserción de contactos se realiza de la siguiente forma: // Inserta contacto (previo a Android 2.0) ContentValues cv = new ContentValues(); cv.put(contacts.people.name, nombre); Uri uri = getcontentresolver().insert(contacts.people.content_uri, cv); // Añade un teléfono Uri phoneuri = Uri.withAppendedPath(uri, Contacts.People.Phones.CONTENT_DIRECTORY); cv.clear(); cv.put(contacts.people.phones.type, tipo); cv.put(contacts.people.phones.number, telefono); getcontentresolver().insert(phoneuri, cv); // Añade un e-mail Uri emailuri = Uri.withAppendedPath(uri, Contacts.People.ContactMethods.CONTENT_DIRECTORY); cv.clear(); cv.put(contacts.people.contactmethods.kind, Contacts.KIND_EMAIL); cv.put(contacts.people.contactmethods.data, email); cv.put(contacts.people.contactmethods.type, Contacts.People.ContactMethods.TYPE_WORK); getcontentresolver().insert(emailuri, cv); 2. Calendario El acceso al calendario no se ha estandarizado en Android hasta la versión 4.0 (Ice Cream Sandwich). Anteriormente se debían especificar las URI y los campos del proveedor sin ayuda de ninguna constante. Vamos a ver las dos formas de acceder, para poder mantener la compatibilidad con versiones anteriores. Con Android 4.0 el acceso a calendarios se realizará mediante clases internas de CalendarContract. En ellas podemos acceder a las distintas URIs que nos dan acceso a las tablas que contienen los datos de los calendarios. En versiones anteriores deberemos escribir las URIs directamente: Versión URI 6

Hasta Android 2.1 A partir de Android 2.2 "content://calendar/" "content://com.android.calendar/" A partir de Android 4.0 CalendarContract.CONTENT_URI Para poder acceder a los calendarios antes deberemos solicitar los permisos correspondiente en AndroidManifest.xml: <uses-permission android:name="android.permission.read_calendar" /> <uses-permission android:name="android.permission.write_calendar" /> El proveedor de calendarios nos da acceso a multiples calendarios, almacenados en la tabla Calendars. Cada calendario contiene una serie de eventos, contenidos en la tabla Events, y estos eventos pueden contener recordatorios, que se almacenan en la tabla Reminders. 2.1. Selección del calendario Tablas de calendarios En el sistema podemos tener acceso a varios calendarios, por lo que lo primero que deberemos hacer es seleccionar el calendario con el que queramos trabajar. Para ello a partir de Android 4.0 tenemos la clase CalendarContract.Calendars, que contiene las constantes necesarias para acceder a la lista de calendario, como por ejemplo CONTENT_URI. 7

En versiones anteriores deberemos especificar la URI manualmente: Versión URI Hasta Android 2.1 A partir de Android 2.2 "content://calendar/calendars" "content://com.android.calendar/calendars" A partir de Android 4.0 En Android 4.0 podremos acceder a los calendarios con: CalendarContract.Calendars.CONTENT_URI Cursor cursor = getcontentresolver().query(uri.parse(contenturi), new String[] { CalendarContract.Calendars._ID, CalendarContract.Calendars.CALENDAR_DISPLAY_NAME }, null, null, null); Sin embargo, en versiones anteriores deberemos especificar los campos manualmente también: Cursor cursor = getcontentresolver().query(uri.parse(contenturi), new String[] { "_id", "displayname" }, null, null, null); Advertencia Hay que destacar que los nombres de los campos cambian en Android 4.0, por lo que el código de versiones antiguas dejará de funcionar. Por ejemplo, en lugar de "displayname" se utiliza "calendar_displayname". Si queremos conseguir una aplicación compatible con todas las versiones, deberemos detectar la versión que se está utilizando y en función de ésta ajustar los nombres de los campos: Uri calendarsuri; String calendarsid; String calendarsname; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { calendarsuri = CalendarContract.Calendars.CONTENT_URI; calendarsid = CalendarContract.Calendars._ID; calendarsname = CalendarContract.Calendars.CALENDAR_DISPLAY_NAME; } else { if(build.version.sdk_int >= Build.VERSION_CODES.FROYO) { calendarsuri = Uri.parse("content://com.android.calendar/calendars"); } else { calendarsuri = Uri.parse("content://calendar/calendars"); } calendarsid = "_id"; calendarsname = "displayname"; } De esta forma podemos obtener la lista de calendarios, y dejar que el usuario seleccione uno de ellos. Una vez seleccionado, podremos acceder a él y modificarlo, para por ejemplo añadir nuevos eventos. 8

2.2. Añadir eventos al calendario La tabla de eventos tiene las siguientes URIs, dependiendo de la versión de Android: Versión URI Hasta Android 2.1 A partir de Android 2.2 A partir de Android 4.0 "content://calendar/events" "content://com.android.calendar/events" CalendarContract.Events.CONTENT_URI Para crear un evento deberemos proporcionar la fecha y hora de inicio y de fin (en milisegundos), su título y descripción, la zona horaria, y el identificador del calendario al que lo queremos añadir: Date dtstart = // Fecha y hora de inicio Date dtend = // Fecha y hora de fin ContentResolver cr = getcontentresolver(); values.put(calendarcontract.events.dtstart, dtstart.gettime()); values.put(calendarcontract.events.dtend, dtend.gettime()); values.put(calendarcontract.events.title, "Reunión"); values.put(calendarcontract.events.description, "Preparación proyecto"); values.put(calendarcontract.events.calendar_id, calid); values.put(calendarcontract.events.event_timezone, "Europe/Madrid"); Uri uri = cr.insert(calendarcontract.events.content_uri, values); En caso de utilizar versiones anteriores de Android, se hará de la siguiente forma: Date dtstart = // Fecha y hora de inicio Date dtend = // Fecha y hora de fin ContentResolver cr = this.getcontentresolver(); values.put("dtstart", dtstart.gettime()); values.put("dtend", dtend.gettime()); values.put("title", "Reunión"); values.put("description", "Preparación proyecto"); values.put("calendar_id", calid); values.put("eventtimezone", "Europe/Madrid"); Uri newevent = cr.insert(contenturi, values); 2.3. Eventos recurrentes En muchas ocasiones nos interesa agregar un evento que se repite semanalmente durante un periodo de tiempo (por ejemplo las clases de una asignatura). En este caso será conveniente añadirlo como evento recurrente, en lugar de añadirlos como eventos independientes. De esta forma si queremos eliminarlo podremos eliminar la serie entera mediante una única operación. Para definir un evento recurrente deberemos: En DTSTART pondremos la fecha y la hora de inicio del primer evento de la serie, pero 9

en este caso ya no utilizaremos DTEND. En lugar de DTEND, deberemos especificar la duración de los eventos de la serie en DURATION. Se especificará mediante el formato RFC5545. Por ejemplo, una duración de 90 minutos se especifica con "P90M", y una duración de de dos semanas con "P2W". http://tools.ietf.org/html/rfc5545#section-3.8.2.5 Por último, deberemos especificar la regla de recurrencia en RRULE. En ella deberemos especificar la frecuencia con la que se repite y el número de repeticiones o fecha de finalización. Por ejemplo, si ponemos "FREQ=WEEKLY;COUNT=10" se repetirá 10 veces semanalmente. Si queremos fijar una fecha concreta de finalización, lo haremos con el formato "FREQ=WEEKLY;UNTIL=20130525T235959Z". Más información sobre el formato de las reglas: http://tools.ietf.org/html/rfc5545#section-3.8.5.3 A continuación mostramos un ejemplo en el que se añade un evento recurrente para las clases de una asignatura que se imparte semanalmente hasta el fin del cuatrimestre (24 de mayo de 2013): Date dtstart = // Fecha y hora de inicio del primer evento Date dtend = // Fecha y hora de fin del primer evento // Duración de cada evento (formato RFC5545) long duracionmillis = dtend.gettime() - dtstart.gettime(); int duracionminutos = (int) (duracionmillis / (1000 * 60)); String duracion = "P" + duracionminutos + "M"; // Reglas de la serie de eventos String until = "20130525T235959Z"; // Formato: yyyymmddthhmmssz String rrule = "FREQ=WEEKLY;UNTIL=" + until; ContentResolver cr = this.getcontentresolver(); values.put(calendarcontract.events.calendar_id, calid); values.put(calendarcontract.events.title, "Programación I"); values.put(calendarcontract.events.description, "Asignatura troncal"); values.put(calendarcontract.events.event_location, "Aula L18"); values.put(calendarcontract.events.event_timezone, "Europe/Madrid"); values.put(calendarcontract.events.dtstart, dtstart.gettime()); values.put(calendarcontract.events.duration, duracion); values.put(calendarcontract.events.rrule, rrule); // Inserta el evento en el calendario Uri event = cr.insert(calendarcontract.events.content_uri, values); Atención Es importante no indicar el campo DTEND, ya que es incompatible con DURATION. Si ponemos los dos al mismo tiempo, obtendremos un error. Con versiones anteriores de Android esto mismo se haría de la siguiente forma: Date dtstart = // Fecha y hora de inicio del primer evento Date dtend = // Fecha y hora de fin del primer evento 10

// Duración de cada evento (formato RFC5545) long duracionmillis = dtend.gettime() - dtstart.gettime(); int duracionminutos = (int) (duracionmillis / (1000 * 60)); String duracion = "P" + duracionminutos + "M"; // Reglas de la serie de eventos String until = "20130525T235959Z"; // Formato: yyyymmddthhmmssz String rrule = "FREQ=WEEKLY;UNTIL=" + until; ContentResolver cr = this.getcontentresolver(); values.put("calendar_id", idcalendario); values.put("title", "Programación I"); values.put("description", "Asignatura troncal"); values.put("eventlocation", "Aula L18"); values.put("eventtimezone", "Europe/Madrid"); values.put("dtstart", dtstart.gettime()); values.put("duration", duracion); values.put("rrule", rrule); // Inserta el evento en el calendario Uri event = cr.insert(contenturi, values); 2.4. Añadir recordatorios a los eventos Puede interesarnos también añadir recordatorios a los eventos, para recibir un aviso en el momento del evento o con cierta antelación. Estos recordatorios se añadirán a la tabla reminders. En primer lugar necesitaremos el identificador del evento al que vamos a añadir el recordatorio. Podemos extraerla de la URI obtenida al crear el evento: long id = ContentUris.parseId(event); Añadiremos el recordatorio proporcionando: Un método (alerta = 1, alarma = 2, e-mail = 3, sms = 4) Una antelación en minutos, respecto a la hora en la que está programado el evento. Las URIs para la tabla de recordatorios son los siguientes: Versión URI Hasta Android 2.1 A partir de Android 2.2 A partir de Android 4.0 "content://calendar/reminders" "content://com.android.calendar/reminders" CalendarContract.Reminders.CONTENT_URI Podemos añadir el recordatorio de la siguiente forma: values.put(calendarcontract.reminders.event_id, id); values.put(calendarcontract.reminders.method, CalendarContract.Reminders.METHOD_ALERT); values.put(calendarcontract.reminders.minutes, 30); cr.insert(contenturi, values); La forma de hacer esto en versiones anteriores es la siguiente: 11

values.put("event_id", id); values.put("method", 1); values.put("minutes", 30); cr.insert(contenturi, values); 12

13